外观
树结构
Pin 的树结构能力由 Pin\Tree 模块提供,适合菜单、组织架构、分类等层级数据。
TreeModel
php
use Pin\Tree\TreeModel;
class Menu extends TreeModel
{
protected $table = 'menus';
}TreeModel 组合了:
Pin\Tree\Concerns\HasTreePin\Models\Concerns\RedisIdPin\Models\Concerns\SoftDeletes
字段约定
树模型默认使用以下字段:
| 字段 | 说明 |
|---|---|
id | 节点 ID |
pid | 父节点 ID,根节点为 0 |
path | 节点路径 |
paths | path 解析后的 ID 数组 |
level | 节点层级 |
sort | 排序值 |
name | 节点名称 |
创建节点时 bootHasTree() 会自动补齐 id、pid、path、level 和 sort。
创建节点
php
$root = Menu::create([
'name' => '系统管理',
'pid' => 0,
]);
$child = Menu::create([
'name' => '用户管理',
'pid' => $root->id,
]);path 会根据当前节点和父节点自动生成。
Tree ModelService
树结构服务层继承通用 ModelService,额外处理节点移动和删除前检查:
php
use Pin\Tree\ModelService;
class MenuService extends ModelService
{
public string $resourceName = '菜单';
}更新节点时,如果 pid 变化,会重建当前节点和子树路径:
php
app(MenuService::class)
->withModel(Menu::class)
->update($menu, [
'pid' => $newParentId,
'sort' => -1,
]);删除节点前,如果仍存在子节点,会抛出删除失败错误。
TreeFilter
TreeFilter 会在过滤树数据时维护结构完整性:
php
use Pin\Support\Facades\Tree;
$visibleMenus = Tree::filter(
$menus,
fn ($menu) => ! $menu->isDisabled()
);过滤逻辑:
- 找出需要隐藏的节点。
- 移除隐藏节点及其子树。
- 移除过滤后变成空节点的父级。
- 返回重新索引后的集合。
排序与展示
树模块还提供导航、关系、路径、变更、展示和排序相关 trait:
TreeRelationTreeNavigationTreePathTreeMutationTreePresenterTreeQueryTreeSorter
这些能力通过 HasTree 统一挂载到模型上。