import{_ as i,o as a,c as h,a2 as t}from"./chunks/framework.BbmSSMjL.js";const y=JSON.parse('{"title":"6.4 部门管理","description":"","frontmatter":{},"headers":[],"relativePath":"zh/modules/dept.md","filePath":"zh/modules/dept.md"}'),n={name:"zh/modules/dept.md"};function k(l,s,p,e,d,r){return a(),h("div",null,[...s[0]||(s[0]=[t(`
概述
部门管理维护组织架构数据,支持树形结构,是数据权限(按部门过滤)的基础。DeptService 继承 BaseTenantService 实现租户隔离。
| 特性 | 说明 |
|---|---|
| 基类 | BaseTenantService(租户隔离) |
| 树形结构 | treeParentField='parent_id'、treeLikeField='name' |
| 唯一校验 | name 按租户分组唯一(['name','tenant_id']) |
| 删除校验 | beforeDelete 检查子部门与关联用户(均存在时阻止删除) |
| 数据权限 | 被 UserService 的 dataScopeDeptField='dept_id' 引用 |
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 = '部门表';| 方法 | 路径 | 权限码 | 说明 |
|---|---|---|---|
| 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 | 删除 |
树形接口
部门使用 _list() 而非 _page(),返回全量数据后构建树形结构(树形数据需要父子完整链,不适合分页)。
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('该部门下存在用户,不可删除');
}
}
}DELETE /api/dept/delete/{id}
│
▼
Controller::_delete() → Service::delete()
│
▼
beforeDelete($id)
├─ 存在子部门 → throw BizException('存在子部门,不可删除')
├─ 存在关联用户 → throw BizException('该部门下存在用户,不可删除')
│ → 事务回滚 → {"code":1,"msg":"...不可删除"}
▼
DB::transaction { 软删除 is_delete=1(树形子节点不级联,需逐级删除) }不做级联删除
删除父部门不会级联删除子部门(软删除保持数据可恢复)。正确顺序:自叶子节点向上逐级删除;存在子部门时接口直接返回业务错误。
| 关系 | 说明 |
|---|---|
| 用户 → 部门 | laravel_user.dept_id 外键,数据权限按此字段过滤 |
| 部门树 → 前端 | 用户表单中以级联选择器回显(deptName 由 afterDetail 补全) |
| 数据权限 | 范围解析为 2(本部门)时查询叠加 WHERE dept_id = 本部门(见 5.9 数据权限;当前默认解析为 1) |