# 故事017.009: 管理后台用户管理功能完善 ## 元信息 - **史诗**: 017 - 人才小程序功能实现 - **优先级**: P0 - 阻塞性任务(人才登录必需) - **状态**: Approved - **创建日期**: 2025-12-26 - **负责人**: 开发团队 ## 故事描述 **作为** 系统管理员, **我想要** 在管理后台的用户管理页面中创建和编辑人才用户, **以便** 残疾人能够配置为人才用户并使用身份证号/残疾证号登录人才小程序。 ### 背景 **现有系统状态:** - 史诗015已完成人才用户认证API,支持通过`personId`关联残疾人记录 - 数据库`users2`表已包含`userType`字段(支持admin/employer/talent)和`personId`字段 - 后端Schema(`CreateUserDto`/`UpdateUserDto`)已支持`userType`和`personId`字段 - 管理后台路由已配置`/admin/users`,使用`@d8d/user-management-ui`的`UserManagement`组件 - 残疾人选择器组件已存在:`@d8d/allin-disability-person-management-ui/components/DisabledPersonSelector` **问题分析:** - 前端`UserManagement`组件的创建/编辑表单**缺少**`userType`下拉选择器 - 前端`UserManagement`组件**缺少**`personId`残疾人选择器字段 - 当选择人才用户类型时,无法关联残疾人记录 - **结果**: 残疾人无法登录人才小程序,因为缺少`users2`记录中的`personId`关联 **人才登录流程(史诗015已实现):** ``` 身份证号/残疾证号 → disabled_person表 → person_id → users2表 (user_type='talent') ``` **关键依赖:** - `packages/user-management-ui/src/components/UserManagement.tsx` - 需要修改 - `@d8d/allin-disability-person-management-ui/components/DisabledPersonSelector` - 已存在 - `packages/core-module/user-module/src/schemas/user.schema.ts` - Schema已支持 ### 技术实现方案 **需要添加的字段:** 1. **userType下拉选择器** - 选择用户类型(admin/employer/talent) 2. **personId残疾人选择器** - 当`userType='talent'`时显示 **条件渲染逻辑:** - 默认隐藏残疾人选择器 - 当选择用户类型为"人才用户"时,显示残疾人选择器 - 当选择用户类型为"企业用户"时,显示企业选择器(已存在) **复用现有模式:** - 参考`CompanySelectorWrapper`组件模式创建`DisabledPersonSelectorWrapper` - 使用`@d8d/allin-disability-person-management-ui/components`的`DisabledPersonSelector` ## 验收标准 ### 功能完整性 - [ ] 管理员可以在用户管理页面创建用户时选择用户类型(admin/employer/talent) - [ ] 当选择"人才用户"类型时,显示残疾人选择器 - [ ] 残疾人选择器支持搜索、筛选、分页功能 - [ ] 创建人才用户成功后,`users2`记录包含正确的`userType='talent'`和`personId` - [ ] 编辑用户时可以修改用户类型和残疾人关联 ### 用户体验 - [ ] 用户类型切换流畅,选择器位置合理 - [ ] 残疾人选择器对话框功能完整(搜索、筛选、分页) - [ ] 表单验证正确,必填字段提示清晰 - [ ] 错误提示友好,操作反馈及时 ### 集成验证 - [ ] 创建人才用户后,残疾人可以使用身份证号/残疾证号登录人才小程序 - [ ] 登录流程验证:身份证号/残疾证号 → 找到残疾人记录 → 通过personId找到用户 → 登录成功 - [ ] 用户列表正确显示用户类型和关联的残疾人信息 - [ ] 现有功能不受影响(admin用户和employer用户创建流程不变) ### 测试覆盖 - [ ] 编写组件测试验证用户类型选择器功能 - [ ] 编写集成测试验证残疾人选择器集成 - [ ] 编写E2E测试验证完整的人才用户创建和登录流程 - [ ] 类型检查通过(`pnpm typecheck`) ## 任务列表 ### 任务1: 创建DisabledPersonSelectorWrapper组件 (AC: 功能完整性) - [ ] 1.1 在`packages/user-management-ui/src/components/`下创建`DisabledPersonSelectorWrapper.tsx` - [ ] 1.2 参考`CompanySelectorWrapper.tsx`的实现模式 - [ ] 1.3 集成`@d8d/allin-disability-person-management-ui/components/DisabledPersonSelector` - [ ] 1.4 实现单选模式(`mode='single'`) - [ ] 1.5 支持显示已选择的残疾人信息(姓名、残疾证号) - [ ] 1.6 支持清除选择功能 - [ ] 1.7 添加`data-testid`测试选择器 **组件接口设计:** ```typescript interface DisabledPersonSelectorWrapperProps { value: number | null; // personId onChange: (value: number | null) => void; placeholder?: string; disabled?: boolean; } ``` ### 任务2: 扩展UserManagement组件 - 添加userType字段 (AC: 功能完整性) - [ ] 2.1 在创建用户表单中添加`userType`字段(FormField) - [ ] 2.2 使用`Select`组件实现下拉选择器 - [ ] 2.3 添加用户类型选项: admin(管理员), employer(企业用户), talent(人才用户) - [ ] 2.4 在编辑用户表单中添加`userType`字段 - [ ] 2.5 更新表单默认值,`userType`默认为`admin` - [ ] 2.6 添加表单验证,`userType`为必填字段 - [ ] 2.7 添加`data-testid="user-type-select"` ### 任务3: 实现条件渲染逻辑 (AC: 功能完整性, 用户体验) - [ ] 3.1 添加`useWatch`或`useState`监听`userType`字段变化 - [ ] 3.2 当`userType === 'talent'`时,显示残疾人选择器 - [ ] 3.3 当`userType === 'employer'`时,显示企业选择器(已存在) - [ ] 3.4 当`userType === 'admin'`时,隐藏企业选择器和残疾人选择器 - [ ] 3.5 添加条件渲染的过渡动画(可选) - [ ] 3.6 确保切换用户类型时,清空不相关字段的值 ### 任务4: 集成DisabledPersonSelectorWrapper到表单 (AC: 功能完整性) - [ ] 4.1 在创建用户表单中添加`personId`字段(FormField) - [ ] 4.2 条件渲染:仅当`userType === 'talent'`时显示 - [ ] 4.3 使用`DisabledPersonSelectorWrapper`组件 - [ ] 4.4 添加字段描述:"选择关联的残疾人记录" - [ ] 4.5 在编辑用户表单中添加`personId`字段 - [ ] 4.6 编辑模式下显示当前关联的残疾人信息 - [ ] 4.7 添加`data-testid="disabled-person-selector"` ### 任务5: 更新表单Schema和默认值 (AC: 功能完整性) - [ ] 5.1 确认`CreateUserDto`包含`userType`和`personId`字段 - [ ] 5.2 确认`UpdateUserDto`包含`userType`和`personId`字段 - [ ] 5.3 更新创建表单默认值: ```typescript defaultValues: { ...existingFields, userType: UserType.ADMIN, // 新增 personId: null, // 新增 } ``` - [ ] 5.4 更新编辑表单默认值逻辑,加载现有用户的`userType`和`personId` - [ ] 5.5 确保表单提交时包含`userType`和`personId`字段 ### 任务6: 用户体验优化 (AC: 用户体验) - [ ] 6.1 用户类型选择器添加图标或颜色标识 - [ ] 6.2 残疾人选择器打开时显示搜索提示 - [ ] 6.3 选择残疾人后显示姓名和残疾证号(便于确认) - [ ] 6.4 添加表单验证提示: - 选择人才用户时,残疾人为必填 - 选择企业用户时,企业为必填 - [ ] 6.5 优化错误提示信息 - [ ] 6.6 添加加载状态提示 ### 任务7: 用户列表显示优化 (AC: 集成验证) - [ ] 7.1 在用户列表表格中添加"用户类型"列 - [ ] 7.2 使用Badge组件区分用户类型(不同颜色) - [ ] 7.3 添加"关联残疾人"列,显示残疾人姓名 - [ ] 7.4 人才用户行显示残疾人信息,其他用户显示"-" - [ ] 7.5 更新表格列宽和响应式布局 ### 任务8: 测试编写 (AC: 测试覆盖) - [ ] 8.1 编写`DisabledPersonSelectorWrapper`组件测试 - 测试渲染正确性 - 测试选择功能 - 测试清除功能 - [ ] 8.2 编写`UserManagement`组件集成测试 - 测试用户类型切换 - 测试条件渲染逻辑 - 测试表单提交 - [ ] 8.3 编写E2E测试 - 测试完整的人才用户创建流程 - 测试人才用户登录小程序流程 - [ ] 8.4 运行类型检查`pnpm typecheck` - [ ] 8.5 确保所有测试通过 ### 任务9: 文档更新 (AC: 集成验证) - [ ] 9.1 更新史诗017的PRD文档,标记故事017.009为进行中 - [ ] 9.2 在本故事的Dev Agent Record中记录实现细节 - [ ] 9.3 添加使用说明:如何在管理后台创建人才用户 - [ ] 9.4 更新史诗017的进度统计 ## 技术细节 ### 组件依赖关系 ``` UserManagement ├── DisabledPersonSelectorWrapper (新建) │ └── DisabledPersonSelector (已存在,来自@d8d/allin-disability-person-management-ui) ├── CompanySelectorWrapper (已存在) └── Form, Select,等 (来自@d8d/shared-ui-components) ``` ### 包依赖更新 需要在`packages/user-management-ui/package.json`中添加: ```json { "dependencies": { "@d8d/allin-disability-person-management-ui": "workspace:*" } } ``` ### UserType枚举值 ```typescript enum UserType { ADMIN = 'admin', // 管理员 EMPLOYER = 'employer', // 企业用户 TALENT = 'talent' // 人才用户 } ``` ### 条件渲染逻辑示例 ```typescript const userType = createForm.watch('userType'); {userType === UserType.TALENT && ( ( 关联残疾人 )} /> )} ``` ## 风险与注意事项 **风险1: 残疾人选择器API不兼容** - **缓解措施**: 确认`DisabledPersonSelector`组件的props接口,必要时创建适配器 **风险2: 表单验证逻辑复杂** - **缓解措施**: 使用react-hook-form的自定义验证规则,清晰定义验证逻辑 **风险3: 现有功能回归** - **缓解措施**: 充分测试admin和employer用户创建流程,确保不受影响 **风险4: 数据一致性** - **缓解措施**: 确保后端API正确处理`userType`和`personId`字段的关联关系 ## 兼容性要求 - [ ] 现有admin用户创建流程不受影响 - [ ] 现有employer用户创建流程不受影响 - [ ] 用户列表表格兼容新增的用户类型列 - [ ] 响应式布局在不同屏幕尺寸下正常显示 - [ ] 现有用户编辑功能不受影响 ## 完成定义 - [ ] 所有任务完成,验收标准全部满足 - [ ] 管理员可以通过管理后台创建人才用户 - [ ] 创建的人才用户可以成功登录人才小程序 - [ ] 所有测试通过(组件测试、集成测试、E2E测试) - [ ] 类型检查通过 - [ ] 代码审查通过 - [ ] 文档更新完成 ## Dev Agent Record ### 实现笔记 _在此记录实现过程中的关键决策和技术细节_ ### 调试日志 _在此记录遇到的问题和解决方案_ ### 完成总结 _在此记录任务完成后的总结和改进建议_