|

Aimee

Write the Code. Change the World.

部分发货:三个包裹签收了两个,整单算完成了吗

· 分享镜

部分发货:三个包裹签收了两个,整单算完成了吗

实物商品拆单发货是常态——仓库不同、供应商不同、商品重量限制……一笔订单三个包裹,用户陆续签收。

问题来了:签收了两个,第三个还在途,整单状态要写什么?


整单状态不等于子单状态的简单映射

把子单状态汇总给父订单,听起来直觉上是"谁最慢就显示谁",但这个逻辑放在完成条件上会有歧义。

"已完成"意味着什么?

  • 所有子单都完成:最严格的定义。只要还有一个包裹没签收,整单不算完成。
  • 主要履约已完成:核心商品发出并签收,附赠品/赠品还在路上,整单可视为完成。
  • 用户主动确认:用户点击"全部收到",无论子单状态如何。

三种定义都有业务场景,选哪个要提前决定,不能等上线后再改——因为这影响到售后、评价、结算,牵一发动全身。


聚合算法:各状态组合的映射表

用穷举法把所有组合的结果定义清楚,比写一堆 if-else 更可维护:

子单状态组合父订单状态
全部 COMPLETEDCOMPLETED(已完成)
全部 CANCELLEDCANCELLED(已取消)
部分 COMPLETED + 部分 CANCELLEDPARTIALLY_COMPLETED(部分完成)
有任意 SHIPPEDPARTIALLY_SHIPPED(部分配送中)
有任意 PENDING_SHIPMENT,无 SHIPPEDPENDING_SHIPMENT(待发货)
有任意 EXCEPTION(异常)EXCEPTION(需处理)
OrderStatus aggregate(List<OrderStatus> statuses) {
    if (statuses.stream().allMatch(s -> s == COMPLETED)) return COMPLETED;
    if (statuses.stream().allMatch(s -> s == CANCELLED)) return CANCELLED;
    if (statuses.stream().allMatch(s -> s == COMPLETED || s == CANCELLED)) return PARTIALLY_COMPLETED;
    if (statuses.contains(EXCEPTION)) return EXCEPTION;
    if (statuses.contains(SHIPPED)) return PARTIALLY_SHIPPED;
    return PENDING_SHIPMENT;
}

超时自动完成

用户签收了却没点"确认收货"(或者 App 都没打开),快递已到站还在站点存放——这类订单不能永远停在"已签收待确认"状态。

标准做法:快递物流回传"已签收"后,启动超时计时(通常 7-15 天),到期自动触发"确认收货",订单转为完成状态,释放评价权限。

超时触发要对每个子单分别计时,而不是等所有子单都"已签收"才开始整体计时——先到的子单先开计时,签收了就可以评价那件商品,不用等最后一个包裹。


完成触发的后续动作

"已完成"不只是改一个字段,它触发的事情很多:

  • 解冻资金,结算给商家
  • 开启评价窗口(给每个子单对应的商品评价)
  • 关闭退货窗口(超过退货期)
  • 积分/返现到账

这些后续动作里,"结算给商家"是不可逆的,所以完成条件的定义格外重要。如果因为状态聚合逻辑错误把未全部履约的订单算成了完成,资金已经结算出去,追回来很麻烦。

宁可晚一点完成,不要早了。

评论0

登录后参与评论。

还没有评论,来抢沙发吧。

回到顶部