小程序迁移 静态页面完成!!!

This commit is contained in:
Neo
2026-03-18 05:14:35 +08:00
parent 72bb11b34f
commit 075caf067f
124 changed files with 10407 additions and 2738 deletions

View File

@@ -0,0 +1,292 @@
# 前端展示规范总表(小程序)
> **文档编号**DS-DISPLAY-001
> **版本**v1.0.0
> **适用范围**NeoZQYY 小程序所有前端页面
> **最后更新**2026-03-18
> **关联文档**[日期时间展示规范](./DATETIME-DISPLAY-STANDARD.md)
---
## 目录
1. [金额展示规范](#1-金额展示规范)
2. [课时与时长展示规范](#2-课时与时长展示规范)
3. [数字与计数展示规范](#3-数字与计数展示规范)
4. [空值与缺失值规范](#4-空值与缺失值规范)
5. [百分比展示规范](#5-百分比展示规范)
6. [等级文案规范](#6-等级文案规范)
7. [任务截止日期展示规范](#7-任务截止日期展示规范)
8. [评分与星级展示规范](#8-评分与星级展示规范)
9. [Mock 数据规范](#9-mock-数据规范)
---
## 1. 金额展示规范
### 1.1 规则总表
| 场景 | 格式 | 示例 |
|---|---|---|
| 正常金额 | `¥N,NNN`(千分位逗号,无小数) | `¥12,680` |
| 负数金额 | `-¥N,NNN`(负号在 ¥ 前) | `-¥368` |
| 零值 | `¥0` | `¥0` |
| 空值 / undefined | `--` | `--` |
| 大额金额 | 不简写,保留完整数字 | `¥120,000` |
### 1.2 禁止事项
- ❌ 禁止 `¥-368`(负号位置错误)
- ❌ 禁止 `¥0.00`(零值不保留小数)
- ❌ 禁止 `¥12万`(不做大额简写)
- ❌ 禁止 `toLocaleString()` 直接用于展示(各设备行为不一致)
- ❌ Mock 数据中金额字段统一为 `number` 类型,不含 `¥` 前缀,由格式化层统一添加
### 1.3 实现参考(`utils/money.ts`,待新建)
```typescript
export function formatMoney(value: number | null | undefined): string {
if (value === null || value === undefined) return '--'
if (value === 0) return '¥0'
const abs = Math.round(Math.abs(value))
const formatted = abs.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
return value < 0 ? `${formatted}` : `¥${formatted}`
}
```
### 1.4 当前涉及位置(待统一)
| 文件 | 问题 |
|---|---|
| `pages/task-list/task-list.ts` | `perf.customerBalance.toLocaleString()` 裸调 |
| `pages/performance-records/performance-records.ts` | Mock 字符串硬编码 `¥510``¥280` 等 |
| `pages/task-detail/task-detail.ts` | `serviceRecords.income` 硬编码 `¥200` 等 |
| `pages/board-coach/board-coach.ts` | `salary``svAmount` 硬编码 `¥12,680` 等 |
---
## 2. 课时与时长展示规范
### 2.1 规则总表
| 场景 | 格式 | 示例 |
|---|---|---|
| 整数小时 | `Nh` | `2h` |
| 非整数小时保留1位 | `N.Nh` | `2.5h` |
| 带折算备注 | `实际h折后 原始h` | `2.0h(折后 2.5h` |
| 零值 | `0h` | `0h` |
| 空值 | `--` | `--` |
### 2.2 实现参考(追加至 `utils/time.ts`
```typescript
export function formatHours(hours: number | null | undefined): string {
if (hours === null || hours === undefined) return '--'
if (hours === 0) return '0h'
return hours % 1 === 0 ? `${hours}h` : `${hours.toFixed(1)}h`
}
```
### 2.3 折算标注字段约定
- `hours`:折算后实际计入课时(`number`
- `hoursRaw`:折算前原始小时数(`number | undefined`
- 仅当 `hoursRaw` 存在且与 `hours` 不同时展示括号备注
- WXML 示例:`{{item.hours}}h{{item.hoursRaw ? '(折后 ' + item.hoursRaw + 'h' : ''}}`
### 2.4 当前使用折算标注的位置(待统一)
| 文件 | 当前写法 | 目标写法 |
|---|---|---|
| `pages/performance-records/performance-records.ts` r7 | `deduct: '(折0.5h)'` 字符串 | `hours: 2, hoursRaw: 2.5`number |
| `pages/performance-records/performance-records.ts` r16 | 同上 | 同上 |
| `pages/performance-records/performance-records.ts` r21 | 同上 | 同上 |
| `pages/performance-records/performance-records.ts` r27 | 同上 | 同上 |
| `pages/task-detail/task-detail.ts` serviceRecords r1 | `durationRaw: '3.0h'` 字符串 | 改为 `number` 类型 |
| `components/service-record-card` | `hours-raw` prop 字符串 | 对齐 `number` 类型后格式化 |
---
## 3. 数字与计数展示规范
### 3.1 规则总表
| 场景 | 规则 | 示例 |
|---|---|---|
| 计数类(笔/次/人) | Mock 只存 `number`,单位由前端模板拼接 | API 返回 `32`WXML 展示 `32笔` |
| 大数字(≥ 1000 | 千分位逗号 | `1,280` |
| 零值 | `--` | `--` |
| 空值 / undefined | `--` | `--` |
### 3.2 单位映射表
| 字段语义 | 单位 |
|---|---|
| 服务记录数 / 交易笔数 | `笔` |
| 到店次数 / 服务次数 | `次` |
| 客户数 / 人数 | `人` |
| 任务数 | `个` |
| 工龄 | `年` |
### 3.3 实现参考(追加至 `utils/money.ts`
```typescript
export function formatCount(
value: number | null | undefined,
unit: string
): string {
if (value === null || value === undefined || value === 0) return '--'
const n = value >= 1000
? value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
: String(value)
return `${n}${unit}`
}
```
### 3.4 当前涉及位置(待统一)
| 文件 | 问题 |
|---|---|
| `pages/performance-records/performance-records.ts` | `totalCount: '32笔'` 字符串硬编码单位 |
| `pages/customer-service-records/customer-service-records.ts` | `monthCount: '6次'` 字符串硬编码单位 |
| `pages/board-coach/board-coach.ts` | `svCustomerCount: '18'` 裸字符串无单位 |
---
## 4. 空值与缺失值规范
### 4.1 统一占位符:`--`
| 场景 | 处理方式 |
|---|---|
| 数值型字段缺失(金额/课时/评分) | 展示 `--` |
| 文本型字段缺失(名称/备注/标签) | 展示 `--` |
| 列表为空 | 空态组件 `<t-empty />`,不用 `--` |
| 图片加载失败 | 默认占位图,不用 `--` |
### 4.2 禁止事项
- ❌ 禁止向用户展示 `undefined``null``NaN`、空字符串
- ❌ 禁止使用 `暂无``无``N/A``-` 等其他占位符
- ❌ 禁止直接绑定可能为 `undefined` 的字段而不加兜底
### 4.3 WXS 兜底函数(追加至 `utils/format.wxs`
```javascript
function safe(val) {
if (val === undefined || val === null || val === '') return '--'
return val
}
// WXML 用法:{{fmt.safe(item.someField)}}
```
---
## 5. 百分比展示规范
### 5.1 规则总表
| 场景 | 格式 | 示例 |
|---|---|---|
| 展示文字 | 保留1位小数 + `%` | `58.3%``120.0%` |
| 进度条 CSS 宽度 | 保留1位小数截断至100防溢出 | `width:58.3%` |
| 超过100%的展示文字 | 正常展示,不截断 | `120.0%` |
| 零值 | `0%` | `0%` |
| 空值 | `--` | `--` |
### 5.2 实现参考(追加至 `utils/money.ts`
```typescript
export function formatPercent(value: number | null | undefined): string {
if (value === null || value === undefined) return '--'
if (value === 0) return '0%'
return `${value.toFixed(1)}%`
}
export function toProgressWidth(value: number): string {
return `${Math.min(100, Math.max(0, value)).toFixed(1)}%`
}
```
### 5.3 当前涉及位置(待统一)
| 文件 | 问题 |
|---|---|
| `pages/task-list/task-list.ts` | `filledPct` 计算用 `Math.round(*1000)/10`,精度逻辑分散 |
| `pages/task-list/task-list.wxml` | `width: {{perfData.tierProgress}}%` 无小数位 |
---
## 6. 等级文案规范
### 6.1 助教等级
**英文 Key 标准(单一数据源:`vi-colors.ts` `COACH_LEVEL_COLORS`**
| 英文 Key | 中文展示文案 |
|---|---|
| `junior` | 初级 |
| `middle` | 中级 |
| `senior` | 高级 |
| `star` | ⭐ 星级 |
**规范要求:**
- API / Mock 统一返回英文 key
- 所有组件、页面、常量统一使用英文 key中文文案只在渲染层转换
- `coach-level-tag` 组件的 `LEVEL_MAP` 改为英文 key当前为中文 key
**当前待统一的位置:**
| 文件 | 问题 |
|---|---|
| `components/coach-level-tag/coach-level-tag.ts` | `LEVEL_MAP` key 为中文,需改为英文 |
| `pages/board-coach/board-coach.ts` | `level: '星级'` 等直接使用中文字符串 |
| `pages/board-coach/board-coach.ts` `LEVEL_CLASS` | key 为中文,需改为英文 |
| `utils/mock-data.ts` | 助教相关 Mock `level` 字段使用中文 |
### 6.2 关系等级
**英文 Key 标准(单一数据源:`vi-colors.ts` `RELATIONSHIP_LEVELS`**
| 英文 Key | 中文展示文案 | 分数范围 |
|---|---|---|
| `excellent` | 很好 | `> 8.5` |
| `good` | 良好 | `6 ~ 8.5` |
| `normal` | 一般 | `3.5 ~ 6` |
| `poor` | 待发展 | `< 3.5` |
**规范要求:**
- `task-detail.ts` 中的 `updateRelationshipDisplay` 应调用 `vi-colors.ts``getRelationshipLevel()`,不得重复维护判断逻辑
- 中文文案统一从 `RELATIONSHIP_LEVELS[key].name` 读取
**当前待统一的位置:**
| 文件 | 问题 |
|---|---|
| `pages/task-detail/task-detail.ts` | `updateRelationshipDisplay` 内联等级判断逻辑,与 `vi-colors.ts` 重复 |
### 6.3 客户标签类别
**英文 Key 标准(`vi-colors.ts` `CUSTOMER_TAG_COLORS`**
| 英文 Key | 中文展示文案 |
|---|---|
| `basic_info` | 客户基础 |
| `consumption` | 消费习惯 |
| `play_pref` | 玩法偏好 |
| `promo_pref` | 促销偏好 |
| `social` | 社交关系 |
| `feedback` | 重要反馈 |
**规范要求:**
- `CUSTOMER_TAG_COLORS` 的 key 从中文改为英文
- Mock 数据中 `category` 字段统一使用英文 key
**当前待统一的位置:**
| 文件 | 问题 |
|---|---|
| `utils/vi-colors.ts` `CUSTOMER_TAG_COLORS` | key 为中文,需改为英文 |
| `utils/mock-data.ts` `mockRetentionClues` | `category` 字段已是英文,保持不变 |
> 第 79 章及附录见:[DISPLAY-STANDARDS-2.md](./DISPLAY-STANDARDS-2.md)