app对接接口说明.md 33 KB

APP 对接接口说明

1. 文档说明

本文档用于统一维护 APP 对接后台接口说明。

  • 服务前缀:/api
  • 本地开发示例地址:http://localhost:18888
  • 鉴权方式:除登录等白名单接口外,请求头需携带登录后的 Token;APP 接口使用 APP 登录返回的 Token
  • 通用返回结构:codemessagedata

2. 接口目录

序号 接口名称 方法 URI 说明
1 查询用户背部产品穴位坐标列表 GET /api/user/acupoint/{profileId}/product-back-coordinates 查询指定子用户身体部位为背部且产品穴位为是的穴位坐标
2 查询当前账号下的设备列表 GET /api/app/device/list 通过 Token 获取当前 APP 账号可使用的设备列表
3 用户手动输入设备编号绑定设备 POST /api/app/user/device/bind-by-code APP 端按设备编号绑定到当前 Token 账号下,编号不存在返回错误提示
4 APP 端查询设备详情 GET /api/app/device/{id} APP 端查询当前账号可访问的设备详情(仅限已绑定的家庭/公共设备)
5 新增用户自定义方案 POST /api/app/custom-plan 当前用户新增一个自定义模式方案(含穴位步骤),后端强制设置 modeType=3、authorType=2、authorId=当前用户
6 查询当前用户的自定义方案列表 GET /api/app/custom-plan/list 通过 Token 获取当前 APP 账号下创作人属于自己的自定义模式方案基本信息列表(不含穴位步骤),如需详情请调用第 7 个接口
7 查询用户自定义方案详情 GET /api/app/custom-plan/{id} 查询当前用户自己的某个自定义方案详情,校验方案归属,含穴位步骤列表
8 修改用户自定义方案 PUT /api/app/custom-plan 当前用户修改自己的自定义方案(含穴位步骤),仅允许修改创作人为当前用户、模式为自定义模式的方案
9 删除用户自定义方案 DELETE /api/app/custom-plan/{id} 当前用户删除自己的自定义方案,仅允许删除创作人为当前用户、模式为自定义模式的方案

3. 接口详情

3.1 查询用户背部产品穴位坐标列表

3.1.1 接口用途

用于查询指定子用户的穴位坐标列表,接口固定筛选身体部位为背部,且产品穴位为的穴位。

当前场景:APP 根据用户档案 ID 获取该用户已计算出的背部产品穴位坐标,用于设备推送、坐标展示或调理方案匹配。

3.1.2 请求信息

  • 请求方式:GET
  • URI:/api/user/acupoint/{profileId}/product-back-coordinates
  • 完整示例:http://localhost:18888/api/user/acupoint/123/product-back-coordinates

3.1.3 请求参数

参数名 类型 是否必填 说明 示例
profileId number 子用户 ID,对应 user_profile.id,通过路径参数传递 123

3.1.4 调用示例

GET /api/user/acupoint/123/product-back-coordinates HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X GET "http://localhost:18888/api/user/acupoint/123/product-back-coordinates" \
  -H "Authorization: Bearer <token>"

3.1.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": [
    {
      "id": 192837465,
      "userId": 123,
      "acupointId": 371,
      "acupointCode": "dumai-14",
      "acupointName": "大椎",
      "acupointSide": "center",
      "bodyPart": "背部",
      "productAcupoint": 1,
      "coordinateX": 0.00,
      "coordinateY": 0.00,
      "coordinateZ": 0.00,
      "confidence": "high"
    },
    {
      "id": 192837466,
      "userId": 123,
      "acupointId": 362,
      "acupointCode": "dumai-04",
      "acupointName": "命门",
      "acupointSide": "center",
      "bodyPart": "背部",
      "productAcupoint": 1,
      "coordinateX": 0.00,
      "coordinateY": 245.30,
      "coordinateZ": 0.00,
      "confidence": "medium"
    }
  ]
}

3.1.6 字段说明

字段名 类型 说明
id number 用户穴位坐标记录 ID,对应 user_acupoint.id
userId number 子用户 ID,对应 user_profile.id
acupointId number 穴位 ID,对应 acupoint.id
acupointCode string 穴位编码
acupointName string 穴位名称
acupointSide string 坐标侧别:center=中心left=左侧right=右侧
bodyPart string 身体部位,本接口固定返回 背部
productAcupoint number 是否产品穴位,本接口固定返回 1
coordinateX number X 坐标,单位 mm,相对大椎穴中心,向右为正
coordinateY number Y 坐标,单位 mm,相对大椎穴中心,向下为正
coordinateZ number Z 坐标,单位 mm,当前体表坐标为 0
confidence string 坐标置信度:highmediumlow

3.1.7 备注

  • 本接口不需要传 bodyPartproductAcupoint,后端固定按 bodyPart=背部productAcupoint=1 查询。
  • 本接口只返回启用且未删除的穴位坐标,即 acupoint.status=1acupoint.deleted=0
  • 如果该子用户尚未生成穴位坐标表,后端会先自动生成用户穴位坐标,再返回查询结果。
  • profileId 使用子用户档案 ID,即 user_profile.id,不是后台管理员 ID。

3.2 查询当前账号下的设备列表

3.2.1 接口用途

用于根据请求头 Token 查询当前登录 APP 账号下可使用的设备列表。

当前场景:APP 登录后不再额外传 userIdstatus 等查询参数,后端从 Token 中解析当前账号 ID,返回该账号可使用的家庭设备和公共设备,用于展示当前账号可选择或可使用的设备。

3.2.2 请求信息

  • 请求方式:GET
  • URI:/api/app/device/list
  • 完整示例:http://localhost:18888/api/app/device/list

3.2.3 请求参数

无查询参数。后端通过 Authorization 请求头中的 Token 获取当前 APP 账号。

3.2.4 调用示例

GET /api/app/device/list HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X GET "http://localhost:18888/api/app/device/list" \
  -H "Authorization: Bearer <token>"

3.2.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": [
    {
      "id": 1001,
      "deviceId": 1001,
      "deviceCode": "AJY-0001",
      "deviceName": "艾灸椅一号",
      "deviceModel": "AJY-2026",
      "deviceType": 1,
      "deviceTypeName": "家庭设备",
      "serialNo": "SN202606020001",
      "firmwareVersion": "1.0.0",
      "onlineStatus": 0,
      "lastOnlineTime": "2026-06-02 10:30:00",
      "address": "广东省深圳市",
      "groupId": 2001,
      "memberId": 3001,
      "profileId": 123,
      "profileName": "张三",
      "profileComplete": true
    },
    {
      "id": 1002,
      "deviceId": 1002,
      "deviceCode": "AJY-0002",
      "deviceName": "共享艾灸椅",
      "deviceModel": "AJY-2026",
      "deviceType": 2,
      "deviceTypeName": "公共设备",
      "serialNo": "SN202606020002",
      "firmwareVersion": "1.0.0",
      "onlineStatus": 1,
      "lastOnlineTime": "2026-06-02 10:35:00",
      "address": "广东省深圳市",
      "groupId": null,
      "memberId": null,
      "profileId": 123,
      "profileName": "张三",
      "profileComplete": true
    }
  ]
}

3.2.6 字段说明

字段名 类型 说明
id number 设备 ID,对应 device.id
deviceId number 设备 ID,对应 device.id
deviceCode string 设备编号
deviceName string 设备名称
deviceModel string 设备型号
deviceType number 设备类型:1=家庭设备2=公共设备
deviceTypeName string 设备类型名称
serialNo string 设备序列号
firmwareVersion string 固件版本
onlineStatus number 在线状态:1=在线0=离线
lastOnlineTime string 最近在线时间
address string 设备地址
groupId number/null 家庭设备所属群组 ID,公共设备返回 null
memberId number/null 当前账号在家庭群组中的成员 ID,公共设备返回 null
profileId number/null 当前设备默认关联的用户档案 ID,对应 user_profile.id
profileName string/null 当前设备默认关联的用户档案名称
profileComplete boolean 当前关联档案是否已补全设备使用所需资料

3.2.7 备注

  • APP 查询设备列表时只需要携带 Token,不需要传 userIdstatuspageNumpageSize
  • 后端会根据 Token 中的当前 APP 账号 ID 查询该账号可使用的设备,包含家庭设备和公共设备。
  • 家庭设备来源于当前账号已加入的设备群组;公共设备来源于当前账号下用户档案已绑定的启用设备。
  • 本接口返回数组,不返回分页结构。

3.3 用户手动输入设备编号绑定设备

3.3.1 接口用途

用于 APP 端让用户手动输入设备编号后,将设备绑定到当前登录账号下。

后端会先根据设备编号查询设备主表 device

  • 如果设备编号存在,则从 Token 中获取当前 APP 账号 ID,自动确认或创建当前账号档案,再带出设备名称、设备型号等信息,并新增用户设备绑定记录。
  • 如果设备编号不存在,则返回错误码和错误信息,APP 可直接弹窗提示。

3.3.2 请求信息

  • 请求方式:POST
  • URI:/api/app/user/device/bind-by-code
  • 完整示例:http://localhost:18888/api/app/user/device/bind-by-code

3.3.3 请求参数

请求体格式:application/json

参数名 类型 是否必填 说明 示例
deviceCode string 用户手动输入的设备编号,对应 device.device_code AJY-0001

3.3.4 调用示例

POST /api/app/user/device/bind-by-code HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
Content-Type: application/json

{
  "deviceCode": "AJY-0001"
}
curl -X POST "http://localhost:18888/api/app/user/device/bind-by-code" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{\"deviceCode\":\"AJY-0001\"}"

3.3.5 成功返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "id": 192837466,
    "userId": 123,
    "deviceCode": "AJY-0001",
    "deviceName": "艾灸椅一号",
    "deviceModel": "AJY-2026",
    "isPrimary": 0,
    "onlineStatus": 0,
    "status": 1,
    "bindTime": "2026-06-02 10:35:00",
    "createTime": "2026-06-02 10:35:00",
    "updateTime": "2026-06-02 10:35:00"
  }
}

3.3.6 失败返回示例

设备编号不存在:

{
  "code": 1300,
  "message": "设备不存在",
  "data": null
}

当前账号已绑定此设备:

{
  "code": 1304,
  "message": "该用户已绑定此设备",
  "data": null
}

3.3.7 备注

  • APP 端只需要传 deviceCode,不需要传 userIddeviceNamedeviceModel
  • 后端从 Token 中获取当前 APP 账号 ID,并将设备绑定到当前账号对应的用户档案下。
  • 成功响应中的 userId 为后端自动关联的用户档案 ID,对应 user_profile.id
  • 后端会用 deviceCode 查询设备主表,存在时自动写入 deviceNamedeviceModel
  • 绑定成功后,绑定记录默认 status=1isPrimary=0
  • APP 可根据失败响应中的 message 直接弹窗,例如设备编号不存在时提示"设备不存在"。

3.4 APP 端查询设备详情

3.4.1 接口用途

用于 APP 端查询当前登录账号可访问的设备详情。

后端会根据 Token 中的 APP 账号 ID 校验访问权限:

  • 家庭设备(deviceType=1):校验当前 APP 账号是否在该设备的家庭群组内(device_group_member
  • 公共设备(deviceType=2):校验当前 APP 账号下的用户档案是否已绑定该设备(user_device
  • 越权或设备不存在时返回 4031300 错误

3.4.2 请求信息

  • 请求方式:GET
  • URI:/api/app/device/{id}
  • 完整示例:http://localhost:18888/api/app/device/1001

3.4.3 请求参数

参数名 类型 是否必填 说明 示例
id number 设备 ID,对应 device.id,通过路径参数传递 1001

3.4.4 调用示例

GET /api/app/device/1001 HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X GET "http://localhost:18888/api/app/device/1001" \
  -H "Authorization: Bearer <token>"

3.4.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "id": 1001,
    "deviceCode": "AJY-0001",
    "deviceName": "艾灸椅一号",
    "deviceModel": "AJY-2026",
    "deviceType": 1,
    "serialNo": "SN202606020001",
    "firmwareVersion": "1.0.0",
    "onlineStatus": 0,
    "lastOnlineTime": "2026-06-02 10:30:00",
    "provinceCode": "440000",
    "cityCode": "440300",
    "districtCode": "440305",
    "address": "广东省深圳市南山区",
    "remark": "测试设备",
    "deleted": 0,
    "createTime": "2026-06-01 09:00:00",
    "updateTime": "2026-06-02 10:30:00"
  }
}

3.4.6 字段说明

字段名 类型 说明
id number 设备 ID,对应 device.id
deviceCode string 设备编号
deviceName string 设备名称
deviceModel string 设备型号
deviceType number 设备类型:1=家庭设备2=公共设备
serialNo string 设备序列号
firmwareVersion string 固件版本
onlineStatus number 在线状态:1=在线0=离线
lastOnlineTime string 最后在线时间
provinceCode string 省级行政区划编码(GB/T 2260)
cityCode string 市级行政区划编码
districtCode string 区/县级行政区划编码
address string 详细地址
remark string 备注
deleted number 逻辑删除:0=未删除1=已删除
createTime string 创建时间
updateTime string 更新时间

3.4.7 失败返回示例

设备不存在:

{
  "code": 1300,
  "message": "设备不存在",
  "data": null
}

当前账号无权限访问该设备:

{
  "code": 403,
  "message": "无权访问该设备",
  "data": null
}

3.4.8 备注

  • 本接口需要 APP 登录后的 Token,不接受后台管理员 Token。
  • 越权校验在 Service 层完成,家庭设备校验 device_group_member.app_user_id,公共设备校验 user_device.user_id 是否归属当前 APP 账号下的用户档案。
  • 后端不会返回 boundUserCountboundUserNamesuserIds 等聚合字段,避免暴露其他用户信息。
  • 路径参数 iddevice.id(主键),不是设备编号 deviceCode,APP 调用时需先通过列表接口获取设备主键。

3.5 新增用户自定义方案

3.5.1 接口用途

用于 APP 端用户新增一个自定义模式方案(含穴位步骤)。

后端强制设置:

  • modeType = 3(自定义模式)
  • authorType = 2(用户创作)
  • authorId = 当前 APP 用户 ID
  • planCode = 系统自动生成(S + 6 位随机字符)

前端无需传入这些字段,后端会忽略前端传值。

3.5.2 请求信息

  • 请求方式:POST
  • URI:/api/app/custom-plan
  • 完整示例:http://localhost:18888/api/app/custom-plan

3.5.3 请求参数

请求体格式:application/json

参数名 类型 是否必填 说明 示例
name string 方案名称(最长 100 字符,不可重复) 我的祛湿方案
symptoms string 适用症状(逗号分隔) 关节酸痛,乏力
applicableGender number 适用人群:0=不限1=仅男2=仅女 0
ageMin number 适用年龄最小值(岁) 18
ageMax number 适用年龄最大值(岁) 60
description string 方案描述(最长 500 字符) 针对湿气重的人群定制
status number 状态:0=草稿1=已发布。不传默认为 1 1
steps array 穴位步骤列表,至少 1 个 见下方 steps 字段说明

steps 数组中每个元素字段:

参数名 类型 是否必填 说明
acupointId number 穴位 ID,对应 acupoint.id
side number 侧别:1=中心2=左侧3=右侧4=双侧。不传则跟随穴位默认侧别(一般为 1
temperature number 温度(°C,范围 35-50)
duration number 时长(分钟,范围 1-30)
techniqueId number 艾灸手法 ID(对应 moxibustion_technique.id
remark string 步骤备注(最长 100 字符)

说明:

  • 请求体中无需idplanIdstepOrderacupointNametechniqueName 等字段,后端会按 steps 数组顺序自动重排 stepOrder(从 1 开始),并通过 acupointId 自动带出 acupointNametechniqueName
  • 修改接口(PUT /api/app/custom-plan)与本接口共用同一份步骤结构,请求示例保持一致。

3.5.4 调用示例

POST /api/app/custom-plan HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "我的祛湿方案",
  "symptoms": "关节酸痛,乏力",
  "applicableGender": 0,
  "ageMin": 18,
  "ageMax": 60,
  "description": "针对湿气重的人群定制",
  "status": 1,
  "steps": [
    {
      "acupointId": 371,
      "side": 1,
      "temperature": 42.00,
      "duration": 10,
      "techniqueId": 1,
      "remark": "核心穴位"
    },
    {
      "acupointId": 362,
      "side": 1,
      "temperature": 42.00,
      "duration": 10,
      "techniqueId": 1,
      "remark": ""
    }
  ]
}
curl -X POST "http://localhost:18888/api/app/custom-plan" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"我的祛湿方案","symptoms":"关节酸痛,乏力","applicableGender":0,"ageMin":18,"ageMax":60,"description":"针对湿气重的人群定制","status":1,"steps":[{"acupointId":371,"side":1,"temperature":42.00,"duration":10,"techniqueId":1,"remark":"核心穴位"},{"acupointId":362,"side":1,"temperature":42.00,"duration":10,"techniqueId":1,"remark":""}]}'

3.5.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": 2067138786800111618
}

3.5.6 失败返回示例

方案名称重复:

{
  "code": 1702,
  "message": "方案名称已存在",
  "data": null
}

步骤为空:

{
  "code": 1706,
  "message": "方案步骤至少保留1个",
  "data": null
}

3.5.7 备注

  • modeTypeeffectTypeplanCodeauthorIdauthorNameauthorType 等字段前端无需传入,后端统一设置。
  • 方案名称不可重复,若重复返回 1702 错误。
  • 成功返回 data 为新方案的 ID,后续可用于详情查询、修改和删除。
  • steps 不能为空,至少包含 1 个穴位步骤。

3.6 查询当前用户的自定义方案列表

3.6.1 接口用途

用于 APP 端查询当前登录账号下,自己(作为创作人)创建的所有自定义模式(modeType=3)方案的基本信息。

当前场景:APP 中"我的方案"页面展示用户自己创建的自定义方案列表,用于查看、复用或继续编辑。

本接口只返回方案基本信息,不包含穴位步骤。查看方案详情(含穴位步骤)请使用第 7 个接口 GET /api/app/custom-plan/{id}

3.6.2 请求信息

  • 请求方式:GET
  • URI:/api/app/custom-plan/list
  • 完整示例:http://localhost:18888/api/app/custom-plan/list

3.6.3 请求参数

无查询参数。后端通过 Authorization 请求头中的 Token 获取当前 APP 账号 ID,仅返回创作人类型为用户(authorType=2)、模式为自定义模式(modeType=3)且创作人 ID 等于当前账号 ID 的方案。

3.6.4 调用示例

GET /api/app/custom-plan/list HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X GET "http://localhost:18888/api/app/custom-plan/list" \
  -H "Authorization: Bearer <token>"

3.6.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": [
    {
      "id": 1001,
      "planCode": "SA1B2C3",
      "name": "我的颈椎调理方案",
      "modeType": 3,
      "effectType": "",
      "symptoms": "肩颈酸痛,头晕",
      "applicableGender": 0,
      "ageMin": 18,
      "ageMax": 60,
      "description": "针对长期伏案人群的颈椎调理方案",
      "authorId": 17320687382,
      "authorName": "张三",
      "authorType": 2,
      "useCount": 12,
      "avgRating": 4.80,
      "lastUseTime": "2026-06-15 08:30:00",
      "status": 1,
      "createTime": "2026-06-10 09:00:00",
      "updateTime": "2026-06-12 10:30:00"
    },
    {
      "id": 1002,
      "planCode": "S9X8Y7Z6",
      "name": "我的祛湿方案",
      "modeType": 3,
      "effectType": "",
      "symptoms": "关节酸痛,乏力",
      "applicableGender": 0,
      "ageMin": 20,
      "ageMax": 60,
      "description": "针对湿气重的人群定制",
      "authorId": 17320687382,
      "authorName": "张三",
      "authorType": 2,
      "useCount": 0,
      "avgRating": null,
      "lastUseTime": null,
      "status": 1,
      "createTime": "2026-06-13 14:00:00",
      "updateTime": "2026-06-13 14:00:00"
    }
  ]
}

3.6.6 字段说明

字段名 类型 说明
id number 方案 ID,对应 plan.id
planCode string 方案编码
name string 方案名称
modeType number 模式类型,本接口固定返回 3(自定义模式)
effectType string 作用类型,自定义模式固定为空字符串
symptoms string 适用症状(逗号分隔)
applicableGender number 适用人群:0=不限1=仅男2=仅女
ageMin number/null 适用年龄最小值(岁)
ageMax number/null 适用年龄最大值(岁)
description string 方案描述
authorId number 创作人 ID,等于当前 APP 账号 ID
authorName string 创作人名称(冗余字段)
authorType number 创作人类型,本接口固定返回 2(用户创作)
useCount number 使用人数
avgRating number/null 平均评分
lastUseTime string/null 最后使用时间
status number 状态:0=草稿1=已发布2=已下架
createTime string 创建时间
updateTime string 更新时间

3.6.7 备注

  • 本接口不返回穴位步骤列表(steps),仅返回方案基本信息。如需查看方案详情和穴位步骤,请调用第 7 个接口 GET /api/app/custom-plan/{id}
  • 本接口仅返回当前 APP 账号作为"创作人"的自定义模式方案,不会返回系统方案或其他用户创作的方案。
  • 后端根据 Token 解析当前账号 ID 作为 authorId,按 authorType=2modeType=3authorId=当前用户ID 严格过滤。
  • useCountavgRating 为方案被使用后的统计字段,新建方案的初始值为 0/null
  • 结果按 updateTime 倒序返回,最近修改或创建的方案排在前。

3.7 查询用户自定义方案详情

3.7.1 接口用途

用于 APP 端查询当前登录账号下,自己创建的某个自定义模式方案详情,校验方案归属权,避免越权访问。

3.7.2 请求信息

  • 请求方式:GET
  • URI:/api/app/custom-plan/{id}
  • 完整示例:http://localhost:18888/api/app/custom-plan/1001

3.7.3 请求参数

参数名 类型 是否必填 说明 示例
id number 方案 ID,对应 plan.id,通过路径参数传递 1001

3.7.4 调用示例

GET /api/app/custom-plan/1001 HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X GET "http://localhost:18888/api/app/custom-plan/1001" \
  -H "Authorization: Bearer <token>"

3.7.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "id": 1001,
    "planCode": "SA1B2C3",
    "name": "我的颈椎调理方案",
    "modeType": 3,
    "symptoms": "肩颈酸痛,头晕",
    "applicableGender": 0,
    "ageMin": 18,
    "ageMax": 60,
    "description": "针对长期伏案人群的颈椎调理方案",
    "useCount": 12,
    "avgRating": 4.80,
    "status": 1,
    "createTime": "2026-06-10 09:00:00",
    "updateTime": "2026-06-12 10:30:00",
    "steps": [
      {
        "id": 5001,
        "planId": 1001,
        "stepOrder": 1,
        "acupointId": 371,
        "acupointName": "大椎穴",
        "side": 1,
        "temperature": 42.00,
        "duration": 10,
        "techniqueId": 1,
        "techniqueName": "温和灸",
        "remark": ""
      }
    ]
  }
}

3.7.6 字段说明

方案基本信息字段(idplanCodenamemodeTypeeffectTypesymptomsapplicableGenderageMinageMaxdescriptionauthorIdauthorNameauthorTypeuseCountavgRatinglastUseTimestatuscreateTimeupdateTime)定义同 3.6.6 节。

steps 穴位步骤列表字段:

字段名 类型 说明
steps array 穴位步骤列表,按 stepOrder 升序
steps[].id number 步骤 ID,对应 plan_step.id
steps[].planId number 所属方案 ID
steps[].stepOrder number 步骤序号(从 1 开始)
steps[].acupointId number 穴位 ID,对应 acupoint.id
steps[].acupointName string 穴位名称(冗余字段)
steps[].side number 侧别:1=中心2=左侧3=右侧4=双侧
steps[].temperature number 温度(°C,范围 35-50)
steps[].duration number 时长(分钟,范围 1-30)
steps[].techniqueId number/null 艾灸手法 ID
steps[].techniqueName string/null 艾灸手法名称(冗余字段)
steps[].remark string 步骤备注

3.7.7 失败返回示例

方案不存在或非当前用户创建的自定义方案:

{
  "code": 1700,
  "message": "方案不存在",
  "data": null
}

3.7.8 备注

  • 越权校验在 Service 层完成:仅当 modeType=3authorType=2authorId=当前用户ID 同时满足时才返回方案详情,否则按"方案不存在"处理。
  • 不会返回其他用户创作的方案、系统预设方案(modeType=1/2/4)的详情。
  • APP 在编辑方案前应先调用本接口获取最新数据。

3.8 修改用户自定义方案

3.8.1 接口用途

用于 APP 端让用户修改自己创建的自定义模式方案,包括方案基本信息和穴位步骤列表。

请求体格式与"新增用户自定义方案"接口(POST /api/app/custom-plan,见 3.5 节)保持一致,仅多一个 id 字段。steps 结构、字段含义、必填/可选规则完全相同。

3.8.2 请求信息

  • 请求方式:PUT
  • URI:/api/app/custom-plan
  • 完整示例:http://localhost:18888/api/app/custom-plan

3.8.3 请求参数

请求体格式:application/json

参数名 类型 是否必填 说明 示例
id number 方案 ID,对应 plan.id 1001
name string 方案名称(最长 100 字符,不可重复) 我的祛湿方案
symptoms string 适用症状(逗号分隔) 关节酸痛,乏力
applicableGender number 适用人群:0=不限1=仅男2=仅女 0
ageMin number 适用年龄最小值(岁) 18
ageMax number 适用年龄最大值(岁) 60
description string 方案描述(最长 500 字符) 针对湿气重的人群定制
status number 状态:0=草稿1=已发布2=已下架 1
steps array 穴位步骤列表,传 [] 表示清空所有步骤,传 null 表示保留原步骤 见下方 steps 字段说明

steps 数组中每个元素字段(与 3.5 节"新增用户自定义方案"完全一致):

参数名 类型 是否必填 说明
acupointId number 穴位 ID,对应 acupoint.id
side number 侧别:1=中心2=左侧3=右侧4=双侧。不传则跟随穴位默认侧别(一般为 1
temperature number 温度(°C,范围 35-50)
duration number 时长(分钟,范围 1-30)
techniqueId number 艾灸手法 ID(对应 moxibustion_technique.id
remark string 步骤备注(最长 100 字符)

说明:请求体中无需id(步骤)、planIdstepOrderacupointNametechniqueName 等字段,后端会按 steps 数组顺序自动重排 stepOrder(从 1 开始),并通过 acupointId 自动带出 acupointNametechniqueName

3.8.4 调用示例

PUT /api/app/custom-plan HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
Content-Type: application/json

{
  "id": 1001,
  "name": "我的祛湿方案",
  "symptoms": "关节酸痛,乏力",
  "applicableGender": 0,
  "ageMin": 18,
  "ageMax": 60,
  "description": "针对湿气重的人群定制",
  "status": 1,
  "steps": [
    {
      "acupointId": 371,
      "side": 1,
      "temperature": 42.00,
      "duration": 10,
      "techniqueId": 1,
      "remark": "核心穴位"
    },
    {
      "acupointId": 362,
      "side": 1,
      "temperature": 42.00,
      "duration": 10,
      "techniqueId": 1,
      "remark": ""
    }
  ]
}
curl -X PUT "http://localhost:18888/api/app/custom-plan" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"id":1001,"name":"我的祛湿方案","symptoms":"关节酸痛,乏力","applicableGender":0,"ageMin":18,"ageMax":60,"description":"针对湿气重的人群定制","status":1,"steps":[{"acupointId":371,"side":1,"temperature":42.00,"duration":10,"techniqueId":1,"remark":"核心穴位"},{"acupointId":362,"side":1,"temperature":42.00,"duration":10,"techniqueId":1,"remark":""}]}'

3.8.5 成功返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": null
}

3.8.6 失败返回示例

方案不存在或非当前用户创建的自定义方案:

{
  "code": 1700,
  "message": "方案不存在",
  "data": null
}

方案名称已存在:

{
  "code": 1702,
  "message": "方案名称已存在",
  "data": null
}

穴位不存在或已停用:

{
  "code": 1400,
  "message": "穴位不存在",
  "data": null
}

3.8.7 备注

  • 本接口需要 APP 登录后的 Token,不接受后台管理员 Token。
  • 后端会自动校验 modeType=3authorType=2authorId=当前用户ID,不满足时按"方案不存在"处理,避免越权。
  • 修改方案时后端使用"先删后增"的方式更新穴位步骤:stepsnull 时保留原步骤;传 [] 时清空所有步骤;传非空数组时整体替换为新步骤并重新计算步骤序号。
  • 方案名称全局唯一,修改时不能与其他方案(包含其他用户创建的方案)重名。
  • 穴位必须处于启用状态(acupoint.status=1)才能被引用。
  • modeTypeeffectTypeplanCodeauthorIdauthorNameauthorTypeuseCountavgRating 等字段为系统字段,APP 传入也会被忽略,不允许用户修改。

    3.9 删除用户自定义方案

3.9.1 接口用途

用于 APP 端用户删除自己的自定义方案。

后端校验方案归属(modeType=3authorType=2authorId=当前用户ID),仅允许删除自己的自定义方案。删除为物理删除,会同步删除方案下的穴位步骤。

3.9.2 请求信息

  • 请求方式:DELETE
  • URI:/api/app/custom-plan/{id}
  • 完整示例:http://localhost:18888/api/app/custom-plan/2067138786800111618

3.9.3 请求参数

参数名 类型 是否必填 说明 示例
id number 方案 ID,对应 plan.id,通过路径参数传递 2067138786800111618

3.9.4 调用示例

DELETE /api/app/custom-plan/2067138786800111618 HTTP/1.1
Host: localhost:18888
Authorization: Bearer <token>
curl -X DELETE "http://localhost:18888/api/app/custom-plan/2067138786800111618" \
  -H "Authorization: Bearer <token>"

3.9.5 返回示例

{
  "code": 200,
  "message": "操作成功",
  "data": null
}

3.9.6 失败返回示例

方案不存在或不属于当前用户:

{
  "code": 1700,
  "message": "方案不存在",
  "data": null
}

3.9.7 备注

  • 删除为物理删除,不可恢复,请谨慎操作。
  • 仅允许删除创作人为当前用户的自定义模式方案,不存在或不属于当前用户的方案均返回 1700 错误。
  • 删除方案时会同步删除该方案下的所有穴位步骤。