|
|
@@ -0,0 +1,198 @@
|
|
|
+# Story 008.004: 移植薪资管理UI(salary → @d8d/allin-salary-management-ui)
|
|
|
+
|
|
|
+## Status
|
|
|
+Draft
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 开发者,
|
|
|
+**I want** 将salary管理页面从allin_system-master/client移植为独立UI包@d8d/allin-salary-management-ui,完成技术栈转换并集成区域选择器组件,
|
|
|
+**so that** 我们可以将Allin系统的薪资管理UI模块集成到当前项目中,遵循现有的UI包结构和编码标准,并正确集成区域选择器组件用于薪资区域关联管理。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. 创建`allin-packages/salary-management-ui`目录结构
|
|
|
+2. 完成组件转换:薪资表格、复杂表单组件
|
|
|
+3. **区域包集成**:集成`@d8d/area-management-ui`的区域选择器组件
|
|
|
+4. 完成API客户端转换:薪资计算API(使用rpcClient + ClientManager模式)
|
|
|
+5. 完成状态管理转换:数值计算状态
|
|
|
+6. 完成表单转换:复杂数值验证
|
|
|
+7. 配置package.json:依赖`@d8d/area-management-ui`
|
|
|
+8. 编写组件测试:验证数值计算和验证
|
|
|
+9. 通过类型检查和基本测试验证
|
|
|
+
|
|
|
+**集成测试要求**:
|
|
|
+- 测试文件:`tests/integration/salary.integration.test.tsx`
|
|
|
+- 测试覆盖:完整CRUD流程、错误处理、区域选择功能、数值计算验证
|
|
|
+- 验证:数据渲染、用户交互、API调用、状态管理、区域选择器集成
|
|
|
+- 遵循现有集成测试模式
|
|
|
+
|
|
|
+**区域选择器集成要求**:
|
|
|
+- 使用`@d8d/area-management-ui`的`AreaSelect`组件
|
|
|
+- 实现省份→城市→区县三级联动
|
|
|
+- 表单验证包含区域ID验证
|
|
|
+- 测试区域选择功能
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [ ] 任务1:创建薪资管理UI包基础结构 (AC: 1, 7)
|
|
|
+ - [ ] 创建目录:`allin-packages/salary-management-ui/`
|
|
|
+ - [ ] 复制并修改package.json:参考`allin-packages/platform-management-ui/package.json`,更新包名为`@d8d/allin-salary-management-ui`,添加对`@d8d/area-management-ui`的依赖
|
|
|
+ - [ ] 复制并修改tsconfig.json:参考`allin-packages/platform-management-ui/tsconfig.json`
|
|
|
+ - [ ] 复制并修改vitest.config.ts:参考`allin-packages/platform-management-ui/vitest.config.ts`
|
|
|
+ - [ ] 创建基础目录结构:`src/`、`src/components/`、`src/api/`、`src/hooks/`、`src/types/`、`tests/`
|
|
|
+
|
|
|
+- [ ] 任务2:分析源UI页面结构和区域选择器集成 (AC: 2, 3)
|
|
|
+ - [ ] 分析源文件:`allin_system-master/client/app/admin/dashboard/salary/page.tsx`
|
|
|
+ - [ ] 查看区域选择器组件:`packages/area-management-ui/src/components/AreaSelect.tsx`
|
|
|
+ - [ ] 参考对照文件:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`和`allin-packages/company-management-ui/src/components/CompanyManagement.tsx`
|
|
|
+ - [ ] 创建主组件:`src/components/SalaryManagement.tsx`
|
|
|
+ - [ ] 转换Ant Design组件为@d8d/shared-ui-components组件
|
|
|
+ - [ ] 集成区域选择器:使用`AreaSelect`组件替换原有的省份、城市、区县选择逻辑
|
|
|
+
|
|
|
+- [ ] 任务3:查看薪资模块RPC API调用路径并创建API客户端 (AC: 4)
|
|
|
+ - [ ] 查看薪资模块集成测试:`allin-packages/salary-module/tests/integration/salary.integration.test.ts`
|
|
|
+ - [ ] 查看薪资模块路由定义:`allin-packages/salary-module/src/routes/salary-custom.routes.ts`
|
|
|
+ - [ ] 创建RPC客户端:`src/api/salaryClient.ts`
|
|
|
+ - [ ] 实现`SalaryClientManager`类:使用rpcClient + ClientManager单例模式
|
|
|
+ - [ ] 导出`salaryClientManager`单例实例和`salaryClient`默认客户端实例
|
|
|
+ - [ ] 创建类型定义:`src/api/types.ts`
|
|
|
+
|
|
|
+- [ ] 任务4:完成状态管理和表单转换 (AC: 5, 6)
|
|
|
+ - [ ] 转换Jotai状态管理为React Query
|
|
|
+ - [ ] 转换Ant Design Form为React Hook Form + Zod
|
|
|
+ - [ ] 使用后端模块提供的Schema:`CreateSalarySchema`和`UpdateSalarySchema`
|
|
|
+ - [ ] 集成数值计算逻辑:基本工资、津贴、保险、公积金等计算
|
|
|
+ - [ ] 实现复杂数值验证:正数验证、范围验证等
|
|
|
+
|
|
|
+- [ ] 任务5:编写集成测试 (AC: 8)
|
|
|
+ - [ ] 创建测试文件:`tests/integration/salary.integration.test.tsx`
|
|
|
+ - [ ] 实现完整CRUD流程测试:创建薪资 → 查询薪资列表 → 更新薪资 → 删除薪资
|
|
|
+ - [ ] 实现区域选择器集成测试:验证省份→城市→区县三级联动
|
|
|
+ - [ ] 实现数值计算测试:验证薪资计算逻辑
|
|
|
+ - [ ] 实现错误处理测试:API错误、网络错误、验证错误
|
|
|
+
|
|
|
+- [ ] 任务6:验证和测试 (AC: 9)
|
|
|
+ - [ ] 运行`pnpm typecheck`确保无类型错误
|
|
|
+ - [ ] 运行`pnpm test`确保所有集成测试通过
|
|
|
+ - [ ] 验证区域选择器组件集成正常工作
|
|
|
+ - [ ] 验证数值计算和表单验证功能
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 从前一个故事学到的关键经验(故事008.003):
|
|
|
+1. **Schema设计一致性验证**:必须查看后端模块的集成测试和路由定义来确保Schema设计正确,不能仅凭前端使用场景假设。
|
|
|
+2. **API路径一致性验证**:必须根据后端实际路由设计前端API调用,不能假设为标准CRUD模式。
|
|
|
+3. **测试精度优化**:在测试中使用test ID比文本查找更精确可靠。
|
|
|
+4. **类型推导优化**:遵循现有UI包的模式,使用正确的RPC类型推导语法。
|
|
|
+5. **表单组件模式规范**:必须使用条件渲染两个独立的Form组件,避免在单个Form组件上动态切换props。
|
|
|
+
|
|
|
+### 技术栈规范 [Source: docs/architecture/ui-package-standards.md]
|
|
|
+- **包结构规范**:标准目录结构,包含components、api、hooks、types目录
|
|
|
+- **RPC客户端实现规范**:必须使用ClientManager单例模式管理RPC客户端生命周期
|
|
|
+- **组件开发规范**:使用@d8d/shared-ui-components组件库,React Query进行状态管理
|
|
|
+- **类型定义规范**:使用RPC推断类型,避免重新定义类型
|
|
|
+- **测试规范**:集成测试、组件测试、单元测试分层结构
|
|
|
+- **表单组件模式规范**:必须使用条件渲染两个独立的Form组件,避免在单个Form组件上动态切换props
|
|
|
+
|
|
|
+### 项目结构信息 [Source: docs/architecture/source-tree.md]
|
|
|
+- **UI包位置**:`allin-packages/salary-management-ui/`(Allin系统专属包目录)
|
|
|
+- **参考实现**:
|
|
|
+ - `allin-packages/platform-management-ui/`(已完成的平台管理UI包)
|
|
|
+ - `allin-packages/channel-management-ui/`(已完成的渠道管理UI包)
|
|
|
+ - `allin-packages/company-management-ui/`(已完成的公司管理UI包)
|
|
|
+- **后端模块**:`allin-packages/salary-module/`(对应的后端模块)
|
|
|
+- **区域管理UI包**:`packages/area-management-ui/`(需要集成的区域选择器组件)
|
|
|
+
|
|
|
+### 源系统文件路径
|
|
|
+- **需要移植的源文件**:`allin_system-master/client/app/admin/dashboard/salary/page.tsx`
|
|
|
+- **需要对照参考的文件**:
|
|
|
+ - `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
|
|
|
+ - `allin-packages/platform-management-ui/src/api/platformClient.ts`
|
|
|
+ - `allin-packages/platform-management-ui/src/api/types.ts`
|
|
|
+ - `allin-packages/platform-management-ui/tests/integration/platform.integration.test.tsx`
|
|
|
+ - `allin-packages/company-management-ui/src/components/CompanyManagement.tsx`
|
|
|
+ - `allin-packages/company-management-ui/src/api/companyClient.ts`
|
|
|
+ - `allin-packages/company-management-ui/src/types/index.ts`
|
|
|
+- **区域选择器组件文件**:
|
|
|
+ - `packages/area-management-ui/src/components/AreaSelect.tsx`
|
|
|
+ - `packages/area-management-ui/src/api/areaClient.ts`
|
|
|
+
|
|
|
+### 薪资模块RPC API调用信息(基于集成测试和路由定义)
|
|
|
+- **RPC客户端调用方式**(来自`allin-packages/salary-module/tests/integration/salary.integration.test.ts`和`allin-packages/salary-module/src/routes/salary-custom.routes.ts`):
|
|
|
+ - `salaryClientManager.get().create.$post({ json: salaryData })` - 创建薪资记录
|
|
|
+ - `salaryClientManager.get().update[':id'].$put({ param: { id }, json: salaryData })` - 更新薪资记录
|
|
|
+ - `salaryClientManager.get().delete[':id'].$delete({ param: { id } })` - 删除薪资记录
|
|
|
+ - `salaryClientManager.get().$get({ query: { page, pageSize, filters, sortBy, sortOrder } })` - 获取薪资列表(分页)
|
|
|
+ - `salaryClientManager.get()[':id'].$get({ param: { id } })` - 获取薪资详情
|
|
|
+ - `salaryClientManager.get().getByProvinceCity.$get({ query: { provinceId, cityId } })` - 按省份城市获取薪资
|
|
|
+
|
|
|
+- **API路径映射**(来自`allin-packages/salary-module/src/routes/salary-custom.routes.ts`):
|
|
|
+ - `POST /create` → `salaryClientManager.get().create.$post`
|
|
|
+ - `PUT /update/{id}` → `salaryClientManager.get().update[':id'].$put`
|
|
|
+ - `DELETE /delete/{id}` → `salaryClientManager.get().delete[':id'].$delete`
|
|
|
+ - `GET /` → `salaryClientManager.get().$get`(分页查询)
|
|
|
+ - `GET /{id}` → `salaryClientManager.get()[':id'].$get`
|
|
|
+ - `GET /getByProvinceCity` → `salaryClientManager.get().getByProvinceCity.$get`
|
|
|
+
|
|
|
+- **薪资数据字段**(来自`allin-packages/salary-module/src/schemas/salary.schema.ts`):
|
|
|
+ - `provinceId: number` - 省份ID
|
|
|
+ - `cityId: number` - 城市ID
|
|
|
+ - `districtId?: number` - 区县ID(可选)
|
|
|
+ - `basicSalary: number` - 基本工资
|
|
|
+ - `allowance?: number` - 津贴(可选)
|
|
|
+ - `insurance?: number` - 保险(可选)
|
|
|
+ - `housingFund?: number` - 公积金(可选)
|
|
|
+
|
|
|
+### 区域选择器集成方案
|
|
|
+- **组件使用**:导入`AreaSelect`组件从`@d8d/area-management-ui`
|
|
|
+- **三级联动**:使用`AreaSelect`组件内置的省份→城市→区县三级联动功能
|
|
|
+- **表单集成**:在薪资表单中集成区域选择器,替换原有的省份、城市、区县选择逻辑
|
|
|
+- **数据格式**:`AreaSelect`组件返回`{ provinceId?, cityId?, districtId? }`格式
|
|
|
+- **验证集成**:薪资Schema中的区域字段验证与`AreaSelect`组件集成
|
|
|
+
|
|
|
+### 数值计算和验证要求
|
|
|
+- **基本工资**:必须为正数,有最小值限制
|
|
|
+- **津贴、保险、公积金**:可选,但必须为正数
|
|
|
+- **总额计算**:前端计算显示总额(基本工资 + 津贴 - 保险 - 公积金)
|
|
|
+- **表单验证**:使用Zod Schema进行数值范围验证
|
|
|
+
|
|
|
+### Testing
|
|
|
+**测试标准**:
|
|
|
+- **测试框架**:Vitest + Testing Library
|
|
|
+- **测试位置**:
|
|
|
+ - 集成测试:`tests/integration/salary.integration.test.tsx`
|
|
|
+- **测试覆盖要求**:
|
|
|
+ - 完整CRUD流程测试
|
|
|
+ - 区域选择器集成测试
|
|
|
+ - 数值计算验证测试
|
|
|
+ - 表单验证测试
|
|
|
+ - 错误处理测试
|
|
|
+- **测试模式**:参考现有UI包的集成测试模式
|
|
|
+
|
|
|
+**测试策略**:
|
|
|
+- 使用`test`属性或`data-testid`进行元素定位
|
|
|
+- 模拟完整的用户交互流程
|
|
|
+- 验证区域选择器的三级联动功能
|
|
|
+- 测试数值计算和验证逻辑
|
|
|
+- 覆盖各种错误场景
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|--------|
|
|
|
+| 2025-12-03 | 1.0 | 初始创建故事008.004 | Scrum Master Bob |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+*This section is populated by the development agent during implementation*
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+*To be filled by dev agent*
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+*To be filled by dev agent*
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+*To be filled by dev agent*
|
|
|
+
|
|
|
+### File List
|
|
|
+*To be filled by dev agent*
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*Results from QA Agent QA review of the completed story implementation*
|