Files
Neo-ZQYY/docs/miniprogram-dev/API-OUTPUT-SPEC.md

15 KiB
Raw Blame History

小程序后端接口输出规范

文档编号DS-API-OUTPUT-001
版本v1.0.0
适用范围NeoZQYY 小程序所有后端接口HTTP JSON 响应体)
最后更新2026-03-18
关联文档


目录

  1. 总体约定
  2. 响应体结构
  3. 字段类型规范(核心规则)
  4. 各业务字段细则
  5. 枚举值规范
  6. 分页规范
  7. 接口端点命名规范
  8. 各页面接口字段对照表
  9. 禁止事项速查

1. 总体约定

项目 规范
协议 HTTPS REST JSON
编码 UTF-8
Content-Type application/json
时区 后端统一输出 UTC前端负责本地化展示
数值精度 金额为整数(元),课时为 0.5 步长浮点
空值 字段不存在时输出 null不得省略字段
布尔值 true / false,不用 0/1
字符串编码格式 纯数据,不含展示单位¥、h、%、笔等)

2. 响应体结构

2.1 成功响应

{
  "code": 0,
  "message": "success",
  "data": { ... }
}

2.2 失败响应

{
  "code": 40001,
  "message": "参数错误:缺少 customerId",
  "data": null
}

2.3 分页列表响应

{
  "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次"
百分比 number0100整数或1位小数 85.5 formatPercent() "85.5%" "0.855"
日期 stringYYYY-MM-DD "2026-03-18" formatDeadline() "2026/03/18" 1742256000000
时间戳 stringISO 8601含时区 "2026-03-18T08:30:00+08:00" formatRelativeTime() Unix 毫秒整数
等级 key string(英文 key "star" LEVEL_MAP "星级" "gold"
状态 key string(英文 key "pending" 查枚举映射 "待处理"
评分 number0100.5步长) 8.5 scoreToHalfStar() "8.5分" 4 (5分制)
布尔 boolean true 直接使用 1 "true"
空值 null null 展示 -- "" 0(有语义时除外)

4. 各业务字段细则

4.1 金额字段

// 正确
{ "balance": 2000, "income": 510, "salary": 12680 }

// 错误
{ "balance": "¥2,000", "income": "¥510", "salary": "¥12,680" }
  • 统一以「元」为单位,不含分
  • 负数直接输出负整数:-368
  • 零值输出 0,不输出 null
  • 前端调用 formatMoney(value) 展示

4.2 课时字段

// 正确
{ "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.01.52.02.5

4.3 计数字段

// 正确
{ "totalCount": 32, "serviceCount": 18 }

// 错误
{ "totalCount": "32笔", "serviceCount": "18次" }
  • 前端调用 formatCount(value, '笔') 展示,单位由页面层决定

4.4 百分比字段

// 正确(进度/完成率)
{ "filledPct": 85, "completionRate": 72.5 }

// 错误
{ "filledPct": "85%", "completionRate": 0.725 }
  • 统一 0100 整数或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 评分字段

// 正确
{ "heartScore": 8.5, "noteScore": 7.0 }

// 错误
{ "heartScore": 4, "noteScore": "7.5分" }
  • 统一使用 010 分制0.5 步长
  • 0 表示「未评分」,前端展示 --
  • 前端调用 scoreToHalfStar(score) 转换为 05 星展示

4.7 等级字段

// 正确
{ "level": "star" }

// 错误
{ "level": "星级" }
后端 key 前端展示
star 星级助教
senior 高级助教
middle 中级助教
junior 初级助教

4.8 天数字段

// 正确
{ "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(橙)
17 还剩 N 天 normal
> 7 MM-DD muted(灰)
null -- muted

6. 分页规范

{
  "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

{
  "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": "建议本周内回访,余额即将到期"
}

说明:

  • lastVisitDaysinteger距上次到店天数null 表示从未到店
  • balanceinteger余额null 表示无储值
  • filledPctinteger0100关系进度百分比
  • deadlineYYYY-MM-DD,前端调用 formatDeadline() 语义化
  • aiSuggestionstringAI 摘要文案,后端生成,前端直接展示

8.2 任务详情页 GET /api/xcx/tasks/:id

{
  "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),或根据权限返回明文
  • score010 分制0 表示未评分
  • serviceRecords.hourshoursRawnumber小时前端调用 formatHours()
  • serviceRecords.incomeserviceSummary.*integer前端调用 formatMoney()
  • isEstimatebooleantrue 时前端展示「预估」标注

8.3 助教看板页 GET /api/xcx/coaches

{
  "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 展示中文
  • monthHoursnumber小时前端调用 formatHours()
  • monthIncomesvAmountinteger前端调用 formatMoney()
  • filledPctinteger0100前端调用 formatPercent()toProgressWidth()
  • customerCounttaskCounturgentTaskCountinteger前端调用 formatCount()

8.4 绩效记录页 GET /api/xcx/performance/records

请求参数:?year=2026&month=2&page=1&pageSize=20

{
  "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
}

说明:

  • dateYYYY-MM-DD前端格式化为「2月7日」
  • summary.*dateGroups.totalIncomerecords.incomeinteger
  • summary.totalHoursdateGroups.totalHoursrecords.hoursnumber小时
  • hoursRawnull 表示无折算,有值时前端展示折算备注
  • courseType:英文 keybasic/vip/tip/recharge/incentive

8.5 备注接口 GET /api/xcx/tasks/:id/notes

[
  {
    "id": "note-001",
    "content": "已通过微信联系王先生...",
    "tagType": "customer",
    "tagLabel": "客户:王先生",
    "createdAt": "2026-03-10T16:30:00+08:00",
    "score": 8.5
  }
]
  • tagTypecustomer / coach / system
  • score0 表示未评分0.5 步长,前端调用 scoreToHalfStar() 转 5 星制
  • createdAtISO 8601前端调用 formatRelativeTime() 展示相对时间

9. 禁止事项速查

禁止行为 正确做法
输出 "¥12,680" 输出 12680
输出 "2.5h" 输出 2.5
输出 "32笔" 输出 32
输出 "85%" 输出 85
输出 "星级" 作为等级 输出 "star"
输出 "待处理" 作为状态 输出 "pending"
省略值为 null 的字段 显式输出 null
0 代替 null 表示「无」 null0 保留给有意义的零值)
输出 Unix 毫秒时间戳 输出 ISO 8601 字符串
输出 YYYY/MM/DD 日期格式 输出 YYYY-MM-DD
后端做 toLocaleString() 格式化 后端输出原始数值,前端格式化
hoursRaw 输出 "(折0.5h)" 输出 3.0(原始小时数)

关联文档

  • DISPLAY-STANDARDS.md — 前端格式化规范
  • DISPLAY-STANDARDS-2.md — 截止日期 / 评分 / Mock 规范
  • DATETIME-DISPLAY-STANDARD.md — 时间展示规范
  • utils/money.tsformatMoney / formatCount / formatPercent / toProgressWidth
  • utils/time.tsformatHours / formatDeadline / formatRelativeTime
  • utils/rating.tsscoreToHalfStar / isUnrated
  • utils/mock-data.ts — Mock 数据(字段结构与接口保持一致)