Files
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

69 lines
3.0 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 缺失项 #22详情页各模块的加载失败独立处理
## 简要结论
- 状态:✅ 已解决
- 风险等级:🟢 低
- 后端对每个扩展模块使用独立 try/except 优雅降级;前端 customer-service-records 也实现了模块级独立错误处理
## 详细审查
### 审查范围
- `apps/backend/app/services/customer_service.py``get_customer_detail()` 错误处理
- `apps/backend/app/services/coach_service.py``get_coach_detail()` 错误处理
- `apps/miniprogram/miniprogram/pages/customer-service-records/customer-service-records.ts` — 前端错误处理
### 发现
#### 后端 — customer_service.py
1. 核心字段member_info查询失败 → 直接抛 500/404
2. Banner 字段balance、consumption_60d、days_since_visit各自独立 try/except失败降级为 `None`
3. 扩展模块ai_insight、retention_clues、notes、consumption_records、coach_tasks、favorite_coaches各自独立 try/except失败降级为空默认值
4. 注释明确标注:"核心字段查询失败 → 500扩展模块查询失败 → 空默认值(优雅降级)"
#### 后端 — coach_service.py
1. 核心字段assistant_info查询失败 → 直接抛 500/404
2. 扩展模块income、tier_nodes、top_customers、service_records、task_groups、notes、history_months各自独立 try/except
3. 每个模块失败时 logger.warning 记录日志,降级为空默认值
#### 前端 — customer-service-records.ts
1. `loadCustomerInfo()` 失败不阻塞记录展示:`catch` 中仅 `console.error`,注释"客户信息加载失败不阻塞记录展示"
2. `loadMonthRecords()` 失败设置 `pageState: 'error'`,提供重试按钮
### 证据
```python
# customer_service.py — 每个模块独立 try/except
try:
ai_insight = _build_ai_insight(customer_id, conn)
except Exception:
logger.warning("构建 aiInsight 失败,降级为空", exc_info=True)
ai_insight = {"summary": "", "strategies": []}
try:
retention_clues = _build_retention_clues(customer_id, conn)
except Exception:
logger.warning("构建 retentionClues 失败,降级为空列表", exc_info=True)
retention_clues = []
```
```python
# coach_service.py — 同样的模式
try:
income = _build_income(conn, site_id, coach_id, now)
except Exception:
logger.warning("构建 income 失败,降级为空", exc_info=True)
income = {"this_month": [], "last_month": []}
```
```typescript
// customer-service-records.ts — 客户信息加载失败不阻塞
async loadCustomerInfo(id: string) {
try { ... } catch (err) {
console.error('[customer-service-records] loadCustomerInfo failed:', err)
// 客户信息加载失败不阻塞记录展示
}
}
```
### 建议
- 前端 customer-detail.ts 的 `loadDetail()` 目前是单一 try/catch所有数据在一个请求中获取。如果后端某个模块降级为空前端会正常展示空状态但如果整个 API 请求失败,所有模块都不可用。这是可接受的设计,因为核心数据和扩展数据在同一个 API 调用中返回。