'integer', 'published_at' => 'datetime', ]; public const TEMPLATES = [ 'standard' => '标准文章', 'tech' => '技术文档', 'feature' => '专题报道', ]; public function category(): BelongsTo { return $this->belongsTo(Category::class, 'category_id'); } public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } /** * 可见性作用域(与 forum 一致): * - 审核员(articles.moderate):看全部 * - 登录用户:看已审 + 自己投稿(无论状态) * - 游客:仅看已审 */ public function scopeVisibleTo($query, ?User $user = null) { if ($user && $user->canPerm('articles.moderate')) { return $query; } if ($user) { return $query->where(function ($q) use ($user) { $q->where('status', 'approved')->orWhere('user_id', $user->id); }); } return $query->where('status', 'approved'); } public function scopePublished($query) { return $query->where('status', 'approved') ->whereNotNull('published_at') ->orderByDesc('published_at'); } /** * 前台可见文章:已审核通过(approved) 且已设定发布时间。 * 用户自己的待审(pending)/驳回(rejected) 由控制器单独查询,不进此作用域。 */ public function scopeVisiblePublic($query) { return $query->where('status', 'approved') ->whereNotNull('published_at'); } /** * 前台 SEO 标题:优先用文章自定义,否则回退到标题。 */ public function seoTitle(): string { return $this->seo_title ?: $this->title; } public function seoDescription(): string { return $this->seo_description ?: ($this->summary ?: $this->title); } }