编辑/添加订单营员
对 导入订单 产生的订单做营员级维护:type=1(默认)编辑现有营员,按 order_num + sid 全量覆盖该营员字段,sid 不变;type=2 新增一名营员到订单,受订单购买人数上限约束。营员字段键与 获取营种导入模版 返回的 form_fields.child/big 的 name 一致,两种模式的落库口径均与 导入订单 完全同构。
本接口是"导入订单"链路的配套营员修正 / 追加接口,编辑采用全量覆盖语义(须回传完整字段)。若只需按单个字段增量修改,请使用 编辑订单营员。
核心语义
type=1编辑现有营员(默认):全量覆盖,student_info为该营员的完整字段集合,未提供的自定义字段会被置空;sid不变、不新建,不改动订单人数、库存、支付流水与幂等映射。建议每次回传完整字段,而非只传要改的项。type=2新增营员:sid可为 0(传了也忽略),系统按导入订单的落库行为新建一名营员并绑定到该订单;新增前校验订单现有营员总数不得达到购买人数上限number(见导入订单返回的order_num对应订单),新增仅在已购名额内追加,不再改动库存 / 支付。成人营员(is_children=0)仅亲子营支持。- 落库口径与
导入订单一致:两种type均复用同一套字段映射、选项文案 → 存储值转换、表单快照构建,保证编辑 / 新增后后台回显不错乱。 - 儿童 / 成人判定:
type=1由该sid在订单内既有类型自动决定,无需上游指定;type=2由入参is_children指定(默认1=儿童)。 - 工具接口契约:
code恒为0;成功时msg为空、data为营员摘要;失败时msg非空、data为空数组。
请求参数
| 名称 | 类型 | 描述 | 是否必填 | 默认值 | 备注 |
|---|---|---|---|---|---|
| token | String | 身份校验令牌 | 必填 | - | 由 获取访问令牌 获得 |
| order_num | String | 订单号 | 必填 | - | 导入订单 返回的 order_num,形如 NO... |
| type | Number | 编辑或新增 | 非必填 | 1 | 1=编辑现有营员(默认),2=新增营员;非 1/2 归一为 1 |
| sid | Number | 营员 ID | type=1 必填 | - | 必须属于该订单,否则报错;值取 获取订单营员信息 的 sid;type=2 时可为 0 / 缺省(新增后返回新营员 ID) |
| is_children | Number | 新增营员类型 | 非必填(仅 type=2 生效) | 1 | 1=儿童(默认);0=成人,仅亲子营支持 |
| student_info | String / Object | 营员对象 | 必填 | - | 可传 JSON 字符串,或标准 POST 数组(student_info[name]=...),两种形式均兼容;键 = 模版 form_fields 的 name,结构与 导入订单 的 students[i] 完全一致;仅支持单个营员 |
student_info 字段
固定六项映射口径与 导入订单 完全一致:
| 键 | 说明 |
|---|---|
| name | 姓名 |
| gender | 性别文本:含"男"→男,含"女"→女,其它→未知 |
| phone | 营员手机号 |
| birthday | 出生日期(如 2015-01-01);证件类型为身份证时以证件号反推为准 |
| idcard_type | 证件类型文本:含"身份证"→身份证,含"护照"→护照,其它→其他 |
| idcard | 证件号。合法身份证号会自动强制类型为身份证并反推生日 / 性别;缺省时系统生成虚拟号(类型降级为"其他") |
其余自定义字段(如 school_name、grade、medical_history 等)按模版定义的 name 传值即可;未在表单定义中的键会被忽略。
选项类字段(radio / select / checkbox)传文案(如 grade 传"三年级"、性别传"男"),服务端在落库前自动转换为存储值:select 为 0 起、radio / checkbox 为 1 起(checkbox 多选用逗号分隔文案,转为逗号分隔存储值)。
CURL
V1
curl --location --request POST 'https://open.xinduobang.cn/api/editStudent' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=YOUR_TOKEN' \
--data-urlencode 'order_num=NO20261009103000123456' \
--data-urlencode 'sid=88123' \
--data-urlencode 'student_info={"name":"张小明","gender":"男","phone":"13800000001","birthday":"2015-03-01","idcard_type":"身份证","idcard":"110105201503010012","school_name":"实验小学","grade":"三年级"}'
V2(appid 为 V2 版本)
curl --location --request POST 'https://open.xinduobang.cn/api/editStudent' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'X-Timestamp: 1770000000' \
--header 'X-Nonce: 3f9c1a7b2e6d4058' \
--header 'X-Signature: <computed_hmac_sha256>' \
--data-urlencode 'token=YOUR_TOKEN' \
--data-urlencode 'order_num=NO20261009103000123456' \
--data-urlencode 'sid=88123' \
--data-urlencode 'student_info={"name":"张小明","gender":"男","phone":"13800000001","birthday":"2015-03-01","idcard_type":"身份证","idcard":"110105201503010012","school_name":"实验小学","grade":"三年级"}'
V2 签名算法及 X-Signature 计算方式见 V2 接入示例。
请求示例
type=1 编辑现有营员
POST 字段:
order_num=NO20261009103000123456、sid=88123、student_info=<下方 JSON>。下例修正了school_name(学校)与grade(年级,选项类字段传文案)。
{
"name": "张小明",
"gender": "男",
"phone": "13800000001",
"birthday": "2015-03-01",
"idcard_type": "身份证",
"idcard": "110105201503010012",
"school_name": "实验小学",
"grade": "三年级"
}
type=2 新增营员
POST 字段:
order_num=NO20261009103000123456、type=2、sid=0、is_children=1、student_info=<下方 JSON>(新增儿童营员,sid传0即可)。
{
"name": "张小红",
"gender": "女",
"phone": "13800000002",
"birthday": "2016-05-01",
"idcard_type": "身份证",
"idcard": "110105201605010024",
"school_name": "实验小学",
"grade": "二年级"
}
若订单现有营员总数已达购买上限 number,新增返回 {"code":0,"msg":"订单营员数已达上限(N人),无法继续增加","data":[]}。
成功响应
{
"code": 0,
"msg": "",
"data": {
"order_num": "NO20261009103000123456",
"order_id": 123456,
"sid": 88123,
"is_children": 1,
"student": {
"name": "张小明",
"sex": 1,
"phone": "13800000001",
"birthday": "2015-03-01",
"idcard_type": 1,
"idcard": "110105201503010012"
}
}
}
响应字段说明
| 键 | 类型 | 说明 |
|---|---|---|
| order_num / order_id | String / Number | 命中的订单号与订单 ID |
| sid | Number | type=1 为被编辑的营员 ID(保持不变);type=2 为新增营员的系统 ID |
| is_children | Number | 1 儿童,0 成人(type=1 由订单内既有类型判定;type=2 为入参指定值) |
| student | Object | 归一化后的营员摘要:sex 1 男 / 2 女 / 3 未知;idcard_type 1 身份证 / 2 护照 / 3 其他;birthday 在证件类型为身份证时为证件号反推值 |
失败响应
工具接口契约下
code恒为0,失败通过非空msg与空data标识。
{ "code": 0, "msg": "该订单下不存在此营员,sid=88123", "data": [] }
| 错误文案 | 说明 |
|---|---|
order_num不能为空 / sid不能为空 / student_info不能为空 | 参数缺失(sid不能为空 仅 type=1 触发;含 student_info 非法 JSON 无法解析) |
订单不存在:xxx | order_num 查无订单 |
该订单下不存在此营员,sid=xxx | type=1 时 sid 不属于该订单 |
订单营员数已达上限(N人),无法继续增加 | type=2 时订单现有营员总数已达购买上限 number |
非亲子营不支持新增成人营员 | type=2 且 is_children=0,但订单对应营种非亲子营 |
营种不存在,pid=xxx | type=2 时订单对应的营种查无 |
营员必填字段[xxx]为空 | 模版 isMust=1 字段非空校验失败 |
落库行为
type=1 编辑现有营员
系统按营员类型取对应报名表模版,全量覆盖以下内容:
- 营员档案:更新姓名、性别、出生日期、手机号、证件号、证件类型;
- 报名表快照:按当前表单定义重建该营员的表单数据与扁平字段(尺码 / 年级 / 班级 / 城市 / 学校等),并刷新为最新表单定义;
- 同步快照:相关表单前置快照一并更新,保持与导入链路一致;
sid、订单归属、营员类型(儿童 / 成人)保持不变;不新建营员、不改动订单人数、库存与支付流水、不写幂等映射。
type=2 新增营员
- 校验:订单现有营员总数必须小于购买上限
number,否则报人数超限;成人营员(is_children=0)仅亲子营允许;必填字段按导入口径校验; - 营员档案:复用
导入订单的创建行为——同一证件号在同一营期已存在时走更新覆盖并复用原营员 ID,否则新建; - 表单绑定:按营种报名表模版新增该营员的表单记录,与导入生成的记录同构;
- 订单人数:儿童(
is_children=1)或成人(is_children=0)报名人数 +1,购买上限number保持不变;不额外扣库存、不写支付流水(名额已在下单时扣减)。
相关接口
- 导入订单(产出
order_num/sid):导入订单 - 营种导入模版(字段定义来源):
获取营种导入模版 - 获取订单营员信息(取
sid):获取订单营员信息 - 增量修改单字段:
编辑订单营员 - 更换营期(线下导入订单,允许跨营种):
更换营期
变更记录
| 日期 | 变更 |
|---|---|
| 2026-10-12 | 新增 type(1=编辑现有营员(默认),2=新增营员)与 is_children 参数;type=2 时 sid 可为 0,新增前校验订单现有营员总数不得达到购买上限 number,新增后对应儿童 / 成人报名人数 +1 |
| 2026-10-10 | 首次发布:/api/editStudent(POST:order_num + sid + student_info),按订单 + 营员全量更新,落库口径与 导入订单 一致;选项类字段传文案、服务端自动转存储值 |