store-manage/app/Models/Keyword.php

98 lines
2.6 KiB
PHP

<?php
namespace App\Models;
use App\Admin\Components;
use App\Filters\KeywordFilter;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Keyword extends Model
{
use Filterable;
use HasFactory;
protected $fillable = ['name', 'key', 'value', 'parent_id', 'parent_key', 'path', 'sort', 'lv'];
protected function serializeDate(\DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
protected static function boot()
{
parent::boot();
// 监听 Keyword 的创建事件,用于初始化 path 和 lv 字段值
static::saving(function (Keyword $keyword) {
if (is_null($parent = $keyword->parent)) {
$keyword->forceFill([
'path' => '-',
'lv' => 1,
]);
if ((string) $keyword->key === '') {
$keyword->key = Str::random(16);
}
} else {
$keyword->forceFill([
'parent_key' => $parent->lv > 1 ? $parent->parent_key : $parent->key,
'path' => $parent->full_path,
'lv' => $parent->lv + 1,
]);
if ((string) $keyword->key === '') {
$keyword->key = $parent->key.'_'.($parent->children()->count() + 1);
}
}
});
}
public function parent()
{
return $this->belongsTo(static::class, 'parent_id');
}
public function children()
{
return $this->hasMany(static::class, 'parent_id');
}
public function scopeSort($q)
{
return $q->orderBy('sort', 'asc');
}
public function scopeAllChildrenOfKey($q, $parentKey)
{
$q->where('path', 'like', '%-'.
static::where('key', $parentKey)->value('id')
.'-%' ?? '');
}
public function modelFilter(): string
{
return KeywordFilter::class;
}
public static function tagsMap(string $key)
{
$mapArr = [];
self::query()->where('parent_key', $key)->get()->map(function ($item) use (&$mapArr) {
$mapArr[$item->id] = Components::make()->keywordsTag($item->name, $item->value);
});
return $mapArr;
}
protected function fullPath(): Attribute
{
return Attribute::make(
get: fn (mixed $value, array $attributes) => $attributes['path'].$attributes['id'].'-',
);
}
}