# 阶段三实施总结:部门层级结构 > **实施日期**: 2025-12-30 > **状态**: ✅ Schema更新完成,迁移脚本已创建 > **下一步**: 需要在应用Schema变更后运行迁移脚本 --- ## 📋 实施内容 ### 1. Schema 变更 **文件**: `prisma/schema.prisma` **变更内容**: 在 `Department` 模型中添加层级结构字段 ```prisma model Department { id String @id @default(uuid()) name String @unique // 部门名称(保留,向后兼容) createdAt DateTime @default(now()) // 部门层级结构(阶段三新增) code String? @unique // 部门编码(可选,如:DEPT-001) parentId String? // 父部门ID(支持层级结构) parent Department? @relation("DepartmentHierarchy", fields: [parentId], references: [id]) children Department[] @relation("DepartmentHierarchy") level Int @default(1) // 层级:1=一级部门,2=二级部门,3=三级部门 managerId String? // 部门负责人ID(部门管理员) manager User? @relation("DepartmentManager", fields: [managerId], references: [id]) status String @default("active") // active/disabled/archived(部门状态) description String? // 部门描述 sortOrder Int @default(0) // 排序字段 updatedAt DateTime @updatedAt // 关联用户(阶段二新增) users User[] @relation("UserDepartment") permissions DepartmentMaterialPermission[] @@index([parentId]) @@index([status]) @@index([level]) @@index([managerId]) @@map("departments") } ``` **同时更新 `User` 模型**: ```prisma model User { // ... 其他字段 ... // 部门管理关联(阶段三新增) managedDepartments Department[] @relation("DepartmentManager") } ``` **关键设计**: - ✅ **向后兼容**: 保留 `name` 字段,不破坏现有代码 - ✅ **可选字段**: 所有新字段都是可选的,有默认值 - ✅ **自关联**: 使用 `parentId` 实现树形结构 - ✅ **层级冗余**: `level` 字段冗余存储,避免递归查询 - ✅ **状态管理**: `status` 字段支持启用/禁用/归档 ### 2. 数据迁移脚本 **文件**: `scripts/migrate-department-hierarchy-safe.ts` **功能**: 1. 为所有现有部门设置默认值(`level=1`, `status='active'`) 2. 为没有编码的部门生成编码(`DEPT-001`, `DEPT-002`, ...) 3. 验证数据完整性(检查父部门是否存在,层级是否一致) **使用方法**: ```bash # 1. 先应用Schema变更(生成Prisma客户端) npx prisma db push # 或 npx prisma migrate dev --name add_department_hierarchy # 2. 运行迁移脚本 DATABASE_URL="your_database_url" npx tsx scripts/migrate-department-hierarchy-safe.ts ``` **执行流程**: 1. 检查 Schema 是否已更新(字段是否存在) 2. 设置所有部门的默认值 3. 生成部门编码 4. 验证迁移结果 5. 检查数据完整性 **注意**: 迁移脚本需要在应用Schema变更并重新生成Prisma客户端后运行,否则会出现TypeScript类型错误。 ### 3. 验证脚本更新 **文件**: `scripts/verify-migration.ts` **更新内容**: 更新 `verifyStage3()` 函数,使用 Prisma API 进行验证 **验证项目**: - 检查 `level` 字段是否存在 - 统计各部门层级分布 - 检查父子部门关系 - 验证层级一致性 --- ## 📊 字段说明 ### 新增字段 | 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `code` | `String?` | `null` | 部门编码(唯一标识) | | `parentId` | `String?` | `null` | 父部门ID(外键) | | `level` | `Int` | `1` | 层级:1/2/3 | | `managerId` | `String?` | `null` | 部门负责人ID | | `status` | `String` | `'active'` | 部门状态:active/disabled/archived | | `description` | `String?` | `null` | 部门描述 | | `sortOrder` | `Int` | `0` | 排序字段 | ### 关联关系 - `parent` / `children`: 部门层级关系(自关联) - `manager` / `managedDepartments`: 部门负责人关系 ### 索引 - `@@index([parentId])`: 优化父部门查询 - `@@index([status])`: 优化状态筛选 - `@@index([level])`: 优化层级查询 - `@@index([managerId])`: 优化负责人查询 --- ## 🔄 下一步工作 ### 待完成任务 - [ ] 在影子系统应用 Schema 变更(`prisma db push`) - [ ] 运行迁移脚本设置默认值 - [ ] 更新前端 UI 支持层级展示 - [ ] 在影子系统进行功能测试 ### 已完成的API更新 - [x] GET `/api/departments` - 支持层级查询(`includeHierarchy` 参数) - [x] POST `/api/departments` - 支持创建子部门(`parentId`, `level`, `code`, `status` 等参数) - [x] GET `/api/departments/[id]` - 获取部门详情(包含层级信息) - [x] PUT `/api/departments/[id]` - 更新部门信息(包括层级关系、状态等) - [x] DELETE `/api/departments/[id]` - 删除部门(包含安全检查:子部门和用户检查) - [x] DELETE `/api/departments` - 更新删除逻辑(向后兼容) --- ## ✅ 检查清单 ### Schema 变更 - [x] 添加 `code` 字段(可选,唯一) - [x] 添加 `parentId` 字段(可选外键) - [x] 添加 `level` 字段(默认值 1) - [x] 添加 `managerId` 字段(可选外键) - [x] 添加 `status` 字段(默认值 'active') - [x] 添加 `description` 字段(可选) - [x] 添加 `sortOrder` 字段(默认值 0) - [x] 添加 `updatedAt` 字段 - [x] 添加自关联关系(parent/children) - [x] 添加负责人关联关系(manager/managedDepartments) - [x] 添加必要索引 ### 迁移脚本 - [x] 创建迁移脚本 - [x] 实现默认值设置逻辑 - [x] 实现编码生成逻辑 - [x] 实现数据验证逻辑 - [x] 实现完整性检查 ### 验证脚本 - [x] 更新 `verifyStage3()` 函数 - [x] 使用 Prisma API 进行验证 - [x] 处理字段不存在的情况(阶段三未实施时跳过) ### API更新 - [x] 更新 GET `/api/departments` - 支持层级查询(`includeHierarchy` 参数) - [x] 更新 POST `/api/departments` - 支持创建子部门(`parentId`, `level`, `code`, `status` 等参数) - [x] 创建 GET `/api/departments/[id]` - 获取部门详情(包含层级信息) - [x] 创建 PUT `/api/departments/[id]` - 更新部门信息(包括层级关系、状态等) - [x] 创建 DELETE `/api/departments/[id]` - 删除部门(包含安全检查) - [x] 更新 DELETE `/api/departments` - 增加安全检查(向后兼容) - [x] 实现循环引用检查 - [x] 实现删除前安全检查(子部门、用户检查) --- ## 🚨 注意事项 ### 向后兼容 - ✅ 所有新字段都是可选的,不会影响现有数据 - ✅ 保留 `name` 字段,现有代码继续工作 - ✅ 默认值确保现有部门自动成为一级部门 ### 数据迁移 - ⚠️ **必须先应用Schema变更**(`prisma db push` 或 `prisma migrate dev`) - ⚠️ **迁移脚本需要在Schema更新后运行**,否则会出现TypeScript类型错误 - ⚠️ 部门编码生成使用顺序编号,如果后续需要调整层级,可能需要重新生成编码 - ⚠️ 层级关系需要在后续业务逻辑中设置(迁移脚本只设置默认值) ### 性能考虑 - ✅ 添加了必要的索引优化查询性能 - ✅ `level` 字段冗余存储,避免递归查询 - ⚠️ 层级查询需要在代码中优化(使用递归或CTE) --- **文档版本**: 1.0 **创建日期**: 2025-12-30 **最后更新**: 2025-12-30