gongxiangp2/docs/stage3-implementation-summary.md
chenpei ea9076df45 feat: 实现统一的下载错误处理系统并修复产品全案数据库Schema
- 创建统一的下载错误处理模块 (lib/download-errors.ts)
- 实现13种错误类型分类和中文错误消息
- 后端统一使用 createDownloadError 创建标准化错误响应
- 前端统一使用 parseDownloadError 解析错误并显示
- 修复正式系统数据库Schema,添加产品全案相关字段和表
- 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段
- 创建 material_assets, api_keys, api_call_logs 表
2026-01-05 17:52:42 +08:00

7.3 KiB
Raw Blame History

阶段三实施总结:部门层级结构

实施日期: 2025-12-30
状态: ✅ Schema更新完成,迁移脚本已创建
下一步: 需要在应用Schema变更后运行迁移脚本


📋 实施内容

1. Schema 变更

文件: prisma/schema.prisma

变更内容: 在 Department 模型中添加层级结构字段

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 模型:

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. 验证数据完整性(检查父部门是否存在,层级是否一致)

使用方法:

# 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更新

  • GET /api/departments - 支持层级查询(includeHierarchy 参数)
  • POST /api/departments - 支持创建子部门(parentId, level, code, status 等参数)
  • GET /api/departments/[id] - 获取部门详情(包含层级信息)
  • PUT /api/departments/[id] - 更新部门信息(包括层级关系、状态等)
  • DELETE /api/departments/[id] - 删除部门(包含安全检查:子部门和用户检查)
  • DELETE /api/departments - 更新删除逻辑(向后兼容)

✅ 检查清单

Schema 变更

  • 添加 code 字段(可选,唯一)
  • 添加 parentId 字段(可选外键)
  • 添加 level 字段(默认值 1)
  • 添加 managerId 字段(可选外键)
  • 添加 status 字段(默认值 'active')
  • 添加 description 字段(可选)
  • 添加 sortOrder 字段(默认值 0)
  • 添加 updatedAt 字段
  • 添加自关联关系(parent/children)
  • 添加负责人关联关系(manager/managedDepartments)
  • 添加必要索引

迁移脚本

  • 创建迁移脚本
  • 实现默认值设置逻辑
  • 实现编码生成逻辑
  • 实现数据验证逻辑
  • 实现完整性检查

验证脚本

  • 更新 verifyStage3() 函数
  • 使用 Prisma API 进行验证
  • 处理字段不存在的情况(阶段三未实施时跳过)

API更新

  • 更新 GET /api/departments - 支持层级查询(includeHierarchy 参数)
  • 更新 POST /api/departments - 支持创建子部门(parentId, level, code, status 等参数)
  • 创建 GET /api/departments/[id] - 获取部门详情(包含层级信息)
  • 创建 PUT /api/departments/[id] - 更新部门信息(包括层级关系、状态等)
  • 创建 DELETE /api/departments/[id] - 删除部门(包含安全检查)
  • 更新 DELETE /api/departments - 增加安全检查(向后兼容)
  • 实现循环引用检查
  • 实现删除前安全检查(子部门、用户检查)

🚨 注意事项

向后兼容

  • ✅ 所有新字段都是可选的,不会影响现有数据
  • ✅ 保留 name 字段,现有代码继续工作
  • ✅ 默认值确保现有部门自动成为一级部门

数据迁移

  • ⚠️ 必须先应用Schema变更(prisma db push 或 prisma migrate dev)
  • ⚠️ 迁移脚本需要在Schema更新后运行,否则会出现TypeScript类型错误
  • ⚠️ 部门编码生成使用顺序编号,如果后续需要调整层级,可能需要重新生成编码
  • ⚠️ 层级关系需要在后续业务逻辑中设置(迁移脚本只设置默认值)

性能考虑

  • ✅ 添加了必要的索引优化查询性能
  • ✅ level 字段冗余存储,避免递归查询
  • ⚠️ 层级查询需要在代码中优化(使用递归或CTE)

文档版本: 1.0
创建日期: 2025-12-30
最后更新: 2025-12-30