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'); } }