# 变更审计记录：任务列表近60天数据展示 + WXML 格式化改造

| 字段 | 值 |
|------|-----|
| 日期 | 2026-03-27 23:55:19 |
| Prompt-ID | P20260327-235519 |

## 操作摘要
用户反馈任务列表卡片"将最近到店改为到店"、小时数和金额为0时没有显示。本次变更涉及：
1. `xcx_tasks.py` Schema 新增 `expected_days`、`ideal_interval_days`、`recent60d_hours`、`recent60d_income`、`customer_phone`、`balance` 字段
2. `task_manager.py` 重构：合并 7 次独立 ETL 连接为 1 次 `batch_query_for_task_list`；新增 RS 范围排除逻辑（SQL 层面排除 relationship_building 任务）；`_build_performance_summary` 支持 `batch_data` 复用；新增 `@trace_service` 装饰器
3. `task-list.wxml` 全面改用 WXS `fmt.*` 格式化函数（safe/money/hours/days/count 等）；卡片新增近60天汇总行；新增逾期标签；新增"查看所有客户"入口；绩效卡片整体可点击

## 本次对话文件变更

### 新增文件
- `docs/audit/prompt_logs/prompt_log_20260327_235519.md`
- `docs/audit/session_logs/2026-03/27/21_df263214_235045/main_01_2d5794de.md`

## 改动注解

### `apps/backend/app/schemas/xcx_tasks.py`
- 变更类型：修改
- 原始原因：任务列表卡片需要展示更多维度数据（预期天数、近60天课时/收入），前端需要这些字段
- 思路分析：在 `TaskItem` 中新增 `expected_days`、`ideal_interval_days`、`recent60d_hours`、`recent60d_income` 四个可选字段；在 `TaskDetailResponse` 中新增 `customer_phone` 和 `balance`。Schema 与 Service 字段保持严格一致
- 修改结果：前端可通过 camelCase 读取新字段，零值时返回 0.0 而非 None，确保前端始终能显示数值

### `apps/backend/app/services/task_manager.py`
- 变更类型：修改
- 原始原因：(1) 性能优化——原 7 次独立 ETL 连接合并为 1 次批量查询；(2) 分页准确性——RS 范围外的 relationship_building 任务需在 SQL 层排除而非内存过滤；(3) 新增近60天汇总数据支持
- 思路分析：
  - 步骤 0 预加载 RS 排除列表，构建 `exclude_clause` 注入 COUNT 和分页 SQL（`NOT (task_type='relationship_building' AND member_id=ANY(%s))`）
  - 步骤 2-5 合并为 `fdw_queries.batch_query_for_task_list()` 单连接批量查询
  - `_build_performance_summary` 新增 `batch_data` 参数复用预查询数据
  - 各 service 方法添加 `@trace_service` 装饰器用于链路追踪
  - 维客线索 category→tag_color 映射改为 CSS 类名后缀（primary/success/error 等），不再用十六进制颜色
- 修改结果：ETL 连接数从 7 降至 1，分页 total 与实际展示一致，卡片新增 `expected_days` 和 `recent60d_*` 数据

### `apps/miniprogram/miniprogram/pages/task-list/task-list.wxml`
- 变更类型：修改
- 原始原因：(1) 文本展示需统一使用 WXS 格式化防止 undefined/null 显示；(2) 卡片需展示近60天课时和收入汇总；(3) 逾期标签需可视化
- 思路分析：
  - 引入 `<wxs src="../../utils/format.wxs" module="fmt" />`，所有文本输出改用 `fmt.safe()`/`fmt.money()`/`fmt.hours()`/`fmt.days()`/`fmt.count()` 等 WXS 函数
  - card-row-2 从"最近到店：X天前 · 余额：X"改为"到店：X前 · 储值 X · 近60天 Xh | ¥X"
  - 新增 `expected-tag--overdue` 逾期标签（仅对非 relationship_building/follow_up_visit 类型显示）
  - 绩效卡片 `perf-card` 整体添加 `bindtap="onPerformanceTap"`，移除内部重复绑定
  - 头像改为从全局用户信息读取，支持 fallback 默认图
  - 新增"查看我的所有客户"按钮入口
- 修改结果：所有文本安全格式化，零值正确显示，卡片信息密度提升

### 非高风险文件简要注解
- `docs/audit/session_logs/2026-02/*/` 及 `2026-03/*/`：session 日志索引批量更新（自动生成）
- `docs/audit/prompt_logs/prompt_log_20260327_235519.md`：本次 prompt 日志（自动生成）

## 合规检查

| 检查项 | 状态 |
|--------|------|
| 新增迁移 SQL | 无 |
| DDL 基线 | 不涉及 |
| BD 手册 | 不涉及（无 DB schema 变更） |
| OpenAPI Spec | ⚠️ 接口代码已变更但 OpenAPI spec 未同步（`api_changed=true`, `openapi_spec_stale=true`） |
| 文档同步 | ⚠️ `xcx_tasks.py` → `docs/contracts/openapi/backend-api.json` 待同步 |
| 文档同步 | ⚠️ `task_manager.py` → `apps/backend/docs/API-REFERENCE.md` + `apps/backend/README.md` 待同步 |

## 待办
- [ ] 重新导出 OpenAPI spec：`python scripts/ops/_export_openapi.py`
- [ ] 更新 `apps/backend/docs/API-REFERENCE.md` 中 TaskItem/TaskDetailResponse 字段说明
