# 6.4 部门管理 :::tip 概述 部门管理维护组织架构数据,支持树形结构,是数据权限(按部门过滤)的基础。`DeptService` 继承 `BaseTenantService` 实现租户隔离。 ::: ## 模块特点 | 特性 | 说明 | |------|------| | 基类 | `BaseTenantService`(租户隔离) | | 树形结构 | `treeParentField='parent_id'`、`treeLikeField='name'` | | 唯一校验 | `name` 按租户分组唯一(`['name','tenant_id']`) | | 删除校验 | `beforeDelete` 检查子部门与关联用户(均存在时阻止删除) | | 数据权限 | 被 `UserService` 的 `dataScopeDeptField='dept_id'` 引用 | ## 数据库表结构 ```sql CREATE TABLE `laravel_dept` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(150) NOT NULL COMMENT '部门名称', `type` int DEFAULT 0 COMMENT '部门类型:1-公司 2-子公司 3-部门 4-小组', `parent_id` int DEFAULT 0 COMMENT '上级部门ID', `sort` int DEFAULT 0 COMMENT '部门排序', `note` varchar(255) DEFAULT NULL COMMENT '备注', `create_user` varchar(50) DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT (now()) COMMENT '创建时间', `update_user` varchar(50) DEFAULT NULL COMMENT '更新人', `update_time` datetime DEFAULT (now()) COMMENT '更新时间', `is_delete` int DEFAULT 0 COMMENT '删除标识:0-正常 1-已删除', PRIMARY KEY (`id`) ) COMMENT = '部门表'; ``` ## API 接口 | 方法 | 路径 | 权限码 | 说明 | |------|------|--------|------| | GET | `/api/dept/list` | sys:dept:list | 树形列表 | | GET | `/api/dept/detail/{id}` | sys:dept:detail | 详情 | | POST | `/api/dept/add` | sys:dept:add | 新增 | | PUT | `/api/dept/update` | sys:dept:update | 修改 | | DELETE | `/api/dept/delete/{id}` | sys:dept:delete | 删除 | :::tip 树形接口 部门使用 `_list()` 而非 `_page()`,返回全量数据后构建树形结构(树形数据需要父子完整链,不适合分页)。 ::: ## Service 配置(来自项目实际代码) ```php class DeptService extends BaseTenantService { use HasCrudOperations, HasQueryScopes, HasUniqueCheck; protected string $modelClass = Dept::class; protected array $pageLikeFields = ['name']; protected array $pageEqFields = []; // 无精确匹配(列表整体按树返回) protected array $pageOrderBy = ['field' => 'sort', 'type' => 'asc']; // name 在同一租户内唯一 protected array $uniqueFields = [['name', 'tenant_id']]; // 树形结构 protected string $treeParentField = 'parent_id'; protected string $treeLikeField = 'name'; /** * 删除前处理:检查子部门与关联用户 * * @param int $id 待删除的部门 ID * @throws BizException 当存在子部门或关联用户时抛出 */ protected function beforeDelete(int $id): void { $hasChildren = Dept::where('parent_id', $id)->exists(); if ($hasChildren) { throw new BizException('存在子部门,不可删除'); } $hasUsers = User::where('dept_id', $id)->exists(); if ($hasUsers) { throw new BizException('该部门下存在用户,不可删除'); } } } ``` ## 删除保护流程 ```text DELETE /api/dept/delete/{id} │ ▼ Controller::_delete() → Service::delete() │ ▼ beforeDelete($id) ├─ 存在子部门 → throw BizException('存在子部门,不可删除') ├─ 存在关联用户 → throw BizException('该部门下存在用户,不可删除') │ → 事务回滚 → {"code":1,"msg":"...不可删除"} ▼ DB::transaction { 软删除 is_delete=1(树形子节点不级联,需逐级删除) } ``` :::warning 不做级联删除 删除父部门不会级联删除子部门(软删除保持数据可恢复)。正确顺序:自叶子节点向上逐级删除;存在子部门时接口直接返回业务错误。 ::: ## 与其他模块的关系 | 关系 | 说明 | |------|------| | 用户 → 部门 | `laravel_user.dept_id` 外键,数据权限按此字段过滤 | | 部门树 → 前端 | 用户表单中以级联选择器回显(`deptName` 由 `afterDetail` 补全) | | 数据权限 | 范围解析为 2(本部门)时查询叠加 `WHERE dept_id = 本部门`(见 [5.9 数据权限](/zh/core/data-scope.html);当前默认解析为 1) |