13-13-code-review-report.md 7.6 KB

Story 13.13 代码审查报告 - 订单统计字段显示修复

审查日期: 2026-01-15 审查类型: 对抗性代码审查 (ADVERSARIAL Senior Developer Code Review) 审查范围: Story 13.13 - 订单统计字段显示修复


审查发现的关键问题

问题 1: 后端路由结构不匹配 RPC 客户端类型 (CRITICAL)

文件: allin-packages/order-module/src/routes/order-custom.routes.ts

问题描述:

  • orderStatsRoute 定义为扁平路径 /company-orders/{id}/stats
  • Hono RPC 客户端期望嵌套路径结构 company-orders:idstats
  • 导致前端无法通过 enterpriseOrderClient['company-orders'][':id']['stats'] 访问统计接口

根本原因: Hono 的 RPC 客户端使用类型推断生成客户端结构,需要后端路由使用嵌套结构才能正确映射。

修复方案:

// 修复前:扁平路由
const orderStatsRoute = createRoute({
  path: '/company-orders/{id}/stats',  // 错误:扁平路径
  ...
});

// 修复后:嵌套路由结构
enterpriseOrderCustomRoutes
  .route('/company-orders',
    new OpenAPIHono<AuthContext>()
      .openapi({ ...companyOrdersRoute, path: '' }, async (c) => { ... })  // 列表
      .openapi(orderStatsRoute, async (c) => { ... })  // 统计 (path: '/:id/stats')
  )

修改的文件:

  • allin-packages/order-module/src/routes/order-custom.routes.ts (行 856-907, 1399-1487)

问题 2: 订单统计 API 未被调用 (CRITICAL)

文件: mini-ui-packages/yongren-order-management-ui/src/pages/OrderList/OrderList.tsx

问题描述: 通过 Playwright MCP 实际测试验证发现:

  • 企业小程序订单列表页面的所有统计字段显示为 0/0 0%
  • 网络请求监控显示没有调用 /company-orders/{id}/stats 接口
  • useOrderStats hook 静默失败,没有抛出错误

根本原因: 与问题 1 相关,由于路由结构不匹配,RPC 客户端无法正确访问统计接口。

修复方案: 修复后端路由结构(见问题 1)后,前端需要重新编译以获取更新后的类型定义。


问题 3: 前端使用默认值掩盖 API 失败 (MEDIUM)

文件: mini-ui-packages/yongren-order-management-ui/src/pages/OrderList/OrderList.tsx (行 65-67)

问题描述:

const checkinStats = statsData?.checkinStats || { current: 0, total: order.actualPeople, percentage: 0 }
const salaryVideoStats = statsData?.salaryVideoStats || { current: 0, total: order.actualPeople, percentage: 0 }
const taxVideoStats = statsData?.taxVideoStats || { current: 0, total: order.actualPeople, percentage: 0 }

当 API 调用失败时,前端会回退到默认值 { current: 0, total: order.actualPeople, percentage: 0 },这会掩盖 API 调用的真实问题。

建议改进:

// 添加错误处理和日志记录
const { data: statsData, isLoading: statsLoading, error: statsError } = useOrderStats(order.id);

if (statsError) {
  console.error(`获取订单 ${order.id} 统计数据失败:`, statsError);
}

// 区分加载状态、错误状态和无数据状态
const checkinStats = statsData?.checkinStats;
const showFallback = !statsLoading && !statsData;

问题 4: E2E 测试凭证不匹配 (MINOR)

文件: web/tests/e2e/specs/cross-platform/order-stats-fix.spec.ts (行 26-27)

问题描述:

const TEST_USER_PHONE = '13800001111'; // 错误的手机号
const TEST_USER_PASSWORD = process.env.TEST_ENTERPRISE_PASSWORD || 'password123';

测试使用的企业账号与实际测试环境不匹配。

修复方案:

const TEST_USER_PHONE = '13800138002'; // 修正为正确的手机号
const TEST_USER_PASSWORD = process.env.TEST_ENTERPRISE_PASSWORD || '123123';

后端代码质量分析

order.service.ts - getOrderStats 方法 (行 1206-1271)

发现的问题:

  1. 时区处理不明确:

    const monthStart = new Date(year, month - 1, 1);
    const monthEnd = new Date(year, month, 1);
    
    • JavaScript Date 对象使用本地时区
    • PostgreSQL related_time 字段存储的是 timestamp
    • 可能导致时区不匹配问题
  2. 查询逻辑正确但可优化:

    • 使用 DISTINCT asset.personId 统计去重人员数是正确的
    • 查询按 relatedTime 筛选本月数据逻辑正确
    • 建议添加时区转换以确保边界准确

测试覆盖率分析

单元测试

状态: 未发现单元测试覆盖 getOrderStats 方法

建议: 添加以下测试用例:

  1. 测试时区边界情况(月末最后一天)
  2. 测试无数据情况
  3. 测试部分数据情况(只有部分人员有资产)
  4. 测试跨月数据筛选

E2E 测试

文件: web/tests/e2e/specs/cross-platform/order-stats-fix.spec.ts

覆盖率: 适中

  • AC1: 修复硬编码问题 ✓ (但 API 验证不充分)
  • AC2: 本月打卡统计 ✓ (结构正确)
  • AC3: 工资视频统计 ✓ (结构正确)
  • AC4: 个税视频统计 ✓ (结构正确)

改进建议:

  1. 添加 API Mock 测试,验证 RPC 客户端调用正确性
  2. 添加错误场景测试(API 失败时的行为)
  3. 添加数据准确性测试(验证百分比计算)

修复后的路由结构

最终实现

// allin-packages/order-module/src/routes/order-custom.routes.ts

enterpriseOrderCustomRoutes
  .route('/company-orders',
    new OpenAPIHono<AuthContext>()
      // GET /company-orders - 企业订单列表
      .openapi({ ...companyOrdersRoute, path: '' }, async (c) => { ... })
      // GET /company-orders/:id/stats - 订单统计
      .openapi(orderStatsRoute, async (c) => { ... })
  )

路径映射:

  • enterpriseOrderClient['company-orders'].$get()/company-orders
  • enterpriseOrderClient['company-orders'][':id']['stats'].$get()/company-orders/:id/stats

修复后的代码文件清单

后端文件

  1. allin-packages/order-module/src/routes/order-custom.routes.ts
    • 修改 orderStatsRoute 路径从 /company-orders/{id}/stats/:id/stats
    • 创建嵌套路由结构,将 companyOrdersRouteorderStatsRoute 放在同一嵌套路由下
    • 修改行: 856-907 (路由定义), 1399-1487 (路由注册)

前端文件

  1. web/tests/e2e/specs/cross-platform/order-stats-fix.spec.ts
    • 修改测试凭证为正确的手机号和密码
    • 修改行: 26-27

验证步骤

  1. 重新编译后端代码

    cd /mnt/code/188-179-template-6
    pnpm build
    
  2. 重启开发服务器(如需要)

  3. 验证路由可用性

    curl -X GET 'http://localhost:8080/api/v1/yongren/order/company-orders/1/stats?year=2026&month=1' \
     -H 'Authorization: Bearer <token>'
    
  4. 运行 E2E 测试

    cd web
    timeout 60 pnpm test:e2e:chromium order-stats-fix
    
  5. 手动验证

    • 登录企业小程序 (13800138002 / 123123)
    • 导航到订单列表页
    • 检查网络请求,确认 /company-orders/:id/stats 被调用
    • 验证统计字段显示实际数据而非硬编码的 0

代码审查总结

严重程度分布

  • CRITICAL: 2 个 (路由结构不匹配、API 未被调用)
  • MEDIUM: 1 个 (默认值掩盖错误)
  • MINOR: 1 个 (测试凭证不匹配)

状态

  • ✅ 已修复: 路由结构问题
  • ✅ 已修复: E2E 测试凭证
  • ⚠️ 需要验证: 前端需要重新编译
  • 📝 建议改进: 前端错误处理、后端时区处理、单元测试覆盖

下一步行动

  1. 重新编译项目以应用类型定义更新
  2. 运行 E2E 测试验证修复效果
  3. 使用 Playwright MCP 手动验证订单统计字段显示
  4. 考虑添加单元测试覆盖 getOrderStats 方法