# 故事 012.009：管理后台企业用户配置表单扩展

## 状态
Ready for Review

## 故事
**作为**管理员，
**我希望**在管理后台的用户管理表单中能够配置用户所属的企业，
**以便**为企业用户分配正确的企业关联，支持用人方小程序的企业用户认证功能。

## 验收标准
1. [x] 用户创建表单中包含企业选择字段（下拉选择框），可选值为系统中的企业列表
2. [x] 用户编辑表单中包含企业选择字段，显示当前用户关联的企业并可修改
3. [x] 用户列表显示中可查看用户关联的企业信息
4. [x] 企业选择字段支持清空（设置为NULL），表示用户不关联任何企业
5. [x] 表单验证正确，企业ID必须为有效的企业ID或NULL
6. [x] 所有现有功能不受影响，测试通过

## 任务 / 子任务
将故事分解为实施所需的具体任务和子任务。
在相关处引用适用的验收标准编号。

- [x] 任务1：集成现有企业选择组件（AC：1,2,4,5）
  - [x] 在user-management-ui中导入`@d8d/allin-company-management-ui`包的`CompanySelector`组件
  - [x] 调研CompanySelector组件的API接口和用法
  - [x] 验证companyId字段的表单验证兼容性（支持NULL值）
- [x] 任务2：扩展用户创建表单（AC：1,4,5）
  - [x] 在`packages/user-management-ui/src/components/UserManagement.tsx`的创建表单中添加企业选择字段
  - [x] 使用CompanySelector组件实现企业下拉选择
  - [x] 确保companyId字段正确传递给创建用户API（支持NULL值）
  - [x] 添加表单验证，企业ID必须为有效的企业ID或NULL
- [x] 任务3：扩展用户编辑表单（AC：2,4,5）
  - [x] 在编辑表单中添加企业选择字段
  - [x] 使用CompanySelector组件，初始化表单时加载当前用户的companyId值
  - [x] 确保更新用户API正确接收companyId字段（支持NULL值）
- [x] 任务4：扩展用户列表显示（AC：3）
  - [x] 在用户列表表格中添加"关联企业"列
  - [x] 显示企业名称（通过CompanySelector的数据格式或调用企业API获取）
  - [x] 确保分页和筛选功能不受影响
- [x] 任务5：测试与验证（AC：6）
  - [x] 编写单元测试验证企业选择字段功能（使用CompanySelector组件）
  - [x] 编写集成测试验证表单提交和数据显示
  - [x] 运行现有测试确保无回归
  - [x] 测试企业选择字段的清空功能（设置为NULL）

## 开发笔记
仅填充从docs文件夹中的实际工件提取的相关信息，与此故事相关：

### 先前故事洞察
- 故事012.001已添加`companyId`字段到`users2`表和UserSchema
- UserSchema中的`companyId`字段已定义为`z.number().int().positive().nullable()`
- CreateUserDtoMt和UpdateUserDtoMt已包含`companyId`字段
- 企业数据通过company-module管理，应使用现有企业列表API

### 技术上下文
- **前端包**: `@d8d/user-management-ui` (UserManagement组件)
- **API客户端**: 使用RPC方式，已包含`companyId`字段支持
- **企业数据源**: `@d8d/allin-company-management-ui` 的CompanySelector组件
- **表单库**: react-hook-form + zodResolver
- **UI组件**: 直接使用现有CompanySelector组件（基于shadcn/ui Select）

### 现有组件发现
- **组件名称**: `CompanySelector`
- **位置**: `allin-packages/company-management-ui/src/components/CompanySelector.tsx`
- **功能**: 企业下拉选择组件，内置企业列表查询、加载状态、错误处理
- **接口**: `value?: number`, `onChange?: (value: number) => void`, `placeholder?`, `disabled?`, `className?`, `data-testid?`, `platformId?`
- **数据源**: 自动调用company-module API获取企业列表，支持按平台过滤
- **优势**: 无需重新开发，样式一致，功能完整，支持NULL值传递

### 依赖关系
- 依赖企业模块（company-module）提供企业列表API
- 依赖故事012.001的数据库schema扩展
- 依赖`@d8d/allin-company-management-ui`包的CompanySelector组件
- 不影响现有用户管理功能

### 风险与缓解
- **风险**: CompanySelector组件可能不直接支持NULL值传递
  - **缓解**: 创建CompanySelectorWrapper组件处理NULL值兼容性，将null转换为undefined
- **风险**: 企业数据量过大影响下拉选择性能
  - **缓解**: CompanySelector组件已实现分页（取前100条），性能可控
- **风险**: 组件版本兼容性问题
  - **缓解**: 验证现有组件版本与user-management-ui的兼容性
- **风险**: API响应不包含company关联数据
  - **缓解**: 更新用户路由配置，添加company到relations数组

### 实施细节
- **CompanySelectorWrapper组件**: 创建包装组件处理NULL值兼容性，将null转换为undefined供CompanySelector使用
- **表单集成**: 在UserManagement组件的创建和编辑表单中添加CompanySelectorWrapper
- **列表显示**: 在用户列表中添加"关联企业"列，显示`user.company?.companyName || '无'`
- **API响应**: 更新user.routes.ts和user.routes.mt.ts，添加company到relations配置
- **测试更新**: 更新集成测试期望包含companyId字段

## 文件列表
在此故事中创建、修改或删除的源文件列表（实施后填写）：
- `packages/user-management-ui/src/components/CompanySelectorWrapper.tsx` (新建 - 企业选择器包装组件，支持NULL值)
- `packages/user-management-ui/src/components/UserManagement.tsx` (修改 - 添加CompanySelectorWrapper导入和使用，创建/编辑表单添加企业选择字段，用户列表添加关联企业列)
- `packages/user-management-ui/src/components/index.ts` (修改 - 导出CompanySelectorWrapper组件)
- `packages/user-management-ui/package.json` (修改 - 添加对`@d8d/allin-company-management-ui`的依赖)
- `packages/core-module/user-module/src/schemas/user.schema.ts` (修改 - 添加company字段到UserSchemaMt)
- `packages/user-management-ui/tests/integration/userManagement.integration.test.tsx` (修改 - 更新测试期望包含companyId字段)
- `packages/core-module/user-module/src/routes/user.routes.ts` (修改 - 添加company到relations配置)
- `packages/core-module-mt/user-module-mt/src/routes/user.routes.mt.ts` (修改 - 添加company到relations配置)

## 变更日志
| 日期 | 变更描述 | 作者 |
|------|----------|------|
| 2025-12-18 | 创建故事文档 | James |
| 2025-12-18 | 发现现有CompanySelector组件并更新任务列表 | James |
| 2025-12-18 | 实施故事：添加CompanySelectorWrapper组件，扩展用户创建/编辑表单，添加关联企业列，更新schema和测试 | James |
| 2025-12-18 | 修复用户路由配置，添加company关联到relations | James |

## 代理模型使用
- Claude Sonnet (分析现有代码和创建故事)

## 调试日志引用
- 无

## 完成备注列表
- ✅ 所有验收标准已满足
- ✅ 所有任务已完成
- ✅ 测试通过，构建成功
- ✅ 史诗012所有核心故事已完成
- ✅ 代码已提交到git仓库