fn_b/app/Models/Articles.php
2026-09-12 16:32:37 +08:00

139 lines
4.1 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Spatie\ResponseCache\Facades\ResponseCache;
use App\Models\Tags;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Laravel\Scout\Searchable;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Casts\Attribute;
class Articles extends Model
{
protected $guarded = [];
protected $appends = ['s_created_at_diff'];
use Searchable;
protected function sCreatedAtDiff(): Attribute
{
return Attribute::get(function () {
// 1. 别直接用 $this->created_at,防止它还没被实例化成 Carbon 对象
$oDate = \Carbon\Carbon::parse($this->created_at);
$oNow = \Carbon\Carbon::now();
// 2. 计算小时差(强制转整数)
$iHours = (int)$oDate->diffInHours($oNow);
if ($iHours < 1) {
// 不足 1 小时,看看是不是不足 1 分钟
$iMinutes = (int)$oDate->diffInMinutes($oNow);
return $iMinutes < 1 ? '刚刚' : $iMinutes . '分钟前';
}
if ($iHours < 24) {
return $iHours . '小时前';
}
// 3. 计算天数差(强制转整数)
$iDays = (int)$oDate->diffInDays($oNow);
if ($iDays < 30) {
return $iDays . '天前';
}
// 超过一个月直接显示日期
return $oDate->format('Y-m-d');
});
}
public function shouldBeSearchable(): bool
{
return (int)$this->iStatus === 1;
}
public function searchableAs(): string
{
return 'articles';
}
public function toSearchableArray(): array
{
// 药水哥原则:字段要精准,类型要死磕
return [
'id' => (int) $this->id,
'iCategoryId' => (int) $this->iCategoryId,
'sCategoryName' => (string) ($this->oCategory->sName ?? 'none'),
'sCategorySlug' => (string) ($this->oCategory->sSlug ?? 'none'),
'sTitle' => (string) $this->sTitle,
'sTitleSub' => (string) $this->sTitleSub,
'sSlug' => (string) $this->sSlug,
'sContent' => (string) mb_substr(strip_tags($this->sContent), 0, 500),
'iStatus' => (int) $this->iStatus,
'iIsTop' => (int) $this->iIsTop,
'updated_at' => (int) $this->updated_at->timestamp,
];
}
/**
* 判断当前文章是否超过分类设置的 SEO 暴露天数
* @return bool
*/
public function bIsSeoExpired(): bool
{
$oCategory = $this->oCategory;
// 未关联分类,或分类下的 aOpt 没设置,默认不处理(不过期)
if (!$oCategory || empty($oCategory->aOpt) || !isset($oCategory->aOpt['noindexday'])) {
return false;
}
$iNoindexDay = (int) $oCategory->aOpt['noindexday'];
// 0 或负数代表不限制,一直暴露给搜索引擎
if ($iNoindexDay <= 0) {
return false;
}
// 判断文章创建时间是否早于 N 天前
$oCreateDate = \Carbon\Carbon::parse($this->created_at);
return $oCreateDate->lt(\Carbon\Carbon::now()->subDays($iNoindexDay));
}
protected static function booted()
{
static::saved(function () {
ResponseCache::forget('/'); // 要改成具体文章
});
static::deleted(function () {
ResponseCache::forget('/'); // 要改成具体文章
});
}
public function oTags(): BelongsToMany
{
return $this->belongsToMany(
Tags::class,
'article_tag',
'iArticleId',
'iTagId'
);
}
public function oCategory(): BelongsTo {
return $this->belongsTo(Categories::class, 'iCategoryId', 'id');
}
public function oUser()
{
return $this->belongsTo(User::class, 'iUserId', 'id');
}
}