11 KiB
11 KiB
【修改接口·管理后台】核单 Step2 景区游玩项目字段 (#5049)
PR: #5051 | 服务: hl-order-service-v3 | 更新时间: 2026-07-18 16:40
1. 接口背景
核单 Step2 的景区/游玩项目核算明细需要展示来源、行程天数、规格/票型、销售单价、销售小计和付款方式中文名。现有接口保留原路径,在原 GET/PUT /v3/admin/order/{orderId}/settlement/step2 上做兼容增强。
2. 变更清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 查询门票/游玩项目核算明细 | GET | /v3/admin/order/{orderId}/settlement/step2 |
修改接口 | TicketItemVO 出参新增 6 个字段 |
| 2 | 保存门票/游玩项目核算明细 | PUT | /v3/admin/order/{orderId}/settlement/step2 |
修改接口 | sourceType 新增 CUSTOM_ASSIGNMENT,入参支持保存规格、销售单价、销售小计 |
3. 接口详情
3.1 查询门票/游玩项目核算明细
- 使用场景:进入核单 Step2 景区/游玩项目页签时查询明细。
- 认证:需要管理后台 JWT。
- 幂等性:幂等,只读查询。
- 响应结构:
data为TicketItemVO[]数组。
3.2 保存门票/游玩项目核算明细
- 使用场景:保存核单 Step2 景区/游玩项目核算明细。
- 认证:需要管理后台 JWT。
- 幂等性:全量替换保存;同一份
items重复提交后,以最后一次提交为准。 - 请求体兼容:推荐使用
{ "items": [...] };历史数组 body[...]仍兼容。
4. 接口入参
4.1 路径参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
orderId |
string | 是 | 订单 ID,长整型字符串 |
4.2 PUT 请求体字段
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|---|---|---|---|---|
items |
array | 是 | 门票/游玩项目明细行数组,全量替换保存 | 不允许为 null |
items[].id |
string | 否 | 已存在行 ID;全量替换保存时可不传 | 长整型字符串 |
items[].sourceType |
string | 是 | 来源类型 | SCENIC_ASSIGNMENT / ACTIVITY_ASSIGNMENT / CUSTOM_ASSIGNMENT |
items[].sourceTypeName |
string | 否 | 来源类型中文名,仅展示字段;保存时可不传 | 最大 32 字符 |
items[].scenicAssignmentId |
string | 否 | 来源 assignment ID;手工项目传 null |
长整型字符串或 null |
items[].dayNumber |
integer | 否 | 行程第几天;保存时以后端根据 dayDate 计算后的值为准 |
从 1 开始 |
items[].dayDate |
string | 是 | 行程日期 | yyyy-MM-dd,不能早于订单出发日 |
items[].scenicName |
string | 是 | 景区/游玩项目名称 | 1-200 字符 |
items[].specName |
string | 否 | 规格/票型名称 | 最大 128 字符 |
items[].ticketCount |
integer | 是 | 实际购票数量 | 建议非负整数 |
items[].ticketUnitPrice |
number | 否 | 参考成本单价,单位元 | 小数 |
items[].sellPrice |
number | 否 | 客户成交单价,单位元 | >= 0 |
items[].totalAmount |
number | 否 | 客户成交小计,单位元;为空且有 sellPrice 时后端按 sellPrice * ticketCount 降级计算 |
>= 0 |
items[].plannedCost |
number | 是 | 计划成本,单位元 | >= 0 |
items[].actualCost |
number | 是 | 实际成本,单位元 | >= 0 |
items[].paymentMethod |
string | 否 | 付款方式;为空时默认 COMPANY_PAID |
SIGNED / COMPANY_PAID / CASH_PAID |
items[].paymentMethodName |
string | 否 | 付款方式中文名,仅展示字段;保存时可不传 | 最大 32 字符 |
items[].voucherUrls |
array | 否 | 凭证图片 URL 数组 | 字符串数组 |
items[].remark |
string | 否 | 备注 | 最大 500 字符 |
5. 出参
5.1 GET 响应字段:TicketItemVO
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 核单明细行 ID |
sourceType |
string | 来源类型 |
sourceTypeName |
string | 来源类型中文名;本次新增 |
scenicAssignmentId |
string/null | 来源 assignment ID;手工项目为 null |
dayNumber |
integer/null | 行程第几天;本次新增 |
dayDate |
string | 行程日期,yyyy-MM-dd |
scenicName |
string | 景区/游玩项目名称 |
specName |
string/null | 规格/票型名称;本次新增 |
ticketCount |
integer | 实际购票数量 |
ticketUnitPrice |
number/null | 参考成本单价 |
sellPrice |
number/null | 客户成交单价;本次新增 |
totalAmount |
number/null | 客户成交小计;本次新增 |
plannedCost |
number | 计划成本 |
actualCost |
number | 实际成本 |
paymentMethod |
string | 付款方式 |
paymentMethodName |
string/null | 付款方式中文名;本次新增 |
voucherUrls |
array | 凭证图片 URL 数组 |
remark |
string/null | 备注 |
5.2 PUT 响应字段:SettlementTicketSaveRespVO
| 字段 | 类型 | 说明 |
|---|---|---|
addedIds |
string[] | 本次保存新增的核单明细行 ID 列表 |
updatedIds |
string[] | 本次保存更新的核单明细行 ID 列表;当前全量替换语义下通常为空数组 |
deletedIds |
string[] | 本次保存删除的核单明细行 ID 列表;当前返回通常为空数组 |
totalActualCost |
string | 保存后 Step2 实际成本合计,单位元 |
6. 枚举 / 数据字典
6.1 sourceType
所属字段:items[].sourceType、data[].sourceType | 类型:String | 必填:是
| 值 | 中文 | 说明 |
|---|---|---|
SCENIC_ASSIGNMENT |
景区 | 景区来源行 |
ACTIVITY_ASSIGNMENT |
游玩项目 | 游玩项目来源行 |
CUSTOM_ASSIGNMENT |
手工项目 | 本次新增;核单手工补充行,scenicAssignmentId 可为 null |
6.2 paymentMethod
所属字段:items[].paymentMethod、data[].paymentMethod | 类型:String | 必填:否
| 值 | 中文 | 说明 |
|---|---|---|
SIGNED |
签单 | 现场签单 |
COMPANY_PAID |
公司付款 | 公司统一付款;未传 paymentMethod 时默认该值 |
CASH_PAID |
现付 | 现场现金/线下现付 |
7. 错误码
| code | 含义 | 触发场景 |
|---|---|---|
584011 |
当前核单状态不允许录门票核单 | PUT 保存时,订单不是「待核单」或「核单中」 |
100001 |
参数非法 | 字段格式不符合校验,例如 sourceType 不在允许枚举内、金额小于 0 |
8. 示例
8.1 典型成功:GET 查询
请求
GET /v3/admin/order/2077233855281971202/settlement/step2
Authorization: Bearer {token}
响应
{
"code": 200,
"message": "成功",
"success": true,
"data": [
{
"id": "2077328317421187073",
"sourceType": "SCENIC_ASSIGNMENT",
"sourceTypeName": "景区",
"scenicAssignmentId": "2077233886282088450",
"dayNumber": 5,
"dayDate": "2026-07-18",
"scenicName": "呼和诺尔草原旅游区",
"specName": null,
"ticketCount": 1,
"ticketUnitPrice": 59.00,
"sellPrice": null,
"totalAmount": null,
"plannedCost": 59.00,
"actualCost": 59.00,
"paymentMethod": "COMPANY_PAID",
"paymentMethodName": "公司付款",
"voucherUrls": [],
"remark": null
}
]
}
8.2 边界成功:PUT 保存手工项目
请求
PUT /v3/admin/order/2077233855281971202/settlement/step2
Authorization: Bearer {token}
Content-Type: application/json
{
"items": [
{
"sourceType": "CUSTOM_ASSIGNMENT",
"scenicAssignmentId": null,
"dayDate": "2026-07-18",
"scenicName": "临时补充游玩项目",
"specName": "成人票",
"ticketCount": 2,
"ticketUnitPrice": 12.34,
"sellPrice": 56.78,
"totalAmount": 113.56,
"plannedCost": 24.68,
"actualCost": 24.68,
"paymentMethod": "COMPANY_PAID",
"voucherUrls": [],
"remark": "核单临时补充"
}
]
}
响应
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"addedIds": ["2078398065684692994"],
"updatedIds": [],
"deletedIds": [],
"totalActualCost": "24.68"
}
}
8.3 业务失败:已核单订单禁止保存
请求
PUT /v3/admin/order/2077233886248534018/settlement/step2
Authorization: Bearer {token}
Content-Type: application/json
{
"items": []
}
响应
{
"code": 584011,
"message": "当前核单状态为「已核单」,不允许录门票核单,必须为「待核单」或「核单中」",
"data": null,
"success": false
}
9. 业务边界
PUT是全量替换保存;前端保存时应提交页面当前完整明细列表。CUSTOM_ASSIGNMENT表示核单手工补充项目,scenicAssignmentId可以为null。dayNumber保存时以后端根据dayDate和订单出发日计算的结果为准。totalAmount为空且sellPrice有值时,后端会按sellPrice * ticketCount降级计算。- 未传
paymentMethod时,后端默认使用COMPANY_PAID。 - 订单核单状态必须是「待核单」或「核单中」才允许保存 Step2。
10. 修改前后对比
10.1 字段级对比
| 字段 | 修改前 | 修改后 |
|---|---|---|
sourceType |
SCENIC_ASSIGNMENT / ACTIVITY_ASSIGNMENT |
新增 CUSTOM_ASSIGNMENT |
sourceTypeName |
无 | 新增,返回来源中文名 |
dayNumber |
无 | 新增,返回行程第几天 |
specName |
无 | 新增,返回/保存规格或票型名称 |
sellPrice |
无 | 新增,返回/保存客户成交单价 |
totalAmount |
无 | 新增,返回/保存客户成交小计 |
paymentMethodName |
无 | 新增,返回付款方式中文名 |
10.2 行为级对比
| 行为 | 修改前 | 修改后 |
|---|---|---|
| 手工补充项目来源 | 只能用既有来源类型兜底表达 | 可明确传 CUSTOM_ASSIGNMENT |
| 手工项目 assignment ID | 前端容易误以为必须有来源 ID | CUSTOM_ASSIGNMENT 下 scenicAssignmentId 可为 null |
| 销售金额展示 | 只能展示成本字段 | 可展示 sellPrice / totalAmount |
11. 影响评估 / 回滚
11.1 影响评估
- 是否破坏向后兼容:否。新增字段为兼容性新增;旧字段继续保留。
- 前端是否必须同步上线:否。旧页面可继续按原字段展示;需要原型新增列时再读取新字段。
- 影响已有数据:不需要前端做数据迁移;历史行新字段可能为
null。
11.2 回滚方案
- 回滚接口代码后,前端不要再依赖
CUSTOM_ASSIGNMENT和新增字段。 - 如已保存手工项目,回滚前应确认旧版本是否能识别该来源类型。
12. 注意事项
- 前端不要把
sourceTypeName、paymentMethodName当作提交必填项;它们是展示字段。 - 前端保存时建议保留并回传用户编辑后的
specName、sellPrice、totalAmount。 - 已核单订单保存 Step2 会返回
584011,这不是接口异常。
13. 关联 / 联系人
13.1 链接
13.2 联系人
- 后端负责人: @yst