'array', 'is_sticky' => 'boolean', 'close_comment' => 'boolean', 'published_at' => 'datetime', ]; public function category(): BelongsTo { return $this->belongsTo(Category::class); } public function author(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function comments(): HasMany { return $this->hasMany(Comment::class); } public function scopePublished(Builder $query): Builder { return $query->where('status', 'published') ->whereNotNull('published_at') ->where('published_at', '<=', now()); } public function scopeSearch(Builder $query, ?string $keyword): Builder { if (! $keyword) { return $query; } return $query->where(function (Builder $q) use ($keyword) { $q->where('title', 'like', "%{$keyword}%") ->orWhere('content', 'like', "%{$keyword}%") ->orWhere('excerpt', 'like', "%{$keyword}%") ->orWhere('keywords', 'like', "%{$keyword}%"); }); } public function registerMediaCollections(): void { $this->addMediaCollection('attachments')->useDisk(\App\Support\MediaDisk::name()); $this->addMediaCollection('cover')->useDisk(\App\Support\MediaDisk::name()) ->singleFile() ->registerMediaConversions(function () { $this->addMediaConversion('card')->width(1200)->height(630)->sharpen(1); }); } public function registerMediaConversions(?Media $media = null): void { [$tw, $th] = array_pad(explode('x', strtolower((string) blog_setting('attachments_thumbs_size', '500x500'))), 2, '500'); $this->addMediaConversion('thumb') ->width((int) $tw) ->height((int) $th) ->performOnCollections('attachments'); } public function getUrlAttribute(): string { return route('posts.show', $this->slug ?? $this->id); } /** * 作为可购买实体(单篇解锁)的展示约定。 */ public function payableLabel(): string { return '文章:'.$this->title; } public function payableUrl(): ?string { return route('filament.admin.resources.posts.edit', $this); } public function getExcerptOrFallbackAttribute(): string { if ($this->excerpt) { return $this->excerpt; } $text = strip_tags($this->content); // 付费块不进入摘要,避免付费内容泄漏到列表页/SEO meta $text = preg_replace('/\[paid\].*?\[\/paid\]/s', '', $text); $text = preg_replace('/\[[^\]]*\]/', '', $text); return mb_substr($text, 0, 200); } }