# 前端展示规范总表(小程序) > **文档编号**: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 统一占位符:`--` | 场景 | 处理方式 | |---|---| | 数值型字段缺失(金额/课时/评分) | 展示 `--` | | 文本型字段缺失(名称/备注/标签) | 展示 `--` | | 列表为空 | 空态组件 ``,不用 `--` | | 图片加载失败 | 默认占位图,不用 `--` | ### 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` 字段已是英文,保持不变 | > 第 7~9 章及附录见:[DISPLAY-STANDARDS-2.md](./DISPLAY-STANDARDS-2.md)