Files
Neo-ZQYY/docs/prd/specs/P13-miniapp-fe-polish.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

245 lines
11 KiB
Markdown
Raw 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.
# P13小程序前端 — 联调补齐与格式统一 — miniapp-fe-polish
> 优先级P13依赖 P6~P9 前端页面 + P3 认证 + P4 核心业务 + 后端接口)
> 预估工作量:中
> 生成日期2026-03-20
---
## 背景
小程序前端页面已完成 H5 原型还原P6~P9但在 MOCK 数据排查中发现多处功能点未对接真实数据或逻辑缺失。本 SPEC 统一收敛这些遗漏项,确保每个页面在联调后数据展示完整、格式统一。
---
## 一、通用规则(跨页面)
### G1微信头像与用户信息
**现状**`fetchMe()` 接口已定义但返回空 mock`task-list` 声明了 `avatarUrl` 但未赋值;`performance`/`performance-records``avatarUrl` 字段。
**需求**
- 登录成功后,从后端获取用户信息(微信头像 URL、微信昵称、角色、门店名称
- 后端接口 `GET /api/xcx/me` 返回 `{ avatarUrl, nickName, role, storeName }`
- 头像来源:微信登录时由后端通过 `code2Session` + `getUserInfo` 获取并存储,前端不直接调用 `wx.getUserProfile`
- 所有含 banner 的页面task-list、performance、performance-records统一从全局用户信息读取 `avatarUrl`
**验收标准**
- AC-G1.1:三个 banner 页面展示微信头像,无头像时显示默认占位图
- AC-G1.2:用户昵称、角色、门店名称正确展示
### G2当月预估判断
**现状**WXML 硬编码"预估"文案TS 无当月判断逻辑。
**需求**
- 当查看的数据月份 = 当前自然月时,标题显示"我的预估收入",金额旁显示"预估"标签
- 当查看的数据月份 < 当前自然月时,标题显示"我的收入",无"预估"标签
- 判断逻辑:`isCurrentMonth = (year === nowYear && month === nowMonth)`
- 影响页面performance、performance-records、board-finance
**验收标准**
- AC-G2.1:本月数据显示"预估"标签,历史月份不显示
- AC-G2.2board-finance 本月时间筛选时,经营一览标题含"预估"字样
### G3绩效折算折前/折后)
**现状**`performance-records` 接口定义了 `hoursRaw`(折前)和 `hours`折后WXML 有条件展示逻辑,但 `totalHoursRawLabel` 始终为空。
**需求**
- "绩效折前"/"折前"指 DWS 层定义的绩效惩罚规则计算出的折算前课时
- 后端接口返回 `hours`(折后)和 `hoursRaw`(折前),当两者不同时前端展示"折前 Xh"
- 汇总统计同理:`totalHoursRaw``totalHours` 时展示"折前 Xh"
**验收标准**
- AC-G3.1:存在折算差异时,课时旁显示"折前 Xh"灰色小字
- AC-G3.2:无折算差异时不显示"折前"
### G4储值等级显示规则
**现状**`task-detail` 声明了 `storageLevel` 但无计算逻辑。
**需求**
- 根据客户储值余额balance计算等级文案
- `= 0` → "无"
- `< 200` → "少"
- `< 500` → "一般"
- `< 1500` → "多"
- `≥ 1500` → "非常多"
- 计算在前端完成(后端返回 balance 数值),工具函数放 `utils/storage-level.ts`
**验收标准**
- AC-G4.1task-detail 储值区域根据 balance 正确显示等级文案
- AC-G4.2balance 为 0 时显示"无"
---
## 二、各页面功能点
### P1task-list任务列表
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T1.1 | banner 头像 | `avatarUrl` 声明但未赋值 | 见 G1 |
| T1.2 | 比同期数据 | PerfData 有 `incomeTrend`/`incomeTrendDir`,但值为空 | 后端返回与上月同期的差值(数值,非百分比),如 `+¥1,200` / `-¥800`;前端展示数值 + ↑/↓ 箭头 |
| T1.3 | 放弃原因 | `abandonReason` 硬编码空字符串 | 从后端 task 对象的 `abandonReason` 字段获取,展示放弃时填写的备注文本 |
| T1.4 | 盖戳动画 | ✅ 已实现 | 确认:任何情况下页面加载后盖戳动画都会播放(当前仅 `tierCompleted` 时触发),需改为始终播放 |
**验收标准**
- AC-T1.2:比同期显示为数值差(如 `+¥1,200`),非百分比
- AC-T1.3:已放弃任务卡片展示放弃备注
- AC-T1.4:页面加载后盖戳动画始终播放,不依赖 `tierCompleted`
### P2performance绩效总览
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T2.1 | banner 头像 | 无 `avatarUrl` 字段 | 见 G1 |
| T2.2 | 预估/实际收入 | 硬编码"预估" | 见 G2 |
### P3performance-records绩效明细
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T3.1 | banner 头像 | 无 `avatarUrl` 字段 | 见 G1 |
| T3.2 | 预估/实际收入 | 硬编码"预估" | 见 G2 |
| T3.3 | 总笔数 | 前端 `records.length` 计算 | 后端接口返回 `totalCount` 字段,前端直接使用(分页场景下前端计数不准确) |
| T3.4 | 绩效折前 | 接口有字段但 label 始终为空 | 见 G3 |
### P4task-detail任务详情
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T4.1 | 手机号码 | `onCopyPhone``phone = ''` 硬编码 | 从 `this.data.detail` 获取客户手机号(后端 task 详情接口返回 `customerPhone` |
| T4.2 | 储值显示规则 | `storageLevel` 无计算逻辑 | 见 G4从 detail 的 balance 字段计算 |
| T4.3 | 行动建议 | 仅有"问问助手"跳转 chat | 后端 task 详情接口返回 `actionSuggestions: string[]`AI 生成的行动建议列表),前端在维客线索下方展示为卡片列表 |
| T4.4 | 备注打星 | ✅ 已实现 | star-rating 组件 + note-modal 爱心/台球双维度评分已完整 |
### P5customer-service-records客户服务记录
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T5.1 | 客户名称 | ✅ 已实现 | 从 fetchCustomerDetail 获取 |
| T5.2 | 本月服务次数 | 从 detail 取 `totalServiceCount`,类型断言 `as any` | 后端 `GET /api/xcx/customers/:id` 返回 `totalServiceCount` 字段,前端类型定义补齐 |
| T5.3 | 课程标签 | getTypeLabel 基于 includes 硬编码匹配 | 后端返回 `courseType` 枚举basic/vip/incentive/recharge/snooker/group前端直接映射不再 includes 猜测 |
### P6board-finance财务看板
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T6.1 | AI 智能洞察 | WXML 硬编码 3 行文案 | 后端接口返回 `aiInsights: Array<{ icon: string; text: string }>`,前端动态渲染 |
| T6.2 | 环比箭头 | ✅ 已实现 | compareEnabled 开关 + ↑/↓ 箭头 + 颜色区分 |
| T6.3 | 本月"预估" | 无预估标记 | 见 G2 |
### P7board-customer客户看板
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T7.1 | 爱心 icon | ✅ 已实现 | heart-icon 组件 + getHeartEmoji 映射 |
### P8customer-detail客户详情
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T8.1 | 电话 | ✅ 已实现 | onTogglePhone + onCopyPhone 完整 |
### P9board-coach助教看板
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T9.1 | 级别 Icon | ✅ 已实现 | coach-level-tag 组件 + LEVEL_CLASS 映射 |
### P10coach-detail助教详情
| 编号 | 功能点 | 现状 | 需求 |
|------|--------|------|------|
| T10.1 | 任务执行数量统计 | `taskStats` 硬编码 `{ recall: 24, callback: 14 }` | 后端接口返回 `taskStats: { recall: number; callback: number }`,前端从 API 获取 |
---
## 三、数据格式统一标准
### 已有格式化工具函数(但并没有进行全部调用)
| 类型 | TS 函数 | WXS 函数 | 格式示例 | 缺省值 |
|------|---------|----------|----------|--------|
| 金额 | `formatMoney(value)` | `money(value)` | ¥12,680 / -¥368 / ¥0 | -- |
| 计数 | `formatCount(value, unit)` | `count(value, unit)` | 18笔 / 3次 / 12人 | -- |
| 百分比 | `formatPercent(value)` | `percent(value)` | 12.5% / 0% | -- |
| 课时 | `formatHours(hours)` | `hours(value)` | 86h / 72.5h / 0h | -- |
| 相对时间 | `formatRelativeTime(value)` | — | 刚刚 / 3分钟前 / 2天前 / 03-10 | -- |
| 截止日期 | `formatDeadline(deadline)` | — | 逾期3天 / 今天到期 / 还剩5天 / 03-15 | -- |
| IM 时间 | `formatIMTime(value)` | — | 14:30 / 03-10 14:30 | (空字符串) |
| 爱心 | `getHeartEmoji(score)` | — | 💖 / 🧡 / 💛 / 💙 | 💙 |
| 星级 | `scoreToHalfStar(score)` | — | 4.5 / 3.0 | 0 |
| 空值兜底 | — | `safe(val)` | (原值) | -- |
### 需要补充的格式化
| 类型 | 建议函数名 | 格式示例 | 缺省值 | 说明 |
|------|-----------|----------|--------|------|
| 日期(短) | `formatDateShort(date)` | 3月15日 / 03-15 | -- | 用于服务记录、充值日期等 |
| 日期(完整) | `formatDateFull(date)` | 2026-03-15 | -- | 用于历史数据、导出 |
| 天数 | `formatDays(days)` | 3天 / 15天 | -- | 用于"N天前到店"、逾期天数 |
| 储值等级 | `formatStorageLevel(balance)` | 无/少/一般/多/非常多 | 无 | 见 G4 |
| 同比差值 | `formatTrendValue(value)` | +¥1,200 / -¥800 | -- | 用于"比同期"展示 |
### 接口端格式对齐原则
1. 后端返回原始数值number前端负责格式化展示
2. 金额单位统一为"元"(整数),前端加 ¥ 前缀和千分位
3. 课时单位统一为"小时"number前端加 h 后缀
4. 日期统一 ISO 8601 格式(`YYYY-MM-DDTHH:mm:ss`),前端按场景格式化
5. 百分比后端返回 0-100 的 number前端加 % 后缀
6. 所有 null/undefined/0 值,前端统一展示为 `--`(通过 format 函数兜底)
---
## 四、实施优先级
### 第一批(阻塞联调)
- G1 微信头像(影响 3 个页面 banner
- T1.3 放弃原因(后端字段直通)
- T4.1 手机号码(后端字段直通)
- T3.3 总笔数(后端字段直通)
- T10.1 任务执行统计(后端字段直通)
### 第二批(业务逻辑)
- G2 当月预估判断(纯前端逻辑)
- G3 绩效折算展示(前端条件渲染)
- G4 储值等级规则(前端计算)
- T1.2 比同期数据(需后端新增字段)
- T1.4 盖戳动画始终播放(前端逻辑调整)
- T5.3 课程标签枚举化(前后端对齐)
### 第三批(增强体验)
- T4.3 行动建议(需后端 AI 接口)
- T6.1 AI 智能洞察(需后端 AI 接口)
- 格式化工具函数补充
---
## 五、涉及文件清单
### 前端
- `apps/miniprogram/miniprogram/services/api.ts`
- `apps/miniprogram/miniprogram/utils/money.ts`
- `apps/miniprogram/miniprogram/utils/time.ts`
- `apps/miniprogram/miniprogram/utils/storage-level.ts`(新建)
- `apps/miniprogram/miniprogram/pages/task-list/task-list.ts`
- `apps/miniprogram/miniprogram/pages/performance/performance.ts`
- `apps/miniprogram/miniprogram/pages/performance-records/performance-records.ts`
- `apps/miniprogram/miniprogram/pages/task-detail/task-detail.ts`
- `apps/miniprogram/miniprogram/pages/customer-service-records/customer-service-records.ts`
- `apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts`
- `apps/miniprogram/miniprogram/pages/coach-detail/coach-detail.ts`
### 后端(接口变更)
- `GET /api/xcx/me` — 补充 avatarUrl 字段
- `GET /api/xcx/tasks` — performance 补充 `trendValue`(同比差值)
- `GET /api/xcx/tasks/:id` — 补充 `customerPhone``actionSuggestions`
- `GET /api/xcx/customers/:id` — 类型定义补充 `totalServiceCount`
- `GET /api/xcx/performance/records` — 补充 `totalCount``hoursRaw`
- `GET /api/xcx/coaches/:id` — 补充 `taskStats`
- `GET /api/xcx/board/finance` — 补充 `aiInsights``isEstimated`