63 lines
1.5 KiB
PHP
63 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
/**
|
|
* Model Tree
|
|
*
|
|
* parent_id: 上级id, 默认: 0
|
|
* path: 所有上级id, 例如: -1-2-3-
|
|
* sort: 排序(正序)
|
|
*/
|
|
trait TreePath
|
|
{
|
|
protected static function booted(): void
|
|
{
|
|
static::saving(function (Model $model) {
|
|
if ($model->isDirty('parent_id')) {
|
|
$pid = $model->parent_id;
|
|
if ($pid) {
|
|
$parent = static::query()->findOrFail($pid);
|
|
$model->path = $parent->path . $parent->id . '-';
|
|
} else {
|
|
$model->parent_id = 0;
|
|
$model->path = '-';
|
|
}
|
|
}
|
|
});
|
|
|
|
static::deleting(function (Model $model) {
|
|
static::query()->allChildren($model->id)->delete();
|
|
});
|
|
}
|
|
protected function parentIds(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: fn () => explode('-', substr($this->path, 1, -1)),
|
|
);
|
|
}
|
|
|
|
public function children()
|
|
{
|
|
return $this->hasMany(static::class, 'parent_id');
|
|
}
|
|
|
|
public function parent()
|
|
{
|
|
return $this->belongsTo(static::class, 'parent_id');
|
|
}
|
|
|
|
public function scopeAllChildren($q, $pid)
|
|
{
|
|
return $q->where('path', 'like', '%-'.$pid.'-%');
|
|
}
|
|
|
|
public function scopeSort($q)
|
|
{
|
|
return $q->orderBy('parent_id')->orderBy('sort');
|
|
}
|
|
}
|