14 KiB
14 KiB
【修改接口·管理后台】核单 Step1 住宿成本字段 (#5043)
PR: #5047 | 服务: hl-order-service-v3 | 更新时间: 2026-07-18 16:50
1. 接口背景
核单 Step1 住宿成本明细需要对齐原型里的酒店资源、房型资源、核算单价、来源和确认状态展示。现有接口保留原路径,在 GET/PUT /v3/admin/order/{orderId}/settlement/step1 上做兼容增强。
2. 变更清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 查询住宿核算明细 | GET | /v3/admin/order/{orderId}/settlement/step1 |
修改接口 | HotelItemVO 出参新增 10 个字段 |
| 2 | 保存住宿核算明细 | PUT | /v3/admin/order/{orderId}/settlement/step1 |
修改接口 | HotelItemVO 入参支持保存酒店/房型资源、单价、来源和确认状态字段 |
3. 接口详情
3.1 查询住宿核算明细
- 使用场景:进入核单 Step1 住宿页签时查询住宿成本明细。
- 认证:需要管理后台 JWT。
- 幂等性:幂等,只读查询。
- 响应结构:
data为HotelItemVO[]数组。
3.2 保存住宿核算明细
- 使用场景:保存核单 Step1 住宿成本明细。
- 认证:需要管理后台 JWT。
- 幂等性:全量替换保存;同一份
items重复提交后,以最后一次提交为准。 - 请求体兼容:推荐使用
{ "items": [...] };历史数组 body[...]仍兼容。
4. 接口入参
4.1 路径参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
orderId |
string | 是 | 订单 ID,长整型字符串 |
4.2 PUT 请求体字段
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|---|---|---|---|---|
items |
array | 是 | 住宿成本明细行数组,全量替换保存 | 不允许为 null |
items[].id |
string | 否 | 已存在行 ID;全量替换保存时可不传 | 长整型字符串 |
items[].hotelAssignmentId |
string/null | 否 | 配房 assignment ID;手工行可为 null |
长整型字符串或 null |
items[].hotelId |
string/null | 否 | 酒店资源 ID;本次新增 | 长整型字符串或 null |
items[].roomTypeId |
string/null | 否 | 房型资源 ID;本次新增 | 长整型字符串或 null |
items[].stayDate |
string | 是 | 入住日期 | yyyy-MM-dd,不能早于订单出发日 |
items[].hotelName |
string | 是 | 酒店名称 | 1-200 字符 |
items[].roomType |
string/null | 否 | 房型分类或旧展示字段 | 最大 64 字符 |
items[].roomTypeName |
string/null | 否 | 房型/规格名称;本次新增 | 最大 64 字符 |
items[].roomCount |
integer | 是 | 总间数 | 正整数 |
items[].unitPrice |
number/null | 否 | 核算单价,单位元/间夜;本次新增;不传时按 actualCost / roomCount 降级计算 |
>= 0 |
items[].plannedCost |
number | 是 | 计划成本,单位元 | >= 0 |
items[].actualCost |
number | 是 | 实际成本,单位元 | >= 0 |
items[].paymentMethod |
string | 否 | 付款方式;与 settleType 二选一 |
SIGNED / COMPANY_PAID / CASH_PAID |
items[].paymentMethodName |
string | 否 | 付款方式中文名,仅展示字段;保存时可不传;本次新增 | 最大 32 字符 |
items[].settleType |
string | 否 | 配房结算类型;与 paymentMethod 二选一 |
cash / sign / company |
items[].sourceType |
string | 否 | 来源类型;本次新增;不传时按是否有 hotelAssignmentId 派生 |
HOUSE_ASSIGNMENT / MANUAL / TEMPLATE |
items[].sourceTypeName |
string | 否 | 来源类型中文名,仅展示字段;保存时可不传;本次新增 | 最大 32 字符 |
items[].sourceId |
string/null | 否 | 来源业务 ID;本次新增;配房来源默认等于 hotelAssignmentId |
长整型字符串或 null |
items[].settlementConfirmStatus |
string | 否 | 核单确认状态;本次新增;不传默认 CONFIRMED |
UNCONFIRMED / CONFIRMED |
items[].settlementConfirmStatusName |
string | 否 | 核单确认状态中文名,仅展示字段;保存时可不传;本次新增 | 最大 32 字符 |
items[].remark |
string/null | 否 | 备注 | 最大 500 字符 |
items[].voucherUrls |
array | 否 | 凭证图片 URL 数组 | 字符串数组 |
5. 出参
5.1 GET 响应字段:HotelItemVO
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string/null | 核单住宿明细行 ID;首次派生未保存的行可为 null |
hotelAssignmentId |
string/null | 配房 assignment ID;手工行可为 null |
hotelId |
string/null | 酒店资源 ID;本次新增 |
roomTypeId |
string/null | 房型资源 ID;本次新增 |
stayDate |
string | 入住日期,yyyy-MM-dd |
hotelName |
string | 酒店名称 |
roomType |
string/null | 房型分类或旧展示字段 |
roomTypeName |
string/null | 房型/规格名称;本次新增 |
roomCount |
integer | 总间数 |
unitPrice |
number/null | 核算单价,单位元/间夜;本次新增 |
plannedCost |
number | 计划成本,单位元 |
actualCost |
number | 实际成本,单位元 |
paymentMethod |
string | 付款方式 |
paymentMethodName |
string/null | 付款方式中文名;本次新增 |
settleType |
string/null | 配房结算类型;保存草稿后可能为空 |
sourceType |
string | 来源类型;本次新增 |
sourceTypeName |
string/null | 来源类型中文名;本次新增 |
sourceId |
string/null | 来源业务 ID;本次新增 |
settlementConfirmStatus |
string | 核单确认状态;本次新增 |
settlementConfirmStatusName |
string/null | 核单确认状态中文名;本次新增 |
remark |
string/null | 备注 |
voucherUrls |
array | 凭证图片 URL 数组 |
5.2 PUT 响应字段:SettlementHotelSaveRespVO
| 字段 | 类型 | 说明 |
|---|---|---|
addedIds |
string[] | 本次保存新增的核单住宿明细行 ID 列表 |
updatedIds |
string[] | 本次保存更新的核单住宿明细行 ID 列表;当前全量替换语义下通常为空数组 |
deletedIds |
string[] | 本次保存删除的核单住宿明细行 ID 列表;当前返回通常为空数组 |
totalActualCost |
string | 保存后 Step1 实际成本合计,单位元 |
6. 枚举 / 数据字典
6.1 paymentMethod
所属字段:items[].paymentMethod、data[].paymentMethod | 类型:String | 必填:否
| 值 | 中文 | 说明 |
|---|---|---|
SIGNED |
签单 | 现场签单 |
COMPANY_PAID |
公司付款 | 公司统一付款 |
CASH_PAID |
现付 | 现场现金或线下现付 |
6.2 settleType
所属字段:items[].settleType、data[].settleType | 类型:String | 必填:否
| 值 | 中文 | 映射后的 paymentMethod |
|---|---|---|
cash |
现付 | CASH_PAID |
sign |
签单 | SIGNED |
company |
公司付款 | COMPANY_PAID |
6.3 sourceType
所属字段:items[].sourceType、data[].sourceType | 类型:String | 必填:否
| 值 | 中文 | 说明 |
|---|---|---|
HOUSE_ASSIGNMENT |
配房结果 | 来自房务配房结果 |
MANUAL |
手工 | 核单手工补充住宿行 |
TEMPLATE |
模板 | 模板来源住宿行,当前预留 |
6.4 settlementConfirmStatus
所属字段:items[].settlementConfirmStatus、data[].settlementConfirmStatus | 类型:String | 必填:否
| 值 | 中文 | 说明 |
|---|---|---|
UNCONFIRMED |
未确认 | 核单住宿明细未确认 |
CONFIRMED |
已确认 | 核单住宿明细已确认;不传时默认该值 |
7. 错误码
| code | 含义 | 触发场景 |
|---|---|---|
584002 |
当前核单状态不允许录住宿核单 | PUT 保存时,订单不是「待核单」或「核单中」 |
584008 |
订单缺出发日期,无法派生 dayNumber | PUT 保存时订单出发日期为空 |
584009 |
stayDate 早于订单出发日期 |
PUT 保存时日期越界 |
584062 |
临时行必须指定付款方式 | paymentMethod 和 settleType 都为空 |
584064 |
配房记录 settleType 字典值非法 |
settleType 不是 cash/sign/company |
100001 |
参数非法 | 字段格式不符合校验,例如枚举值不在允许范围内、金额小于 0 |
8. 示例
8.1 典型成功:GET 查询
请求
GET /v3/admin/order/2077233855281971202/settlement/step1
Authorization: Bearer {token}
响应
{
"code": 200,
"message": "成功",
"success": true,
"data": [
{
"id": "2077328317421187001",
"hotelAssignmentId": "2077233886282088401",
"hotelId": "50001",
"roomTypeId": "51001",
"stayDate": "2026-07-18",
"hotelName": "海拉尔海棠酒店",
"roomType": "STANDARD",
"roomTypeName": "精品标间",
"roomCount": 2,
"unitPrice": 440.00,
"plannedCost": 880.00,
"actualCost": 880.00,
"paymentMethod": "CASH_PAID",
"paymentMethodName": "现付",
"settleType": "cash",
"sourceType": "HOUSE_ASSIGNMENT",
"sourceTypeName": "配房结果",
"sourceId": "2077233886282088401",
"settlementConfirmStatus": "CONFIRMED",
"settlementConfirmStatusName": "已确认",
"remark": "已核对",
"voucherUrls": []
}
]
}
8.2 边界成功:PUT 保存手工住宿行
请求
PUT /v3/admin/order/2077233855281971202/settlement/step1
Authorization: Bearer {token}
Content-Type: application/json
{
"items": [
{
"hotelAssignmentId": null,
"hotelId": null,
"roomTypeId": null,
"stayDate": "2026-07-18",
"hotelName": "临时补充酒店",
"roomType": "STANDARD",
"roomTypeName": "标准间",
"roomCount": 1,
"unitPrice": 300.00,
"plannedCost": 300.00,
"actualCost": 300.00,
"paymentMethod": "COMPANY_PAID",
"sourceType": "MANUAL",
"sourceId": null,
"settlementConfirmStatus": "UNCONFIRMED",
"voucherUrls": [],
"remark": "核单临时补充"
}
]
}
响应
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"addedIds": ["2078398065684692001"],
"updatedIds": [],
"deletedIds": [],
"totalActualCost": "300.00"
}
}
8.3 业务失败:缺付款方式
请求
PUT /v3/admin/order/2077233855281971202/settlement/step1
Authorization: Bearer {token}
Content-Type: application/json
{
"items": [
{
"hotelAssignmentId": null,
"stayDate": "2026-07-18",
"hotelName": "临时补充酒店",
"roomType": "STANDARD",
"roomCount": 1,
"plannedCost": 300.00,
"actualCost": 300.00
}
]
}
响应
{
"code": 584062,
"message": "临时行(无配房关联)必须指定 paymentMethod",
"data": null,
"success": false
}
9. 业务边界
PUT是全量替换保存;前端保存时应提交页面当前完整明细列表。hotelAssignmentId有值时通常表示配房来源;hotelAssignmentId为空时通常表示手工补充行。sourceType不传时,hotelAssignmentId有值默认HOUSE_ASSIGNMENT,否则默认MANUAL。sourceId不传且sourceType=HOUSE_ASSIGNMENT时,默认使用hotelAssignmentId;其他来源可为null。unitPrice不传且roomCount > 0、actualCost有值时,返回时会按actualCost / roomCount保留 2 位小数。settlementConfirmStatus不传时默认CONFIRMED。paymentMethod与settleType二选一;paymentMethod优先,settleType会映射成paymentMethod。- 订单核单状态必须是「待核单」或「核单中」才允许保存 Step1。
10. 修改前后对比
10.1 字段级对比
| 字段 | 修改前 | 修改后 |
|---|---|---|
hotelId |
无 | 新增,酒店资源 ID |
roomTypeId |
无 | 新增,房型资源 ID |
roomTypeName |
无 | 新增,房型/规格名称 |
unitPrice |
无 | 新增,核算单价 |
paymentMethodName |
无 | 新增,付款方式中文名 |
sourceType |
无 | 新增,来源类型 |
sourceTypeName |
无 | 新增,来源类型中文名 |
sourceId |
无 | 新增,来源业务 ID |
settlementConfirmStatus |
无 | 新增,核单确认状态 |
settlementConfirmStatusName |
无 | 新增,核单确认状态中文名 |
10.2 行为级对比
| 行为 | 修改前 | 修改后 |
|---|---|---|
| 住宿来源展示 | 只能通过 hotelAssignmentId 粗略判断 |
返回 sourceType/sourceTypeName/sourceId |
| 单价展示 | 前端只能根据总价和间数自行推算 | 返回 unitPrice,缺失时后端按实际成本和间数降级计算 |
| 确认状态展示 | 无独立字段 | 返回 settlementConfirmStatus/settlementConfirmStatusName |
11. 影响评估 / 回滚
11.1 影响评估
- 是否破坏向后兼容:否。新增字段为兼容性新增,旧字段保留。
- 前端是否必须同步上线:否。旧页面可继续按原字段展示;需要原型新增列时读取新增字段。
- 影响已有数据:历史行新增字段可能为
null,前端需要保留空值展示逻辑。
11.2 回滚方案
- 回滚接口代码后,前端不要再依赖本次新增字段。
- 如果页面已使用新增列,回滚期间新增列需要降级为空态展示。
12. 注意事项
paymentMethodName、sourceTypeName、settlementConfirmStatusName都是展示字段,保存时可不传。roomType是旧字段,roomTypeName是本次新增的房型/规格名称;两者可能同时存在。settlementConfirmStatus是核单明细确认状态,与房务配房确认状态不是同一个字段。
13. 关联 / 联系人
13.1 链接
13.2 联系人
- 后端负责人: @yaosutu