hl-api-changelog/changelogs/2026-04/2026-04-19_mp-order-has-refund-field.md

5.0 KiB

小程序订单 - 新增 hasRefund 语法糖字段

  • 日期: 2026-04-19
  • PR: #879 (Closes #875)
  • 类型: FEATURE
  • 状态: 已合并到 dev + 测试环境部署中
  • 服务: hl-mp-service + hl-order-service-v2

一、为什么加这个字段

前端在订单列表/订单详情/我的订单等多处场景都需要判断 "这个订单是否涉及退款",此前只能用原始字段组合推导:

// 旧: 前端自己拼判断
const hasRefund =
  ['REFUNDING', 'REFUNDED'].includes(order.status) ||
  (order.refundAmount != null && Number(order.refundAmount) > 0);

问题:

  • 多处重复写这段逻辑,容易漏写/写错
  • CANCELLED 状态不能只看 status,得再看 refundAmount(未付款取消 → 无退款;已付款取消 → 走退款流程)

后端统一派生,前端一个字段判空:

// 新: 一个字段搞定
if (order.hasRefund) { ... }

二、后端派生规则(前端只需知道结果,规则仅供参考

hasRefund = (status in [REFUNDING, REFUNDED]) || (refundAmount > 0)
订单状态 refundAmount hasRefund
PENDING_PAY false
DEPOSIT_PAID / PAID / CONFIRMED / PENDING_BALANCE / PENDING_DEPARTURE / TRAVELLING null/0 false
COMPLETED null/0 false
COMPLETED > 0有部分退款 true
CANCELLED null/0未付款取消 false
CANCELLED > 0已付款取消走退款 true
REFUNDING true
REFUNDED true

三、变更接口清单

# 方法 路径 影响
1 POST /mp/order/create 返回的 MpOrderDetailVO 新增 hasRefund
2 GET /mp/order/{orderId} 同上
3 PUT /mp/order/{orderId}/edit 同上
4 GET /mp/order/list 返回的 records[] 每项 MpOrderListItemVO 新增 hasRefund
5 GET /mp/order/upcoming 同上(列表结构)
6 GET /mp/order/lookup 同上(列表结构)

四、字段定义

MpOrderDetailVO.hasRefund

属性
类型 Boolean
位置 MpOrderDetailVO 根字段
序列化 字段级 @JsonInclude(ALWAYS),覆盖类级 NON_NULL,无论 true/false 都返回
空值可能 无(后端必派生非 null 值)

MpOrderListItemVO.hasRefund

属性
类型 Boolean
位置 列表每条记录根字段
序列化 类级默认
空值可能 无(后端必派生非 null 值)

五、响应示例对比

{
  "code": 200,
  "data": {
    "orderId": "2045...",
    "status": "CANCELLED",
    "statusLabel": "已取消",
    "refundAmount": 1000.00
  }
}

前端判断:hasRefund = 'CANCELLED' === 'REFUNDING' || ... || Number(1000) > 0true

{
  "code": 200,
  "data": {
    "orderId": "2045...",
    "status": "CANCELLED",
    "statusLabel": "已取消",
    "refundAmount": 1000.00,
    "hasRefund": true
  }
}

前端判断:order.hasRefundtrue


六、前端迁移建议

推荐:新代码直接用 hasRefund

// 订单卡片角标
<span v-if="order.hasRefund" class="badge-refund">
  {{ order.statusLabel }}
</span>

// 订单详情"退款信息"区块展示
<div v-if="order.hasRefund">
  <h3>退款进度</h3>
  <!-- refundProgress / refundAmount / refundPolicy  -->
</div>

兼容:旧组合判断不会失效

现有"status + refundAmount"组合判断仍然正确,不强制迁移。但建议新功能/重构时改用 hasRefund,减少重复逻辑。

⚠️ 不要改成这样

// ❌ 不要这样写,会在 false 时误判为 undefined
if (order.hasRefund === undefined) { ... }

// ✅ 直接布尔判断即可
if (order.hasRefund) { ... }
if (!order.hasRefund) { ... }

七、回归验证

测试环境部署完成后,用 mp token 调用:

# 1. 未付款订单(应 hasRefund=false)
curl "https://api.test.1814.love/mp/order/{pendingPayOrderId}" \
  -H "Authorization: Bearer {mp-token}" \
  | jq '.data | {status, refundAmount, hasRefund}'

# 2. 已取消已退款订单(应 hasRefund=true)
curl "https://api.test.1814.love/mp/order/{cancelledWithRefundOrderId}" \
  -H "Authorization: Bearer {mp-token}" \
  | jq '.data | {status, refundAmount, hasRefund}'

# 3. 列表(每条记录都应有 hasRefund)
curl "https://api.test.1814.love/mp/order/list?page=1&pageSize=10" \
  -H "Authorization: Bearer {mp-token}" \
  | jq '.data.records[] | {orderId, status, hasRefund}'

预期

  • 所有 3 个场景返回的 JSON 中 hasRefund 字段都存在(不管 true/false
  • 未付款/未退款订单:hasRefund: false
  • REFUNDING/REFUNDED 或 refundAmount > 0 订单:hasRefund: true

八、不兼容变更

。纯新增字段,前端不读不受影响;旧的 status / refundAmount / refundProgress 字段全部保留,语义不变。