Files
VolunteerManage-for-byw/client
Trae Assistant 52c6ef2362
Deploy to Server / deploy (push) Successful in 1m46s
fix: 统一所有累计时长计算口径(必须 JOIN 到有效 activities)
- 统一口径定义:所有累计/总/人均/合计时长度量,一律只
  计算 hours 行中 activity_id 存在于 activities 表中的记录
  (排除 FK pragma 关闭时写入导致的幽灵 hours 行)

- server/users.ts:
  · GET /(用户列表列的累计时长)
    原 SELECT SUM(h.hours) FROM hours h → 增加 EXISTS 子查询
    『AND EXISTS (SELECT 1 FROM activities a WHERE a.id=h.activity_id)』
  · GET /:id 详情卡 total_hours_raw(给 enrichUser 用的原始数)
    同样加 EXISTS 校验,然后仍用详情 activities 列表 reduce 覆
    盖,保证卡片累计 = 列表合计 100% 一致,且与列表 SQL 同口径

- server/export.ts:
  · export include_user_totals(导出报告的部员累计时长排行)
    原 LEFT JOIN hours 直接 SUM → 改为 LEFT JOIN 预聚合子查
    询 vh,vh 内先按 EXISTS(activities) 过滤,再 SUM/COUNT
  · export include_activity_matrix(矩阵 _total、预览 KPI、
    导出 Excel 的总时长列)
    hoursRows 全表 SELECT → 增加 WHERE EXISTS(activities) 过
    滤,matrix/remarkMatrix 只聚合有效活动行,再派生的用户级
    _total 自然与 user_totals 同口径

- client/Export.tsx overviewCalc(导出报告顶部的累计总时长/
  人均时长 KPI 卡片,之前只依赖 preview.hours.reduce):
  · 优先级:
    ① 有 user_totals → 用后端同口径返回的 u.total_hours 聚合
      (最靠谱)
    ② 否则有 activity_matrix → 用 matrix.user._total 聚合
      (两者都基于同一 valid_hours 过滤)
    ③ Fallback:preview.hours.reduce(仅在只勾了明细单且没
      勾排行/矩阵时才用)
  · 计算完 totalHours 再 toFixed(1) 去浮点数误差,avgHours
    同步 toFixed(1)

- client/user/Dashboard.tsx(部员侧义工号查询的个人累计页):
  · 累计义工时长卡下半部新增『明细表合计』实时校验行:
    data.activities.reduce 求和直接显示在卡片上,与大号累计
    值左右对照,一眼确认有没有不一致
2026-10-05 14:29:07 +08:00
..