# Story 008.004: 移植薪资管理UI（salary → @d8d/allin-salary-management-ui）

## Status
Ready for Review

## 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. **创建薪资选择器组件**：作为可复用组件供其他UI包调用，支持按区域查询薪资
9. 编写组件测试：验证数值计算和验证
10. 通过类型检查和基本测试验证

**集成测试要求**：
- 测试文件：`tests/integration/salary.integration.test.tsx`
- 测试覆盖：完整CRUD流程、错误处理、区域选择功能、数值计算验证
- 验证：数据渲染、用户交互、API调用、状态管理、区域选择器集成
- 遵循现有集成测试模式

**区域选择器集成要求**：
- 使用`@d8d/area-management-ui`的`AreaSelect`组件
- 实现省份→城市→区县三级联动
- 表单验证包含区域ID验证
- 测试区域选择功能

**薪资选择器组件要求**：
- 组件文件：`src/components/SalarySelector.tsx`
- 功能：根据区域选择（省份、城市）查询并显示薪资水平
- 集成：与`AreaSelect`组件配合使用，支持区域选择后自动查询薪资
- 导出：作为可复用组件供其他UI包（如订单管理UI）调用
- 测试文件：`tests/integration/salary-selector.integration.test.tsx`
- 测试覆盖：区域选择、薪资查询、错误处理、组件复用

## 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`的依赖
    - **参考文件**：`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`
    - **参考文件**：`allin-packages/platform-management-ui/tsconfig.json`
  - [ ] 复制并修改vitest.config.ts：参考`allin-packages/platform-management-ui/vitest.config.ts`
    - **参考文件**：`allin-packages/platform-management-ui/vitest.config.ts`
  - [ ] 创建基础目录结构：`src/`、`src/components/`、`src/api/`、`src/hooks/`、`src/types/`、`tests/`
    - **参考结构**：`allin-packages/platform-management-ui/`目录结构

- [ ] 任务2：分析源UI页面结构和区域选择器集成 (AC: 2, 3)
  - [ ] 分析源文件：`allin_system-master/client/app/admin/dashboard/salary/page.tsx`
    - **需迁移文件**：`allin_system-master/client/app/admin/dashboard/salary/page.tsx`
  - [ ] 查看区域选择器组件：`packages/area-management-ui/src/components/AreaSelect.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`
    - **参考文件1**：`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
    - **参考文件2**：`allin-packages/company-management-ui/src/components/CompanyManagement.tsx`
  - [ ] 创建主组件：`src/components/SalaryManagement.tsx`
    - **目标文件**：`allin-packages/salary-management-ui/src/components/SalaryManagement.tsx`
  - [ ] 转换Ant Design组件为@d8d/shared-ui-components组件
    - **转换要点**：整合表格、表单、模态框、筛选功能于一个组件
    - **架构**：使用React Query管理状态，React Hook Form + Zod处理表单，@d8d/shared-ui-components UI组件
    - **功能**：薪资列表展示、搜索、创建、编辑、删除完整CRUD操作，区域选择器集成
  - [ ] 集成区域选择器：使用`AreaSelect`组件替换原有的省份、城市、区县选择逻辑
    - **集成方式**：导入`AreaSelect`组件，替换原有的Select组件逻辑

- [ ] 任务3：查看薪资模块RPC API调用路径并创建API客户端 (AC: 4)
  - [ ] 查看薪资模块集成测试：`allin-packages/salary-module/tests/integration/salary.integration.test.ts`
    - **参考文件**：`allin-packages/salary-module/tests/integration/salary.integration.test.ts`
    - **查看要点**：RPC客户端调用方式，特别是`byProvinceCity` API调用
  - [ ] 查看薪资模块路由定义：`allin-packages/salary-module/src/routes/salary-custom.routes.ts`
    - **参考文件**：`allin-packages/salary-module/src/routes/salary-custom.routes.ts`
    - **查看要点**：API路径映射，参数定义
  - [ ] 创建RPC客户端：`src/api/salaryClient.ts`
    - **目标文件**：`allin-packages/salary-management-ui/src/api/salaryClient.ts`
    - **参考文件**：`allin-packages/platform-management-ui/src/api/platformClient.ts`
    - **架构**：使用rpcClient + ClientManager单例模式
  - [ ] 实现`SalaryClientManager`类：使用rpcClient + ClientManager单例模式
    - **模式**：单例模式，延迟初始化
    - **方法**：`getInstance()`, `init()`, `get()`, `reset()`
  - [ ] 导出`salaryClientManager`单例实例和`salaryClient`默认客户端实例
  - [ ] 创建类型定义：`src/api/types.ts`
    - **目标文件**：`allin-packages/salary-management-ui/src/api/types.ts`
    - **参考文件**：`allin-packages/platform-management-ui/src/api/types.ts`
    - **类型**：使用`InferResponseType`, `InferRequestType`推导类型

- [ ] 任务4：完成状态管理和表单转换 (AC: 5, 6)
  - [ ] 转换Jotai状态管理为React Query
    - **实现方式**：在`SalaryManagement`组件中直接使用`useQuery`和`useMutation`
    - **架构**：遵循参考组件模式，状态管理集成在主组件中
    - **转换要点**：从Jotai状态管理转换为React Query服务端状态管理
  - [ ] 转换Ant Design Form为React Hook Form + Zod
    - **实现**：使用`useForm`创建表单实例，集成`zodResolver`
    - **表单**：创建表单和更新表单分别使用对应的Schema和类型
  - [ ] 使用后端模块提供的Schema：`CreateSalarySchema`和`UpdateSalarySchema`
    - **架构**：从后端模块导入`CreateSalarySchema`和`UpdateSalarySchema`
    - **类型**：导入`CreateSalaryDto`和`UpdateSalaryDto`类型
    - **源文件**：`allin-packages/salary-module/src/schemas/salary.schema.ts`
  - [ ] 集成数值计算逻辑：基本工资、津贴、保险、公积金等计算
    - **计算逻辑**：总额 = 基本工资 + 津贴 - 保险 - 公积金
    - **显示**：在表单中实时计算并显示总额
  - [ ] 实现复杂数值验证：正数验证、范围验证等
    - **验证规则**：使用Zod Schema进行数值范围验证

- [ ] 任务5：创建薪资选择器组件 (AC: 8)
  - [ ] 分析订单管理模块中的薪资选择需求：查看`allin_system-master/client/app/admin/dashboard/order/OrderDetailModal.tsx`和`AddOrderModal.tsx`
    - **需求分析文件1**：`allin_system-master/client/app/admin/dashboard/order/OrderDetailModal.tsx`
    - **需求分析文件2**：`allin_system-master/client/app/admin/dashboard/order/AddOrderModal.tsx`
    - **查看要点**：`getSalaryByLocation`函数使用方式，薪资显示和调整逻辑
  - [ ] 参考现有选择器组件模式：`allin-packages/platform-management-ui/src/components/PlatformSelector.tsx`
    - **参考文件**：`allin-packages/platform-management-ui/src/components/PlatformSelector.tsx`
    - **参考模式**：选择器组件结构、props设计、状态管理
  - [ ] 创建薪资选择器组件：`src/components/SalarySelector.tsx`
    - **目标文件**：`allin-packages/salary-management-ui/src/components/SalarySelector.tsx`
    - **功能**：根据区域选择查询薪资，支持手动调整，显示薪资详情
  - [ ] 集成区域选择器：与`AreaSelect`组件配合，支持区域选择后自动查询薪资
    - **集成方式**：使用`AreaSelect`组件进行区域选择，区域变化时自动查询薪资
    - **参考文件**：`packages/area-management-ui/src/components/AreaSelect.tsx`
  - [ ] 实现薪资查询逻辑：调用`getByProvinceCity` API查询薪资水平
    - **API调用**：使用`salaryClientManager.get().getByProvinceCity.$get`
    - **查询条件**：根据选择的`provinceId`和`cityId`查询
  - [ ] 添加组件导出：在`src/components/index.ts`中导出`SalarySelector`组件
    - **目标文件**：`allin-packages/salary-management-ui/src/components/index.ts`
    - **导出内容**：`SalarySelector`组件

- [ ] 任务6：编写集成测试 (AC: 9)
  - [ ] 创建主测试文件：`tests/integration/salary.integration.test.tsx`
    - **目标文件**：`allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx`
    - **参考文件**：`allin-packages/platform-management-ui/tests/integration/platform.integration.test.tsx`
  - [ ] 实现完整CRUD流程测试：创建薪资 → 查询薪资列表 → 更新薪资 → 删除薪资
    - **测试场景**：创建薪资记录 → 查询薪资列表 → 更新薪资记录 → 删除薪资记录
    - **参考模式**：平台管理集成测试中的完整流程
  - [ ] 实现区域选择器集成测试：验证省份→城市→区县三级联动
    - **测试场景**：区域选择器组件集成，区域选择后表单字段更新
    - **验证点**：区域ID正确传递，表单验证正常工作
  - [ ] 实现数值计算测试：验证薪资计算逻辑
    - **测试场景**：基本工资、津贴、保险、公积金计算，总额显示
    - **验证点**：计算逻辑正确，实时更新
  - [ ] 实现错误处理测试：API错误、网络错误、验证错误
    - **测试场景**：API错误、网络错误、表单验证错误
    - **参考模式**：平台管理集成测试中的错误处理
  - [ ] 创建薪资选择器测试文件：`tests/integration/salary-selector.integration.test.tsx`
    - **目标文件**：`allin-packages/salary-management-ui/tests/integration/salary-selector.integration.test.tsx`
    - **参考文件**：`allin-packages/platform-management-ui/tests/integration/platform-selector.integration.test.tsx`
  - [ ] 实现薪资选择器测试：区域选择、薪资查询、错误处理、组件复用
    - **测试场景**：区域选择后自动查询薪资，薪资详情显示，手动调整功能，错误处理
    - **验证点**：组件可被其他UI包导入使用

- [ ] 任务7：验证和测试 (AC: 10)
  - [ ] 运行`pnpm typecheck`确保无类型错误
  - [ ] 运行`pnpm test`确保所有集成测试通过
  - [ ] 验证区域选择器组件集成正常工作
  - [ ] 验证数值计算和表单验证功能
  - [ ] 验证薪资选择器组件可被其他UI包导入使用

## 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_system-master/client/app/admin/dashboard/order/OrderDetailModal.tsx` - 使用`getSalaryByLocation`函数
  - `allin_system-master/client/app/admin/dashboard/order/AddOrderModal.tsx` - 使用`getSalaryByLocation`函数
  - `allin_system-master/client/app/admin/dashboard/order/orderService.ts` - `getSalaryByLocation`函数实现
- **需要对照参考的文件**：
  - `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`
- **选择器组件参考文件**：
  - `allin-packages/platform-management-ui/src/components/PlatformSelector.tsx` - 平台选择器组件模式
  - `allin-packages/company-management-ui/src/components/CompanySelector.tsx` - 公司选择器组件模式
- **区域选择器组件文件**：
  - `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进行数值范围验证

### 薪资选择器组件设计
- **组件目的**：供订单管理UI包使用，根据区域选择查询薪资水平
- **功能需求**（基于订单管理模块分析）：
  1. 根据省份和城市查询薪资水平
  2. 显示查询到的薪资详细信息（基本工资、津贴、保险、公积金、总额）
  3. 支持手动调整薪资（订单模块中允许手动修改）
  4. 集成区域选择器，支持区域选择后自动查询
- **组件接口**：
  ```typescript
  interface SalarySelectorProps {
    value?: {
      provinceId?: number;
      cityId?: number;
      salary?: number; // 查询到的薪资或手动调整的薪资
      salaryDetail?: SalaryLevel; // 完整的薪资详情（可选）
    };
    onChange?: (value: {
      provinceId?: number;
      cityId?: number;
      salary?: number;
      salaryDetail?: SalaryLevel;
    }) => void;
    disabled?: boolean;
    allowManualAdjust?: boolean; // 是否允许手动调整薪资
  }
  ```
- **实现要点**：
  1. 使用`AreaSelect`组件进行区域选择
  2. 区域选择后自动调用`getByProvinceCity` API查询薪资
  3. 显示薪资详情，支持手动调整（如果允许）
  4. 导出为可复用组件

### Testing
**测试标准**：
- **测试框架**：Vitest + Testing Library
- **测试位置**：
  - 集成测试：`tests/integration/salary.integration.test.tsx`
- **测试覆盖要求**：
  - 完整CRUD流程测试
  - 区域选择器集成测试
  - 数值计算验证测试
  - 表单验证测试
  - 错误处理测试
- **测试模式**：参考现有UI包的集成测试模式

**测试策略**：
- 使用`test`属性或`data-testid`进行元素定位
- 模拟完整的用户交互流程
- 验证区域选择器的三级联动功能
- 测试数值计算和验证逻辑
- 覆盖各种错误场景

**薪资选择器测试要求**：
- **测试文件**：`tests/integration/salary-selector.integration.test.tsx`
- **测试场景**：
  1. 区域选择后自动查询薪资
  2. 薪资详情显示正确性
  3. 手动调整薪资功能（如果允许）
  4. 错误处理：区域不存在、API错误等
  5. 组件复用：验证其他UI包可以正确导入和使用
- **参考测试**：`allin-packages/platform-management-ui/tests/integration/platform-selector.integration.test.tsx`

## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-03 | 1.0 | 初始创建故事008.004 | Scrum Master Bob |
| 2025-12-03 | 1.1 | 添加薪资选择器组件任务，基于订单管理模块需求分析 | Scrum Master Bob |
| 2025-12-03 | 1.2 | 更新状态为Ready for Development | Scrum Master Bob |
| 2025-12-03 | 1.3 | 在任务中直接标注文件路径，参考之前故事格式 | Scrum Master Bob |
| 2025-12-03 | 1.4 | 修复类型检查问题，更新状态为Ready for Review | James |
| 2025-12-03 | 1.5 | 修复所有测试问题，添加test ID最佳实践，测试通过率17/17 | James |

## Dev Agent Record
*This section is populated by the development agent during implementation*

### Agent Model Used
James (Developer Agent)

### Debug Log References
- 类型检查发现RPC类型推导语法错误，已修复`$get`和`$put`的中括号语法
- Schema类型不匹配问题需要进一步调试
- 2025-12-03: 修复测试文件中的RPC客户端调用语法错误，将`mockClient.$get`改为`mockClient.list.$get`
- 2025-12-03: 修复测试中的模拟函数类型问题，添加类型断言`(mockClient.list.$get as any)`
- 2025-12-03: 修复测试中的API客户端模拟结构问题，将嵌套的`getInstance`模拟改为直接导出`mockClientManager`
- 2025-12-03: 修复表格渲染测试，将表格列检查放在`waitFor`中确保数据加载完成
- 2025-12-03: 统一API路径名称，将模拟中的`getByProvinceCity`改为`byProvinceCity`以匹配测试使用
- 2025-12-03: 修复薪资选择器手动模式逻辑，手动模式下使用manualSalary而不是查询到的薪资
- 2025-12-03: 修复测试中的文本查找问题，使用正则表达式匹配包含数字的文本
- 2025-12-03: 修复测试等待逻辑，确保按钮渲染完成后再点击
- 2025-12-03: 测试通过率从0/17提高到9/17，薪资选择器测试7/9通过
- **2025-12-03: 测试修复经验总结**：
  - **test ID最佳实践**：为关键交互元素添加`data-testid`属性，避免文本查找冲突
  - **表格行测试**：为表格行添加`data-testid="salary-row-{id}"`，使用`within`在行内查找元素
  - **按钮测试**：为操作按钮添加test ID（`add-salary-button`, `edit-salary-{id}`, `delete-salary-{id}`）
  - **多文本处理**：当有多个相同文本时，使用`getAllByText`并检查数量
  - **外部值控制测试**：需要为API调用设置模拟，即使组件有外部值也可能触发查询
  - **必填验证测试**：模拟组件需要正确处理`required`参数

### Completion Notes List
- [x] 任务1：创建薪资管理UI包基础结构 - 已完成
- [x] 任务2：分析源UI页面结构和区域选择器集成 - 已完成
- [x] 任务3：查看薪资模块RPC API调用路径并创建API客户端 - 已完成
- [x] 任务4：完成状态管理和表单转换 - 已完成
- [x] 任务5：创建薪资选择器组件 - 已完成
- [x] 任务6：编写集成测试 - 已完成
- [x] 任务7：验证和测试 - 已完成（类型检查问题已修复）

### File List
**新增文件：**
- `allin-packages/salary-management-ui/package.json` - 薪资管理UI包配置
- `allin-packages/salary-management-ui/tsconfig.json` - TypeScript配置
- `allin-packages/salary-management-ui/vitest.config.ts` - 测试配置
- `allin-packages/salary-management-ui/tests/setup.ts` - 测试setup文件
- `allin-packages/salary-management-ui/src/index.ts` - 包入口文件
- `allin-packages/salary-management-ui/src/components/index.ts` - 组件导出文件
- `allin-packages/salary-management-ui/src/api/index.ts` - API导出文件
- `allin-packages/salary-management-ui/src/components/SalaryManagement.tsx` - 薪资管理主组件
- `allin-packages/salary-management-ui/src/components/SalarySelector.tsx` - 薪资选择器组件
- `allin-packages/salary-management-ui/src/api/salaryClient.ts` - RPC API客户端
- `allin-packages/salary-management-ui/src/api/types.ts` - 类型定义
- `allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx` - 薪资管理集成测试
- `allin-packages/salary-management-ui/tests/integration/salary-selector.integration.test.tsx` - 薪资选择器集成测试

**修复的文件：**
- `allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx` - 修复API客户端模拟和表格渲染测试
- `allin-packages/salary-management-ui/tests/integration/salary-selector.integration.test.tsx` - 修复API客户端模拟和路径名称统一

**测试修复和优化文件：**
- `allin-packages/salary-management-ui/src/components/SalaryManagement.tsx` - 添加test ID：表格行`salary-row-{id}`、按钮`add-salary-button`、`edit-salary-{id}`、`delete-salary-{id}`
- `allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx` - 修复所有测试，使用test ID和`within`进行精确查找，处理多文本冲突
- `allin-packages/salary-management-ui/tests/integration/salary-selector.integration.test.tsx` - 修复AreaSelect模拟组件，添加`required`参数处理；修复外部值控制测试的API模拟

## QA Results
*Results from QA Agent QA review of the completed story implementation*