Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_EleVue/zh/modules/dept.md
T
2026-10-08 17:50:29 +08:00

119 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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) |