# 前端展示规范总表（续）— 第 7～9 章及附录

> 本文件为 [DISPLAY-STANDARDS.md](./DISPLAY-STANDARDS.md) 的续篇。

---

## 7. 任务截止日期展示规范

### 7.1 规则总表

| 距今时间 | 展示格式 | 样式 |
|---|---|---|
| 今天到期（diff = 0） | `今天到期` | 橙色警示 |
| 未来 1 ～ 7 天 | `还剩 N 天` | 正常色 |
| 未来 > 7 天 | `MM-DD` | 灰色 |
| 已逾期（diff < 0） | `逾期 N 天` | 红色高亮 |
| 空值 | `--` | 灰色 |

### 7.2 计算规则

- 以自然日为单位，当天到期 diff = 0
- `diff = floor((deadline零点 - 今天零点) / 86400000)`
- 不受时分秒影响

### 7.3 实现参考（追加至 `utils/time.ts`）

```typescript
export function formatDeadline(deadline: string | null | undefined): {
  text: string
  style: 'normal' | 'warning' | 'danger' | 'muted'
} {
  if (!deadline) return { text: '--', style: 'muted' }
  const now = new Date()
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const target = new Date(deadline)
  const targetDay = new Date(target.getFullYear(), target.getMonth(), target.getDate())
  const diff = Math.round((targetDay.getTime() - today.getTime()) / 86400000)
  if (diff < 0) return { text: `逾期 ${Math.abs(diff)} 天`, style: 'danger' }
  if (diff === 0) return { text: '今天到期', style: 'warning' }
  if (diff <= 7) return { text: `还剩 ${diff} 天`, style: 'normal' }
  const m = String(target.getMonth() + 1).padStart(2, '0')
  const d = String(target.getDate()).padStart(2, '0')
  return { text: `${m}-${d}`, style: 'muted' }
}
```

### 7.4 当前涉及位置（待统一）

| 文件 | 问题 |
|---|---|
| `pages/task-list/task-list.wxml` | `deadline` 直接绑定展示，无语义化处理 |
| `utils/mock-data.ts` | `deadline: '2026-03-10'` 格式正确，无需改动 |

---

## 8. 评分与星级展示规范

### 8.1 分制约定

| 来源 | 分制 | 说明 |
|---|---|---|
| 后端 API / Mock | 0 ～ 10 分 | heartScore、备注 score 等均用 0-10 |
| UI 星级图标 | 0 ～ 5 星（支持半星） | 由 `scoreToStar()` 转换 |
| 手动打分 | 1 ～ 5（整星） | 用户手动点击打分 |

### 8.2 展示场景规则

| 场景 | 展示方式 |
|---|---|
| 任务卡片关系分 | 星级图标（半星精度） |
| 任务详情关系分 | 星级图标 + 原始分（如 `8.5`） |
| 备注满意度评分 | 星级图标（半星精度） |
| 关系等级文字 | 纯文字（从 `RELATIONSHIP_LEVELS` 读取） |
| 未评分（score 为 null/undefined/0） | 展示 `--` 替代星星 |

### 8.3 半星映射规则

后端给分四舍五入到最近 0.5 星：

```typescript
// 追加至 utils/rating.ts
export function scoreToHalfStar(score: number): number {
  return Math.round(score / 2 * 2) / 2
}
// score=7 → 3.5星；score=8 → 4星；score=9 → 4.5星

export function isUnrated(score: number | null | undefined): boolean {
  return score === null || score === undefined || score === 0
}
```

### 8.4 当前涉及位置（待统一）

| 文件 | 问题 |
|---|---|
| `pages/task-detail/task-detail.wxml` | `fmt.toFixed(detail.heartScore, 1)` 直接格式化，无语义 |
| `utils/mock-data.ts` mockNotes | `score: 7.5` 混用小数，需统一为 0.5 步长整数 |
| `components/star-rating` | 需确认 `score=0` 未评分态是否已处理 |

---

## 9. Mock 数据规范

### 9.1 目标

将各页面内联的 Mock 数据统一迁移至 `utils/mock-data.ts`，方便后端联调时统一替换。

### 9.2 字段类型规范

| 字段类型 | Mock 类型 | 说明 |
|---|---|---|
| 金额 | `number`（元，整数） | 不含 `¥` 前缀 |
| 课时 | `number`（小时，0.5步长） | 不含 `h` 后缀 |
| 计数 | `number` | 不含单位 |
| 时间戳 | ISO 8601 字符串 | 统一 UTC |
| 日期 | `YYYY-MM-DD` 字符串 | 纯日期 |
| 等级 | 英文 key | `junior/middle/senior/star` |
| 百分比 | `number`（0～100） | 不含 `%` 符号 |

### 9.3 各页面内联 Mock 待迁移清单

| 页面 | 内联 Mock 内容 | 迁移目标 |
|---|---|---|
| `pages/task-detail/task-detail.ts` | mockNotes、serviceRecords、talkingPoints、retentionClues | `mock-data.ts` |
| `pages/performance-records/performance-records.ts` | dateGroups（约30条） | `mock-data.ts` |
| `pages/board-coach/board-coach.ts` | MOCK_COACHES（6条） | `mock-data.ts` |
| `pages/task-list/task-list.ts` | buildPerfData() 业绩进度数据 | `mock-data.ts` |
| `pages/customer-service-records/customer-service-records.ts` | 记录转换逻辑 | `mock-data.ts` |

### 9.4 迁移原则

- 迁移后页面 `.ts` 只保留视图逻辑，不再包含业务数据定义
- 每个 Mock 数据对象须有注释标注对应的真实 API 端点（`// TODO: GET /api/xcx/...`）
- Mock 字段名与接口文档字段名保持一致，避免联调时大量重命名
- 金额、课时、计数字段统一为 `number` 类型（见 9.2）

---

## 附录：工具函数归属总表

| 函数 | 文件 | 状态 |
|---|---|---|
| `formatRelativeTime` | `utils/time.ts` | ✅ 已实现 |
| `formatDeadline` | `utils/time.ts` | 待新增 |
| `formatHours` | `utils/time.ts` | 待新增 |
| `formatMoney` | `utils/money.ts` | 待新建文件 |
| `formatCount` | `utils/money.ts` | 待新建文件 |
| `formatPercent` | `utils/money.ts` | 待新建文件 |
| `toProgressWidth` | `utils/money.ts` | 待新建文件 |
| `scoreToStar` | `utils/rating.ts` | ✅ 已实现 |
| `scoreToHalfStar` | `utils/rating.ts` | 待新增 |
| `isUnrated` | `utils/rating.ts` | 待新增 |
| `getRelationshipLevel` | `utils/vi-colors.ts` | ✅ 已实现 |
| `relativeTime` (WXS) | `utils/time.wxs` | ✅ 已实现 |
| `safe` (WXS) | `utils/format.wxs` | 待新增 |

---

## 关联文档

- [DISPLAY-STANDARDS.md](./DISPLAY-STANDARDS.md) — 第 1～6 章
- [DATETIME-DISPLAY-STANDARD.md](./DATETIME-DISPLAY-STANDARD.md)
- [VI-DESIGN-SYSTEM.md](./VI-DESIGN-SYSTEM.md)
- `utils/time.ts` — 时间 / 课时 / 截止日期格式化
- `utils/money.ts` — 金额 / 计数 / 百分比格式化（待新建）
- `utils/rating.ts` — 评分 / 星级转换
- `utils/vi-colors.ts` — 等级常量与颜色映射
- `utils/mock-data.ts` — 统一 Mock 数据源
