Quellcode durchsuchen

docs(story): 新增故事017.009 - 管理后台用户管理功能完善

## 问题分析
史诗017缺少管理后台用户管理功能,导致人才用户无法登录:
- 后端API已支持userType和personId字段
- 数据库Schema已就绪
- 残疾人选择器组件已存在
- 但UserManagement组件缺少这两个字段

## 解决方案
新增故事017.009(P0阻塞性任务):
1. 创建DisabledPersonSelectorWrapper组件
2. 添加userType下拉选择器
3. 实现条件渲染逻辑(人才用户显示残疾人选择器)
4. 更新表单Schema和验证
5. 完善用户体验和测试

## 影响
- 优先级:P0(阻塞其他故事测试)
- 史诗017故事总数:8→9
- 状态:Approved

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname vor 3 Wochen
Ursprung
Commit
4e393d45ef
2 geänderte Dateien mit 322 neuen und 4 gelöschten Zeilen
  1. 44 4
      docs/prd/epic-017-talent-mini-program-implementation.md
  2. 278 0
      docs/stories/017.009.story.md

+ 44 - 4
docs/prd/epic-017-talent-mini-program-implementation.md

@@ -3,15 +3,17 @@
 ## 史诗目标
 在mini-talent项目中完整实现人才小程序的所有页面功能,基于史诗015已创建的API模块基础,为残疾人用户提供个人信息管理、考勤记录、就业信息查询等完整的服务体验,并创建rencai mini ui包提供可复用的UI组件。
 
-## 状态更新(2025-12-25
+## 状态更新(2025-12-26
 - **依赖状态**:史诗015已完成3/8核心故事(38%),核心API就绪
 - **启动建议**:史诗017可以立即开始,与史诗015并行开发
 - **调整说明**:参照史诗011(用人方小程序)的成功模式,采用相同的架构和开发规范
-- **故事拆分**:史诗拆分为8个故事,便于逐步开发和测试
+- **🔴 重要发现**:缺少管理后台用户管理功能,导致人才用户无法登录!已补充故事017.009(P0阻塞性任务)
+- **故事拆分**:史诗拆分为9个故事,便于逐步开发和测试
 - **整体进度**:
   - ✅ 故事017.001已完成 (rencai mini ui包基础框架搭建)
   - ✅ 故事017.002已完成 (登录与首页实现)
-  - ⏳ 故事017.003-017.008待开始
+  - 🔴 故事017.009为P0阻塞性任务(管理后台用户管理功能完善)
+  - ⏳ 故事017.003-017.008、017.010待开始
 
 ## 史诗描述
 
@@ -273,7 +275,45 @@
 
 ### 故事017.008:性能优化与测试完善 ⏳ 待开始
 **状态**: ⏳ Pending
-**背景:** 依赖故事017.001-017.007完成的所有功能,进行性能优化和测试完善,确保人才小程序达到生产环境质量标准。
+**背景:** 依赖故事017.001-017.007和017.009完成的所有功能,进行性能优化和测试完善,确保人才小程序达到生产环境质量标准。
+
+**注意**: 故事017.009为P0优先级阻塞性任务,必须在性能优化之前完成,否则人才用户无法登录小程序。
+
+### 故事017.009:管理后台用户管理功能完善 🔴 P0 - 阻塞性任务
+**状态**: ✅ Approved (清晰度评分: 10/10)
+**优先级**: P0 - 阻塞性任务(人才登录必需)
+**背景:** 史诗015已完成人才用户认证API,支持通过`personId`关联残疾人记录。但管理后台的用户管理页面缺少创建人才用户的功能,导致残疾人无法登录人才小程序。
+
+**问题分析:**
+- 后端API已支持: `CreateUserDto`/`UpdateUserDto`包含`userType`和`personId`字段
+- 数据库已支持: `users2`表包含`userType`字段(支持admin/employer/talent)和`personId`字段
+- 残疾人选择器已存在: `@d8d/allin-disability-person-management-ui/components/DisabledPersonSelector`
+- **前端组件缺失**: `UserManagement`组件缺少`userType`和`personId`字段
+
+**详细设计文档**: [docs/stories/017.009.story.md](../stories/017.009.story.md)
+
+**任务列表:**
+1. 创建`DisabledPersonSelectorWrapper`组件,封装残疾人选择器
+2. 在`UserManagement`组件中添加`userType`下拉选择器
+3. 实现条件渲染:当`userType='talent'`时显示残疾人选择器
+4. 更新表单Schema和默认值,支持`userType`和`personId`字段
+5. 优化用户体验:添加表单验证、错误提示、加载状态
+6. 用户列表添加"用户类型"和"关联残疾人"列
+7. 编写测试:组件测试、集成测试、E2E测试
+8. 更新文档和史诗进度
+
+**验收标准:**
+- [ ] 管理员可以在用户管理页面创建人才用户
+- [ ] 选择用户类型为"人才用户"时,显示残疾人选择器
+- [ ] 创建人才用户成功后,`users2`记录包含正确的`userType='talent'`和`personId`
+- [ ] 创建的人才用户可以使用身份证号/残疾证号登录人才小程序
+- [ ] 用户列表正确显示用户类型和关联的残疾人信息
+- [ ] 所有测试通过(组件测试、集成测试、E2E测试、类型检查)
+- [ ] 现有功能不受影响(admin和employer用户创建流程)
+
+### 故事017.010:性能优化与测试完善 ⏳ 待开始
+**状态**: ⏳ Pending
+**背景:** 依赖故事017.001-017.009完成的所有功能,进行性能优化和测试完善,确保人才小程序达到生产环境质量标准。
 
 **任务列表:**
 1. **性能优化**:

+ 278 - 0
docs/stories/017.009.story.md

@@ -0,0 +1,278 @@
+# 故事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 && (
+  <FormField
+    control={createForm.control}
+    name="personId"
+    render={({ field }) => (
+      <FormItem>
+        <FormLabel>关联残疾人</FormLabel>
+        <FormControl>
+          <DisabledPersonSelectorWrapper
+            value={field.value}
+            onChange={field.onChange}
+            placeholder="请选择残疾人"
+          />
+        </FormControl>
+        <FormMessage />
+      </FormItem>
+    )}
+  />
+)}
+```
+
+## 风险与注意事项
+
+**风险1: 残疾人选择器API不兼容**
+- **缓解措施**: 确认`DisabledPersonSelector`组件的props接口,必要时创建适配器
+
+**风险2: 表单验证逻辑复杂**
+- **缓解措施**: 使用react-hook-form的自定义验证规则,清晰定义验证逻辑
+
+**风险3: 现有功能回归**
+- **缓解措施**: 充分测试admin和employer用户创建流程,确保不受影响
+
+**风险4: 数据一致性**
+- **缓解措施**: 确保后端API正确处理`userType`和`personId`字段的关联关系
+
+## 兼容性要求
+
+- [ ] 现有admin用户创建流程不受影响
+- [ ] 现有employer用户创建流程不受影响
+- [ ] 用户列表表格兼容新增的用户类型列
+- [ ] 响应式布局在不同屏幕尺寸下正常显示
+- [ ] 现有用户编辑功能不受影响
+
+## 完成定义
+
+- [ ] 所有任务完成,验收标准全部满足
+- [ ] 管理员可以通过管理后台创建人才用户
+- [ ] 创建的人才用户可以成功登录人才小程序
+- [ ] 所有测试通过(组件测试、集成测试、E2E测试)
+- [ ] 类型检查通过
+- [ ] 代码审查通过
+- [ ] 文档更新完成
+
+## Dev Agent Record
+
+### 实现笔记
+_在此记录实现过程中的关键决策和技术细节_
+
+### 调试日志
+_在此记录遇到的问题和解决方案_
+
+### 完成总结
+_在此记录任务完成后的总结和改进建议_