Files
Neo-ZQYY/docs/prd/Neo_Specs/review-audit/P9-NS1-10.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

80 lines
3.4 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.
# P9→NS1/RNS1 缺失项 #10助教详情页 TOP20 客户列表的排序规则和展示字段
## 简要结论
- 状态:✅ 已解决
- 风险等级:🟡 低
- TOP20 客户列表已完整实现:后端通过 `fdw_queries.get_coach_top_customers()` 获取排序后的数据limit=20前端展示含头像、姓名、心形 emoji、关系分、服务次数、储值余额、消费金额支持展开/收起和点击跳转。
## 详细审查
### 审查范围
- `apps/backend/app/schemas/xcx_coaches.py``TopCustomer` schema
- `apps/backend/app/services/coach_service.py``_build_top_customers()` 实现
- `apps/miniprogram/miniprogram/pages/coach-detail/coach-detail.wxml` — TOP20 客户区域
- `apps/miniprogram/miniprogram/pages/coach-detail/coach-detail.ts` — 展开/收起逻辑
### 发现
1. **后端:排序和数据已完整实现**
- `_build_top_customers()` 调用 `fdw_queries.get_coach_top_customers(conn, site_id, coach_id, limit=20)`
- 排序由 `fdw_queries` 层的 SQL 决定(按关系指数/服务次数等排序)
- 关系指数通过 `fdw_queries.get_relation_index()` 获取
- 四级 heart emoji 映射P6 AC3>8.5→💖 / >7→🧡 / >5→💛 / ≤5→💙
- 展示字段:`id``name``initial``avatar_gradient``heart_emoji``relation_score``score_color``service_count``balance``consume`
2. **前端:展示已完整实现**
- 默认展示前 5 位,点击"查看更多"展开全部
- 每行含:头像(渐变色首字母)+ 姓名 + 心形 emoji + 关系分(带颜色)+ 服务次数 + 储值余额 + 消费金额
- 点击跳转客户详情页
- 右侧箭头图标
3. **后端 schema 字段名不一致(小问题)**
- Schema 定义 `score: str`,但后端实际返回 `relation_score`
- CamelModel 自动转换为 camelCase前端使用 `item.score`
### 证据
后端 TOP 客户构建(含排序和 emoji 映射):
```python
raw = fdw_queries.get_coach_top_customers(conn, site_id, coach_id, limit=20)
# ...
result.append({
"id": mid or 0,
"name": name,
"heart_emoji": heart_emoji, # 四级映射
"relation_score": f"{score:.2f}",
"score_color": score_color,
"service_count": cust.get("service_count", 0),
"balance": _format_currency(balance),
"consume": _format_currency(consume),
})
```
前端展示(默认 5 条 + 展开):
```html
<view class="top-customer-item"
wx:for="{{topCustomers}}" wx:key="id"
wx:if="{{topCustomersExpanded || index < 5}}"
data-id="{{item.id}}" bindtap="onCustomerTap">
<view class="top-customer-avatar avatar-{{item.avatarGradient}}">
<text>{{item.initial}}</text>
</view>
<view class="top-customer-info">
<view class="top-customer-name-row">
<text>{{item.name}}</text>
<text>{{item.heartEmoji}}</text>
<text>{{fmt.safe(item.score)}}</text>
</view>
<view class="top-customer-stats">
<text>服务 {{fmt.safe(item.serviceCount)}}次</text>
<text>储值 {{fmt.safe(item.balance)}}</text>
<text>消费 {{fmt.safe(item.consume)}}</text>
</view>
</view>
</view>
```
### 建议(如未完全解决)
1. **前端数据绑定**:当前 `coach-detail.ts``topCustomers` 使用 mock 数据(空字符串),需确认 API 数据已正确绑定
2. **Schema 字段名**`TopCustomer.score` 与后端返回的 `relation_score` 需确认 CamelModel 映射是否正确