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

48 lines
2.1 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 缺失项 #19客户详情页电话号码的脱敏展示
## 简要结论
- 状态:✅ 已解决
- 风险等级:🟢 低
- 后端已实现 `_mask_phone()` 脱敏函数(中间 4 位用 `****`),前端实现了"点击查看/复制"交互
## 详细审查
### 审查范围
- `apps/backend/app/services/customer_service.py``_mask_phone()` 函数、`get_customer_detail()` 返回
- `apps/miniprogram/miniprogram/pages/customer-detail/customer-detail.wxml` — 电话展示区域
- `apps/miniprogram/miniprogram/pages/customer-detail/customer-detail.ts` — 电话交互逻辑
- `apps/miniprogram/miniprogram/pages/customer-service-records/customer-service-records.ts` — 同样的脱敏逻辑
### 发现
1. 后端 `_mask_phone()` 实现:`phone[:3] + "****" + phone[-4:]`,如 `139****5678`
2. 后端 `get_customer_detail()` 同时返回 `phone`(脱敏)和 `phone_full`(完整),供前端按需展示
3. customer-detail 前端实现了 `phoneVisible` 状态切换:
- 默认显示脱敏号码 `138****5678`
- 点击"查看"按钮切换为完整号码
- 显示完整号码后按钮变为"复制",调用 `wx.setClipboardData`
4. customer-service-records 页面也实现了相同的脱敏+查看交互:
- 前端自行脱敏:`detail.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')`
- 同样有 `onTogglePhone()``onCopyPhone()` 方法
### 证据
```python
# customer_service.py
def _mask_phone(phone: str | None) -> str:
"""手机号脱敏139****5678 格式。"""
if not phone or len(phone) < 7:
return phone or ""
return f"{phone[:3]}****{phone[-4:]}"
```
```html
<!-- customer-detail.wxml -->
<text class="phone">{{phoneVisible ? detail.phone : '138****5678'}}</text>
<view class="phone-toggle-btn" bindtap="{{phoneVisible ? 'onCopyPhone' : 'onTogglePhone'}}">
<text class="phone-toggle-text">{{phoneVisible ? '复制' : '查看'}}</text>
</view>
```
### 建议
- customer-detail.wxml 中脱敏号码硬编码为 `138****5678`,应改为使用后端返回的 `phone` 字段(已脱敏)
- 建议统一脱敏策略:要么全部由后端脱敏,要么全部由前端脱敏,避免两端重复实现