Files
Neo-ZQYY/docs/audit/changes/2026-03-24__fix-tier-nodes-empty-progress-bar.md
Neo 14a12342b5 chore(audit): 补追 96 份未入仓审计孤本 — 覆盖 2026-02-26 ~ 2026-04-08
这些审计记录原本堆积在 docs/audit/changes/changes/ 嵌套误产物目录下(由开发机迁移
79d3c2e 前后的不明批量操作产生)。由于同期 .gitignore 屏蔽了 docs/audit/ 全目录,
它们从未入过 git 任何分支 history。删除即永久丢失。

按 docs/specs/audit-gap-recovery/tasks.md 阶段 1 执行,将全部 96 份 D 类孤本
(主目录无同名、git history 亦无记录)复制到 docs/audit/changes/ 主目录入仓。

涵盖主题: P1-P18 全栈集成 / 多模块累积变更 / ETL bug 修复 / 业务日切 /
   召回与任务引擎改造 / 租户管理与审批 / 董事会财务 / 客户与助教详情 /
   DDL 基线合并 / Kiro 到 Claude Code 迁移

阶段 2(B 类内容漂移 1 份)和阶段 4(嵌套目录删除)独立推进。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 06:35:42 +08:00

78 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 审计记录:修复小程序前端档位进度条无刻度 + bonus_money 计算
- 日期2026-03-24
- Prompt修复小程序前端没有档位进度 / 达XXX可得X元没有显示金额
- 类型Bug 修复
## 原始原因
用户反馈小程序任务列表页1) 绩效进度条没有档位刻度2) "达XXX即得X元"金额为 0。
## 直接原因
1. `tier_nodes` 断裂:`_parse_salary_row` 返回 `"tier_nodes": []` → 兜底变成 `[0]` → 前端 `maxHours=0`
2. `bonus_money` 断裂:之前取 `salary_calc.sprint_bonus`,但 SPRINT 奖金已于 2026-02-28 过期,当前月份值为 0
## 改动方案
1. `fdw_queries.py``batch_query_for_task_list` 增加第 8 步查询 `app.v_cfg_performance_tier`(含 `base_deduction`, `bonus_deduction_ratio``get_performance_tiers` 同步增加两列
2. `task_manager.py``_build_performance_summary` 中:
- `tier_nodes` 从配置表 `min_hours` 构建(如 `[0, 120, 150, 180, 210]`
- `next_tier_hours` 根据 `effective_hours` 找第一个 > total_hours 的档位
- `tier_completed` 当超过最高档时为 True
- `bonus_money` = 基础课节省 + 打赏课节省(见下方公式)
### bonus_money 公式(用户确认版)
```
基础课节省 = next_tier_min_hours × (当前档 base_deduction - 下一档 base_deduction)
打赏课节省 = 当前打赏课时(bonus_hours) × bonus_course_price × (当前档 bonus_deduction_ratio - 下一档 bonus_deduction_ratio)
bonus_money = 基础课节省 + 打赏课节省
```
示例80h 基础 + 20h 打赏T0→T1基础 `120×(28-18)=1200`,打赏 `20×190×(0.50-0.40)=380`,合计 1580 元。
- `bonus_course_price``salary_calc.incentive_rate` 读取(当前统一 190 元/小时),禁止硬编码
- `base_deduction` / `bonus_deduction_ratio``cfg_performance_tier` 配置表读取
## 文件清单
| 文件 | 变更 |
|------|------|
| `apps/backend/app/services/fdw_queries.py` | 查询增加 `base_deduction` + `bonus_deduction_ratio` 列,返回 `performance_tiers` |
| `apps/backend/app/services/task_manager.py` | 用配置表构建 tier_nodes用抽成差额基础+打赏)计算 bonus_money |
## 风险评估
- 低风险:仅影响前端展示数据,不涉及金额写入或工资计算
- `bonus_money` 计算公式已与用户确认(含基础课 + 打赏课两部分)
## 回滚策略
还原两个文件的修改即可。
## 验证 SQL
```sql
-- 1. 确认 cfg_performance_tier 有 base_deduction + bonus_deduction_ratio 数据
SELECT tier_code, min_hours, base_deduction, bonus_deduction_ratio
FROM dws.cfg_performance_tier
WHERE effective_from <= CURRENT_DATE AND effective_to >= CURRENT_DATE
ORDER BY tier_level;
-- 2. 确认 RLS 视图含两列
SET LOCAL app.current_site_id = '1';
SELECT tier_code, min_hours, base_deduction, bonus_deduction_ratio
FROM app.v_cfg_performance_tier
WHERE effective_from <= CURRENT_DATE AND effective_to >= CURRENT_DATE
ORDER BY tier_level;
-- 3. 模拟计算80h 基础 + 20h 打赏T0→T1
-- 基础课节省 = 120 × (28 - 18) = 1200
-- 打赏课节省 = 20 × 190 × (0.50 - 0.40) = 380
-- bonus_money = 1580
SELECT 120 * (28 - 18) AS base_saving,
20 * 190 * (0.50 - 0.40) AS bonus_saving,
120 * (28 - 18) + 20 * 190 * (0.50 - 0.40) AS total_bonus_money;
```