小程序迁移 静态页面完成!!!
This commit is contained in:
545
docs/miniprogram-dev/API-OUTPUT-SPEC.md
Normal file
545
docs/miniprogram-dev/API-OUTPUT-SPEC.md
Normal file
@@ -0,0 +1,545 @@
|
||||
# 小程序后端接口输出规范
|
||||
|
||||
> **文档编号**:DS-API-OUTPUT-001
|
||||
> **版本**:v1.0.0
|
||||
> **适用范围**:NeoZQYY 小程序所有后端接口(HTTP JSON 响应体)
|
||||
> **最后更新**:2026-03-18
|
||||
> **关联文档**:
|
||||
> - [DISPLAY-STANDARDS.md](./design-system/DISPLAY-STANDARDS.md) — 前端展示规范第 1~6 章
|
||||
> - [DISPLAY-STANDARDS-2.md](./design-system/DISPLAY-STANDARDS-2.md) — 第 7~9 章(截止日期 / 评分 / Mock)
|
||||
> - [DATETIME-DISPLAY-STANDARD.md](./design-system/DATETIME-DISPLAY-STANDARD.md) — 时间展示规范
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [总体约定](#1-总体约定)
|
||||
2. [响应体结构](#2-响应体结构)
|
||||
3. [字段类型规范(核心规则)](#3-字段类型规范核心规则)
|
||||
4. [各业务字段细则](#4-各业务字段细则)
|
||||
5. [枚举值规范](#5-枚举值规范)
|
||||
6. [分页规范](#6-分页规范)
|
||||
7. [接口端点命名规范](#7-接口端点命名规范)
|
||||
8. [各页面接口字段对照表](#8-各页面接口字段对照表)
|
||||
9. [禁止事项速查](#9-禁止事项速查)
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体约定
|
||||
|
||||
| 项目 | 规范 |
|
||||
|------|------|
|
||||
| 协议 | HTTPS REST JSON |
|
||||
| 编码 | UTF-8 |
|
||||
| Content-Type | `application/json` |
|
||||
| 时区 | **后端统一输出 UTC,前端负责本地化展示** |
|
||||
| 数值精度 | 金额为整数(元),课时为 0.5 步长浮点 |
|
||||
| 空值 | 字段不存在时输出 `null`,**不得省略字段** |
|
||||
| 布尔值 | `true` / `false`,不用 `0/1` |
|
||||
| 字符串编码格式 | 纯数据,**不含展示单位**(¥、h、%、笔等) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 响应体结构
|
||||
|
||||
### 2.1 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 失败响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 40001,
|
||||
"message": "参数错误:缺少 customerId",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 分页列表响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"list": [ ... ],
|
||||
"total": 32,
|
||||
"page": 1,
|
||||
"pageSize": 20,
|
||||
"hasMore": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 字段类型规范(核心规则)
|
||||
|
||||
> **核心原则:后端输出原始语义数值,前端负责格式化展示。**
|
||||
> 后端不拼接 `¥`、`h`、`%`、`笔` 等展示字符,也不做千分位格式化。
|
||||
|
||||
### 3.1 类型对照表
|
||||
|
||||
| 字段类型 | 后端输出类型 | 示例 | 前端处理函数 | 禁止输出 |
|
||||
|----------|-------------|------|-------------|----------|
|
||||
| **金额** | `number`(元,整数) | `12680` | `formatMoney()` | `"¥12,680"` `"12680.00"` |
|
||||
| **课时** | `number`(小时,0.5步长) | `2.5` | `formatHours()` | `"2.5h"` `"2h30min"` |
|
||||
| **计数** | `number`(整数) | `32` | `formatCount()` | `"32笔"` `"32次"` |
|
||||
| **百分比** | `number`(0~100,整数或1位小数) | `85.5` | `formatPercent()` | `"85.5%"` `"0.855"` |
|
||||
| **日期** | `string`(`YYYY-MM-DD`) | `"2026-03-18"` | `formatDeadline()` | `"2026/03/18"` `1742256000000` |
|
||||
| **时间戳** | `string`(ISO 8601,含时区) | `"2026-03-18T08:30:00+08:00"` | `formatRelativeTime()` | Unix 毫秒整数 |
|
||||
| **等级 key** | `string`(英文 key) | `"star"` | 查 `LEVEL_MAP` | `"星级"` `"gold"` |
|
||||
| **状态 key** | `string`(英文 key) | `"pending"` | 查枚举映射 | `"待处理"` |
|
||||
| **评分** | `number`(0~10,0.5步长) | `8.5` | `scoreToHalfStar()` | `"8.5分"` `4` (5分制) |
|
||||
| **布尔** | `boolean` | `true` | 直接使用 | `1` `"true"` |
|
||||
| **空值** | `null` | `null` | 展示 `--` | `""` `0`(有语义时除外) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 各业务字段细则
|
||||
|
||||
### 4.1 金额字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "balance": 2000, "income": 510, "salary": 12680 }
|
||||
|
||||
// 错误
|
||||
{ "balance": "¥2,000", "income": "¥510", "salary": "¥12,680" }
|
||||
```
|
||||
|
||||
- 统一以「元」为单位,**不含分**
|
||||
- 负数直接输出负整数:`-368`
|
||||
- 零值输出 `0`,不输出 `null`
|
||||
- 前端调用 `formatMoney(value)` 展示
|
||||
|
||||
### 4.2 课时字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "hours": 2.5, "hoursRaw": 3.0 }
|
||||
|
||||
// 错误
|
||||
{ "hours": "2.5h", "deduct": "(折0.5h)" }
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `hours` | `number` | 折算后实际计入课时(小时) |
|
||||
| `hoursRaw` | `number \| null` | 折算前原始小时数;无折算时输出 `null` |
|
||||
|
||||
- 前端仅在 `hoursRaw !== null && hoursRaw !== hours` 时展示折算备注
|
||||
- 步长为 0.5,如 `1.0`、`1.5`、`2.0`、`2.5`
|
||||
|
||||
### 4.3 计数字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "totalCount": 32, "serviceCount": 18 }
|
||||
|
||||
// 错误
|
||||
{ "totalCount": "32笔", "serviceCount": "18次" }
|
||||
```
|
||||
|
||||
- 前端调用 `formatCount(value, '笔')` 展示,单位由页面层决定
|
||||
|
||||
### 4.4 百分比字段
|
||||
|
||||
```json
|
||||
// 正确(进度/完成率)
|
||||
{ "filledPct": 85, "completionRate": 72.5 }
|
||||
|
||||
// 错误
|
||||
{ "filledPct": "85%", "completionRate": 0.725 }
|
||||
```
|
||||
|
||||
- 统一 0~100 整数或1位小数,**不用小数形式**
|
||||
- 允许超过 100(如完成率 120%)
|
||||
|
||||
### 4.5 日期与时间
|
||||
|
||||
| 场景 | 格式 | 示例 |
|
||||
|------|------|------|
|
||||
| 纯日期(截止日、生日等) | `YYYY-MM-DD` | `"2026-03-18"` |
|
||||
| 精确时间(备注时间、服务记录) | ISO 8601 含时区 | `"2026-03-18T08:30:00+08:00"` |
|
||||
| 时间区间(service timeRange) | 直接拼接字符串 | `"20:00-22:00"` |
|
||||
|
||||
- **禁止** 输出 Unix 毫秒时间戳整数
|
||||
- **禁止** 输出 `YYYY/MM/DD` 格式
|
||||
- 前端截止日期调用 `formatDeadline(date)` 语义化
|
||||
- 前端相对时间调用 `formatRelativeTime(iso)` 展示
|
||||
|
||||
### 4.6 评分字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "heartScore": 8.5, "noteScore": 7.0 }
|
||||
|
||||
// 错误
|
||||
{ "heartScore": 4, "noteScore": "7.5分" }
|
||||
```
|
||||
|
||||
- 统一使用 **0~10 分制**,0.5 步长
|
||||
- 0 表示「未评分」,前端展示 `--`
|
||||
- 前端调用 `scoreToHalfStar(score)` 转换为 0~5 星展示
|
||||
|
||||
### 4.7 等级字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "level": "star" }
|
||||
|
||||
// 错误
|
||||
{ "level": "星级" }
|
||||
```
|
||||
|
||||
| 后端 key | 前端展示 |
|
||||
|----------|----------|
|
||||
| `star` | 星级助教 |
|
||||
| `senior` | 高级助教 |
|
||||
| `middle` | 中级助教 |
|
||||
| `junior` | 初级助教 |
|
||||
|
||||
### 4.8 天数字段
|
||||
|
||||
```json
|
||||
// 正确
|
||||
{ "lastVisitDays": 23, "daysAbsent": 23 }
|
||||
|
||||
// 错误
|
||||
{ "lastVisitDays": "23天前", "daysAbsent": "23天" }
|
||||
```
|
||||
|
||||
- 统一输出整数天数,不含「天」「天前」等汉字
|
||||
- 前端拼接文案时自行添加单位
|
||||
|
||||
---
|
||||
|
||||
## 5. 枚举值规范
|
||||
|
||||
所有枚举字段统一使用英文下划线 key,前端维护映射表。
|
||||
|
||||
### 5.1 任务类型 `taskType`
|
||||
|
||||
| key | 展示文案 |
|
||||
|-----|----------|
|
||||
| `callback` | 回访 |
|
||||
| `priority_recall` | 优先召回 |
|
||||
| `high_priority` | 高优先召回 |
|
||||
| `relationship` | 关系构建 |
|
||||
|
||||
### 5.2 任务状态 `status`
|
||||
|
||||
| key | 展示文案 |
|
||||
|-----|----------|
|
||||
| `pending` | 待处理 |
|
||||
| `completed` | 已完成 |
|
||||
| `abandoned` | 已放弃 |
|
||||
|
||||
### 5.3 助教等级 `level`
|
||||
|
||||
| key | 展示文案 |
|
||||
|-----|----------|
|
||||
| `star` | 星级助教 |
|
||||
| `senior` | 高级助教 |
|
||||
| `middle` | 中级助教 |
|
||||
| `junior` | 初级助教 |
|
||||
|
||||
### 5.4 课程类型 `courseType`
|
||||
|
||||
| key | 展示文案 | 样式 key |
|
||||
|-----|----------|----------|
|
||||
| `basic` | 基础课 | `tag-basic` |
|
||||
| `vip` | 包厢课 | `tag-vip` |
|
||||
| `tip` | 打赏课 | `tag-tip` |
|
||||
| `recharge` | 充值 | `tag-recharge` |
|
||||
| `incentive` | 激励 | `tag-incentive` |
|
||||
|
||||
### 5.5 线索来源 `source`
|
||||
|
||||
| key | 展示文案 |
|
||||
|-----|----------|
|
||||
| `manual` | 助教手动录入 |
|
||||
| `ai_consumption` | 系统自动(消费分析) |
|
||||
| `ai_note` | 系统自动(备注分析) |
|
||||
|
||||
### 5.6 线索分类 `category`
|
||||
|
||||
| key | 展示文案 |
|
||||
|-----|----------|
|
||||
| `customer_basic` | 客户基础 |
|
||||
| `consumption` | 消费习惯 |
|
||||
| `play_pref` | 玩法偏好 |
|
||||
| `promo_pref` | 促销偏好 |
|
||||
| `social` | 社交偏好 |
|
||||
| `feedback` | 重要反馈 |
|
||||
|
||||
### 5.7 截止日期语义化(前端计算,非接口字段)
|
||||
|
||||
后端只输出 `deadline: "YYYY-MM-DD"`,前端调用 `formatDeadline()` 计算:
|
||||
|
||||
| diff | 展示文案 | 样式 |
|
||||
|------|----------|------|
|
||||
| < 0 | `逾期 N 天` | `danger`(红) |
|
||||
| = 0 | `今天到期` | `warning`(橙) |
|
||||
| 1~7 | `还剩 N 天` | `normal` |
|
||||
| > 7 | `MM-DD` | `muted`(灰) |
|
||||
| null | `--` | `muted` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 分页规范
|
||||
|
||||
```json
|
||||
{
|
||||
"list": [],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"pageSize": 20,
|
||||
"hasMore": true
|
||||
}
|
||||
```
|
||||
|
||||
- `page` 从 1 开始计数
|
||||
- `hasMore` 由后端根据 `total` 和当前 `page * pageSize` 计算
|
||||
- `total` 为全量数据总条数(不是当前页条数)
|
||||
|
||||
---
|
||||
|
||||
## 7. 接口端点命名规范
|
||||
|
||||
```
|
||||
GET /api/xcx/tasks 任务列表
|
||||
GET /api/xcx/tasks/:id 任务详情
|
||||
GET /api/xcx/tasks/:id/notes 任务备注列表
|
||||
POST /api/xcx/tasks/:id/notes 新增备注
|
||||
GET /api/xcx/tasks/:id/service-records 近期服务记录
|
||||
GET /api/xcx/coaches 助教看板列表
|
||||
GET /api/xcx/coaches/:id 助教详情
|
||||
GET /api/xcx/performance 绩效概览
|
||||
GET /api/xcx/performance/records 绩效记录列表(支持月份分页)
|
||||
GET /api/xcx/retention-clues/:customerId 维客线索
|
||||
```
|
||||
|
||||
- 资源名用复数小写连字符
|
||||
- 路径参数用 `:id`,不用查询参数代替
|
||||
- 月份筛选用 `?year=2026&month=2`
|
||||
|
||||
---
|
||||
|
||||
## 8. 各页面接口字段对照表
|
||||
|
||||
### 8.1 任务列表页 `GET /api/xcx/tasks`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "task-001",
|
||||
"customerName": "王先生",
|
||||
"taskType": "high_priority",
|
||||
"taskTypeLabel": "高优先召回",
|
||||
"deadline": "2026-03-20",
|
||||
"heartScore": 8.5,
|
||||
"isPinned": true,
|
||||
"hasNote": true,
|
||||
"status": "pending",
|
||||
"lastVisitDays": 23,
|
||||
"balance": 2000,
|
||||
"filledPct": 85,
|
||||
"aiSuggestion": "建议本周内回访,余额即将到期"
|
||||
}
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- `lastVisitDays`:integer,距上次到店天数,null 表示从未到店
|
||||
- `balance`:integer(元),余额;null 表示无储值
|
||||
- `filledPct`:integer(0~100),关系进度百分比
|
||||
- `deadline`:`YYYY-MM-DD`,前端调用 `formatDeadline()` 语义化
|
||||
- `aiSuggestion`:string,AI 摘要文案,后端生成,前端直接展示
|
||||
|
||||
### 8.2 任务详情页 `GET /api/xcx/tasks/:id`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "task-001",
|
||||
"customerName": "王先生",
|
||||
"taskType": "high_priority",
|
||||
"taskTypeLabel": "高优先召回",
|
||||
"status": "pending",
|
||||
"deadline": "2026-03-20",
|
||||
"heartScore": 8.5,
|
||||
"phone": "138****5678",
|
||||
"lastVisitDate": "2026-03-01",
|
||||
"lastSpendAmount": 380,
|
||||
"daysAbsent": 23,
|
||||
"callbackReason": "上次体验课后未续费,需跟进意向",
|
||||
"churnRisk": "high",
|
||||
"spendTrend": "down",
|
||||
"aiAnalysis": {
|
||||
"summary": "最近 3 个月每周均有 1-2 次课程互动",
|
||||
"suggestions": ["询问近期是否有空", "告知会员专属活动"]
|
||||
},
|
||||
"talkingPoints": ["王哥好久不见..."],
|
||||
"notes": [
|
||||
{
|
||||
"id": "note-001",
|
||||
"content": "已通过微信联系王先生...",
|
||||
"tagType": "customer",
|
||||
"tagLabel": "客户:王先生",
|
||||
"createdAt": "2026-03-10T16:30:00+08:00",
|
||||
"score": 8.5
|
||||
}
|
||||
],
|
||||
"serviceRecords": [
|
||||
{
|
||||
"table": "A12号台",
|
||||
"type": "基础课",
|
||||
"typeClass": "basic",
|
||||
"recordType": "course",
|
||||
"hours": 2.5,
|
||||
"hoursRaw": 3.0,
|
||||
"income": 200,
|
||||
"isEstimate": true,
|
||||
"drinks": "百威x2 红牛x1",
|
||||
"date": "2026-02-07T21:30:00+08:00"
|
||||
}
|
||||
],
|
||||
"serviceSummary": {
|
||||
"totalHours": 6.0,
|
||||
"totalIncome": 510,
|
||||
"avgIncome": 170
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- `phone`:后端已做脱敏处理(`138****5678`),或根据权限返回明文
|
||||
- `score`:0~10 分制,0 表示未评分
|
||||
- `serviceRecords.hours`、`hoursRaw`:number(小时),前端调用 `formatHours()`
|
||||
- `serviceRecords.income`、`serviceSummary.*`:integer(元),前端调用 `formatMoney()`
|
||||
- `isEstimate`:boolean,true 时前端展示「预估」标注
|
||||
|
||||
### 8.3 助教看板页 `GET /api/xcx/coaches`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "coach-001",
|
||||
"name": "小燕",
|
||||
"level": "star",
|
||||
"storeName": "朗朗桌球",
|
||||
"customerCount": 28,
|
||||
"monthHours": 86.0,
|
||||
"monthIncome": 18600,
|
||||
"svAmount": 5000,
|
||||
"filledPct": 92,
|
||||
"taskCount": 6,
|
||||
"urgentTaskCount": 2,
|
||||
"aiSuggestion": "本月表现优秀,建议重点跟进 2 位高风险流失客户"
|
||||
}
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- `level`:英文 key,前端查 `LEVEL_MAP` 展示中文
|
||||
- `monthHours`:number(小时),前端调用 `formatHours()`
|
||||
- `monthIncome`、`svAmount`:integer(元),前端调用 `formatMoney()`
|
||||
- `filledPct`:integer(0~100),前端调用 `formatPercent()` 或 `toProgressWidth()`
|
||||
- `customerCount`、`taskCount`、`urgentTaskCount`:integer,前端调用 `formatCount()`
|
||||
|
||||
### 8.4 绩效记录页 `GET /api/xcx/performance/records`
|
||||
|
||||
请求参数:`?year=2026&month=2&page=1&pageSize=20`
|
||||
|
||||
```json
|
||||
{
|
||||
"summary": {
|
||||
"totalCount": 32,
|
||||
"totalHours": 59.0,
|
||||
"totalIncome": 4720
|
||||
},
|
||||
"dateGroups": [
|
||||
{
|
||||
"date": "2026-02-07",
|
||||
"totalHours": 6.0,
|
||||
"totalIncome": 510,
|
||||
"records": [
|
||||
{
|
||||
"id": "r1",
|
||||
"customerName": "王先生",
|
||||
"timeRange": "20:00-22:00",
|
||||
"hours": 2.0,
|
||||
"hoursRaw": null,
|
||||
"courseType": "basic",
|
||||
"location": "3号台",
|
||||
"income": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hasMore": false,
|
||||
"page": 1,
|
||||
"pageSize": 20
|
||||
}
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- `date`:`YYYY-MM-DD`,前端格式化为「2月7日」
|
||||
- `summary.*`、`dateGroups.totalIncome`、`records.income`:integer(元)
|
||||
- `summary.totalHours`、`dateGroups.totalHours`、`records.hours`:number(小时)
|
||||
- `hoursRaw`:null 表示无折算,有值时前端展示折算备注
|
||||
- `courseType`:英文 key(`basic`/`vip`/`tip`/`recharge`/`incentive`)
|
||||
|
||||
### 8.5 备注接口 `GET /api/xcx/tasks/:id/notes`
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "note-001",
|
||||
"content": "已通过微信联系王先生...",
|
||||
"tagType": "customer",
|
||||
"tagLabel": "客户:王先生",
|
||||
"createdAt": "2026-03-10T16:30:00+08:00",
|
||||
"score": 8.5
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
- `tagType`:`customer` / `coach` / `system`
|
||||
- `score`:0 表示未评分,0.5 步长,前端调用 `scoreToHalfStar()` 转 5 星制
|
||||
- `createdAt`:ISO 8601,前端调用 `formatRelativeTime()` 展示相对时间
|
||||
|
||||
---
|
||||
|
||||
## 9. 禁止事项速查
|
||||
|
||||
| 禁止行为 | 正确做法 |
|
||||
|----------|----------|
|
||||
| 输出 `"¥12,680"` | 输出 `12680` |
|
||||
| 输出 `"2.5h"` | 输出 `2.5` |
|
||||
| 输出 `"32笔"` | 输出 `32` |
|
||||
| 输出 `"85%"` | 输出 `85` |
|
||||
| 输出 `"星级"` 作为等级 | 输出 `"star"` |
|
||||
| 输出 `"待处理"` 作为状态 | 输出 `"pending"` |
|
||||
| 省略值为 null 的字段 | 显式输出 `null` |
|
||||
| 用 `0` 代替 `null` 表示「无」 | 用 `null`(0 保留给有意义的零值) |
|
||||
| 输出 Unix 毫秒时间戳 | 输出 ISO 8601 字符串 |
|
||||
| 输出 `YYYY/MM/DD` 日期格式 | 输出 `YYYY-MM-DD` |
|
||||
| 后端做 `toLocaleString()` 格式化 | 后端输出原始数值,前端格式化 |
|
||||
| `hoursRaw` 输出 `"(折0.5h)"` | 输出 `3.0`(原始小时数) |
|
||||
|
||||
---
|
||||
|
||||
## 关联文档
|
||||
|
||||
- [DISPLAY-STANDARDS.md](./design-system/DISPLAY-STANDARDS.md) — 前端格式化规范
|
||||
- [DISPLAY-STANDARDS-2.md](./design-system/DISPLAY-STANDARDS-2.md) — 截止日期 / 评分 / Mock 规范
|
||||
- [DATETIME-DISPLAY-STANDARD.md](./design-system/DATETIME-DISPLAY-STANDARD.md) — 时间展示规范
|
||||
- `utils/money.ts` — `formatMoney` / `formatCount` / `formatPercent` / `toProgressWidth`
|
||||
- `utils/time.ts` — `formatHours` / `formatDeadline` / `formatRelativeTime`
|
||||
- `utils/rating.ts` — `scoreToHalfStar` / `isUnrated`
|
||||
- `utils/mock-data.ts` — Mock 数据(字段结构与接口保持一致)
|
||||
Reference in New Issue
Block a user