Browse Source

docs(story): 根据实际API实现修正故事011.005的API规范

- 移除虚构的通用版本和企业专用扩展API描述
- 更新为实际存在的6个分布统计接口:残疾类型分布、性别分布、年龄分布、户籍分布、在职状态分布、薪资分布
- 修正接口路径名称(添加-distribution后缀)
- 修正查询参数(仅支持companyId,无时间范围参数)
- 更新API客户端创建示例,反映mini-ui-packages架构
- 更新RPC类型推断实现示例,使用实际接口名称
- 更新组件中使用示例,使用正确的接口和类型
- 更新技术集成描述,反映实际实现状态

🤖 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 3 weeks ago
parent
commit
37a9101791
1 changed files with 148 additions and 11 deletions
  1. 148 11
      docs/stories/011.005.story.md

+ 148 - 11
docs/stories/011.005.story.md

@@ -24,7 +24,7 @@ Ready
   - [ ] 实现页面标题和筛选条件区域
   - [ ] 添加图表加载状态和错误提示
 - [ ] 任务2:实现残疾类型分布图表(AC:2)
-  - [ ] 集成数据统计API(史诗012提供)
+  - [ ] 集成数据统计API(@d8d/allin-statistics-module提供)
   - [ ] 实现饼图或环形图展示残疾类型分布
   - [ ] 添加图例和百分比显示
   - [ ] 支持图表点击交互(查看详情)
@@ -71,19 +71,144 @@ Ready
 - 011.004(订单管理):统计可能涉及订单数据,Navbar集成和页面结构规范
 
 ### API规范
-**数据统计API**(史诗012提供):
-- 残疾类型统计接口
-- 性别年龄统计接口
-- 地域分布统计接口
-- 时间趋势统计接口
+**数据统计API**(statistics模块):
+- **实现状态**:后端`@d8d/allin-statistics-module`已实现6个分布统计API,均为企业专用版本。前端`@d8d/yongren-statistics-ui`包目前只有占位符API客户端,需要按照故事实现完整的API客户端集成。
+- **架构说明**:按照史诗011的mini-ui-packages架构,API客户端在各UI包内创建。数据统计API客户端应在`@d8d/yongren-statistics-ui`包内创建,而非在`mini/src/api.ts`中统一注册。
+- **后端路由类型**:从`@d8d/allin-statistics-module`导入`statisticsRoutes`类型定义
+- **路径前缀**:`/api/v1/yongren/statistics`(企业专用版本,通过`enterpriseAuthMiddleware`中间件保护)
+- **主要接口**(6个分布统计接口,均为企业专用版本):
+  - `GET /disability-type-distribution` - 残疾类型分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选。如未提供,从认证用户的token中获取)
+  - `GET /gender-distribution` - 性别分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选)
+  - `GET /age-distribution` - 年龄分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选)
+  - `GET /household-distribution` - 户籍分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选)
+  - `GET /job-status-distribution` - 在职状态分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选)
+  - `GET /salary-distribution` - 薪资分布统计接口
+    - 查询参数:`companyId?`(企业ID,可选)
+- **安全要求**:所有API通过`enterpriseAuthMiddleware`中间件保护,自动验证企业用户权限,确保数据安全隔离。
 
-**企业统计API**(史诗012提供):
-- 企业维度数据统计接口
-- 实时数据更新接口
+**企业专用数据统计API客户端创建**:
+- **实现状态**:`@d8d/yongren-statistics-ui`包目前只有占位符API客户端,需要按照本故事实现完整的API客户端。
+- **架构模式**:参考`@d8d/yongren-order-management-ui`包的企业专用API客户端实现模式,在UI包内创建RPC客户端。
+- **客户端创建示例**:
+  ```typescript
+  // 文件:mini-ui-packages/yongren-statistics-ui/src/api/enterpriseStatisticsClient.ts
+  import type { statisticsRoutes } from '@d8d/allin-statistics-module';
+  import { rpcClient } from '@d8d/mini-shared-ui-components/utils/rpc/rpc-client';
+
+  // 注意:企业专用数据统计API通过enterpriseAuthMiddleware中间件保护,确保仅限企业用户访问
+  // **重要安全要求**:企业专用API自动验证JWT token中的`companyId`字段,确保数据隔离安全
+  // 路径前缀 /api/v1/yongren/statistics 在路由层配置
+  export const enterpriseStatisticsClient = rpcClient<typeof statisticsRoutes>('/api/v1/yongren/statistics');
+  ```
+- **路径前缀**:`/api/v1/yongren/statistics`(企业专用版本)
+- **主要接口**(6个分布统计接口,与后端实现保持一致):
+  - `GET /disability-type-distribution` - 残疾类型分布统计接口
+  - `GET /gender-distribution` - 性别分布统计接口
+  - `GET /age-distribution` - 年龄分布统计接口
+  - `GET /household-distribution` - 户籍分布统计接口
+  - `GET /job-status-distribution` - 在职状态分布统计接口
+  - `GET /salary-distribution` - 薪资分布统计接口
+- **使用示例**:
+  ```typescript
+  // 在数据统计UI包内使用
+  import { enterpriseStatisticsClient } from '../api/enterpriseStatisticsClient'
+
+  // 获取残疾类型分布统计
+  const disabilityStats = await enterpriseStatisticsClient['disability-type-distribution'].$get({
+    query: {
+      companyId: 1 // 可选,如未提供则从认证用户token中获取
+    }
+  })
+
+  // 获取性别分布统计
+  const genderStats = await enterpriseStatisticsClient['gender-distribution'].$get({
+    query: {
+      companyId: 1
+    }
+  })
+
+  // 获取年龄分布统计
+  const ageStats = await enterpriseStatisticsClient['age-distribution'].$get()
+
+  // 获取户籍分布统计
+  const householdStats = await enterpriseStatisticsClient['household-distribution'].$get()
+
+  // 获取在职状态分布统计
+  const jobStatusStats = await enterpriseStatisticsClient['job-status-distribution'].$get()
+
+  // 获取薪资分布统计
+  const salaryStats = await enterpriseStatisticsClient['salary-distribution'].$get()
+  ```
+
+**RPC类型推断实现**
+参考 `mini-ui-packages/yongren-order-management-ui/src/api/types.ts` 的实现模式,使用Hono的类型推导工具 `InferResponseType` 和 `InferRequestType` 从API客户端自动推导请求和响应类型,避免手动定义重复的自定义类型。
+
+**实现示例**:
+```typescript
+// 文件:mini-ui-packages/yongren-statistics-ui/src/api/types.ts
+import type { InferResponseType, InferRequestType } from 'hono/client';
+import { enterpriseStatisticsClient } from './enterpriseStatisticsClient';
+
+// 使用Hono类型推导 - 注意正确的属性访问语法
+export type DisabilityTypeDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['disability-type-distribution']['$get'], 200>;
+export type GenderDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['gender-distribution']['$get'], 200>;
+export type AgeDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['age-distribution']['$get'], 200>;
+export type HouseholdDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['household-distribution']['$get'], 200>;
+export type JobStatusDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['job-status-distribution']['$get'], 200>;
+export type SalaryDistributionResponse = InferResponseType<typeof enterpriseStatisticsClient['salary-distribution']['$get'], 200>;
+
+// 查询参数类型推导
+export type DisabilityTypeDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['disability-type-distribution']['$get']>['query'];
+export type GenderDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['gender-distribution']['$get']>['query'];
+export type AgeDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['age-distribution']['$get']>['query'];
+export type HouseholdDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['household-distribution']['$get']>['query'];
+export type JobStatusDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['job-status-distribution']['$get']>['query'];
+export type SalaryDistributionParams = InferRequestType<typeof enterpriseStatisticsClient['salary-distribution']['$get']>['query'];
+```
+
+**优势**:
+- 类型安全:自动与后端路由类型保持同步,确保编译时类型检查
+- 减少重复:避免手动定义重复的类型定义,消除代码冗余
+- 维护性:后端路由变更时,前端类型自动更新,减少维护成本
+- 一致性:确保请求/响应类型与API契约完全匹配
+- 消除不必要的类型断言:无需使用`as any`或`as DisabilityTypeDistributionResponse`等手动断言,TypeScript可自动推断API响应类型
+- 简化组件代码:组件中直接导入推导的类型,代码更简洁清晰
+
+**组件中使用示例**:
+```typescript
+import type { DisabilityTypeDistributionResponse, GenderDistributionResponse } from '../../api'
+
+// API响应自动推断类型,无需手动断言
+const response = await enterpriseStatisticsClient['disability-type-distribution'].$get({ query: { companyId: 1 } })
+const data = await response.json()  // TypeScript自动推断为DisabilityTypeDistributionResponse类型
+
+// 统计数据使用具体类型
+const transformedStats = (data.stats || []).map((item: DisabilityTypeDistributionResponse['stats'][0]) => {
+  // 类型安全的转换逻辑
+  return {
+    key: item.key,
+    value: item.value,
+    percentage: item.percentage
+  }
+})
+
+// 性别分布数据示例
+const genderResponse = await enterpriseStatisticsClient['gender-distribution'].$get()
+const genderData = await genderResponse.json()  // TypeScript自动推断为GenderDistributionResponse类型
+```
 
 **技术集成**:
-- 使用故事011.001集成的RPC客户端
-- API路径前缀:`api/v1/yongren`
+- **RPC客户端工具**:使用`@d8d/mini-shared-ui-components/utils/rpc/rpc-client`提供的RPC客户端工具,在UI包内创建企业专用API客户端
+- **企业专用API路径前缀**:`/api/v1/yongren/statistics`(数据统计模块专用前缀)
+- **架构模式**:按照史诗011的mini-ui-packages架构,每个UI包负责创建和管理自己的API客户端,实现模块化集成。数据统计API客户端在`@d8d/yongren-statistics-ui`包内创建
+- **类型安全**:从`@d8d/allin-statistics-module`导入`statisticsRoutes`路由类型定义,确保类型安全
+- **数据安全**:所有API通过`enterpriseAuthMiddleware`中间件保护,自动验证企业用户权限,仅返回当前企业关联数据
+- **认证集成**:所有API调用自动携带企业用户token(通过企业认证框架管理),自动从token中提取`companyId`进行数据过滤
 
 ### 组件规范
 **数据统计页设计规范**:
@@ -224,6 +349,7 @@ Ready
 | 2025-12-17 | 1.0 | 初始创建(数据统计故事) | Bob(Scrum Master) |
 | 2025-12-20 | 1.1 | 更新Navbar集成规范,添加页面层级结构,反映mini-ui-packages架构 | Claude Code |
 | 2025-12-22 | 1.2 | 更新故事状态为Ready,依赖故事011.001-011.004已完成 | Claude Code |
+| 2025-12-22 | 1.3 | 根据实际API实现修正API规范,移除虚构API描述,更新为6个实际分布统计接口 | Claude Code |
 ## 开发代理记录
 *此部分由开发代理在实施过程中填充*
 
@@ -235,5 +361,16 @@ Ready
 - 更新测试要求,添加页面结构测试场景
 - 统一所有用人小程序页面的Navbar集成标准
 
+**文档更新记录 (2025-12-22)**:
+- 根据实际API实现验证和修正API规范部分
+- 移除虚构的通用版本和企业专用扩展API描述
+- 更新为实际存在的6个分布统计接口:残疾类型分布、性别分布、年龄分布、户籍分布、在职状态分布、薪资分布
+- 修正接口路径名称(添加-distribution后缀)
+- 修正查询参数(仅支持companyId,无时间范围参数)
+- 更新API客户端创建示例,反映mini-ui-packages架构
+- 更新RPC类型推断实现示例,使用实际接口名称
+- 更新组件中使用示例,使用正确的接口和类型
+- 更新技术集成描述,反映实际实现状态
+
 ## QA结果
 *来自QA代理对已完成故事实施的QA审查结果*