接口实现进度-第5批.md 7.1 KB

第 5 批接口移植:订单事件 + 发货 + 售后

时间:2026-10-17 范围:订单运营主链路(改价/备注/改地址/取消审核/删除)、发货单(列表/详情/发货/物流轨迹)、售后(列表/详情/审核/收货退款)

一、本批完成的接口(13 个)

接口 方法 说明
/store/order.event/updatePrice POST 改价:实付款 = 订单金额 + 运费,记录改价差价
/store/order.event/updateRemark POST 商家备注(空值写空串)
/store/order.event/updateAddress POST 改收货地址(name/phone/cascader/detail)
/store/order.event/confirmCancel POST 审核用户取消:同意则退款 + 回退库存/优惠券/积分
/store/order.event/delete POST 订单软删除(is_delete=1)
/store/order.delivery/list GET 发货记录(paginate(10),排除 eorder_html)
/store/order.delivery/detail GET 发货单详情(只主表字段)
/store/order.delivery/delivery POST 确认发货(手动录入 / 无需物流 / 整单 / 分包)
/store/order.delivery/traces GET 物流轨迹(快递100)
/store/order.refund/list GET 售后列表(join 订单号,检索订单号/昵称/会员ID)
/store/order.refund/detail GET 售后详情(orderData/images.file/orderGoods.image/express/address/user)
/store/order.refund/audit POST 商家审核(同意/拒绝,同意时复制退货地址)
/store/order.refund/receipt POST 确认收货并退款(限额校验 + 余额退款 + 流水)

store 模块进度:151 个接口已实现 104 个,剩余 47 个。

URL 兼容:控制器对 updatePrice 与 update_price 两种写法都做了映射;前端实际调用的是驼峰写法(src/api/order/event.js)。

二、关键实现细节(对齐 PHP 行为)

1. 改价

  • 实付款 pay_price = order_price + express_price,两者皆 0 时报「订单实付款价格不能为0.00元」;
  • 改价差价 update_price = 新 order_price - 原 order_price,原值走获取器(库内为 0 时按 total_price - coupon_money + update_price 计算),不是直接读库;
  • 只有 pay_status = 10(待支付) 才能改价,否则「该订单不合法」。

2. 审核取消(confirmCancel)

  • 前置:pay_status = 20 且 order_status = 21(待取消);
  • status 为真:先退款,再走取消事件(回退商品总库存 + SKU 库存、优惠券 is_use=0、积分抵扣退回并写积分流水),最后 order_status = 20;
  • status 为假:仅把订单打回 order_status = 10。

3. 发货

  • 判定条件:pay_status = 20 且 delivery_status != 20,否则「订单号[xxx]不满足发货条件!」;
  • isAllPack=true 时自动取所有未发货商品(数量 = total_num - delivery_num);
  • 发货方式 20(无需物流)时物流单号强制写空;
  • 写「发货单 + 发货商品 + 订单商品累计发货数」,再按「是否全部发完」把订单置为已发货(20) / 部分发货(30) 并写 delivery_time;
  • 只有 order_type = 10(实物) 才写发货单。

4. 售后

  • 审核:拒绝必须填 refuse_desc,同意必须选 address_id;同意换货(type=20)直接置为已完成(20);同意退货退款则从商城收货地址复制一份到 order_refund_address;
  • 收货退款:refund_money ≤ min(订单实付款, 订单商品实付款);余额支付走「加余额 + scene=40 流水(订单退款:{订单号})」;is_settled=1 时同步扣减会员 expend_money。

5. 出参字段集合的两处坑

  • 发货列表里的 orderData 只 with 了 user、address,没有 trade 键,user 上也没有 avatar/avatar_url。订单实体默认会输出这些键,本批改为服务端用 ObjectNode 精确裁剪;
  • 订单详情的 user 未加载 avatar 关联,同样需要裁掉 avatar/avatar_url(列表接口则保留,两者不一致是 PHP 侧的真实行为)。

6. 关联键名

orderData、orderGoods、orderNo 这类驼峰关联名会被全局 SNAKE_CASE 转换,已用 @JsonProperty 固定(order_data / order_goods 是错的)。

三、验证结果

1. 读接口逐字段对比(tools/compare_order_batch.py,10/10 PASS,0 差异)

order.delivery/list(含筛选、空结果)、order.delivery/detail、order/detail×2、order/list、order.refund/list、order.refund/detail(不存在时)、order.delivery/traces(未开启物流查询时的报错文案)。

踩坑记录:PHP 侧 URL 是 index.php?s=/store/xxx/yyy,追加参数必须用 &,写成 ?page=1 会被当成方法名的一部分,返回 method not exists:...?page=1()。

2. 写接口端到端(tools/test_order_writes.py,77 项断言全通过)

现场造订单/售后单 → 调 Java 接口 → 直接查库断言 → 清理恢复,覆盖:

  • 改价成功 + 3 个非法分支(已支付、实付款为 0);
  • 备注写入/清空、改地址 4 个字段;
  • 软删除后详情不可见、列表不返回,再恢复;
  • 取消审核:拒绝(不动余额)/ 同意(余额 +31、scene=40 流水、商品库存 +1、SKU 库存 +1);
  • 发货:分包发货(部分发货 30)→ 整单发货 + 无需物流(已发货 20,单号为空)→ 重复发货被拒 → 未支付订单发货被拒;发货列表/详情字段集合校验;
  • 售后:拒绝无原因、同意无地址两个校验分支;同意后写退货地址;超额退款拦截;正常退款(余额 +10、流水 scene=40);换货同意即完成;拒绝后状态=10 且不写地址。

3. 回归

tools/compare_batch.py 28 个既有接口 28/28 PASS。

四、本批的已知限制(切流前需补)

  1. 微信小程序发货信息同步未接入:PHP 在 platform=MP_WEIXIN && pay_method=wechat 且订单全部发货时会调微信 API 上报物流;本批跳过该调用,sync_weixin_shipping 写 0。
  2. 第三方支付退款(微信/支付宝)未接入:需要商户证书与支付配置,当前对这两类支付方式抛「第三方支付退款暂未接入,请先在商户平台手动退款」;余额支付退款已完整实现(线上当前订单以余额支付为主)。
  3. 物流轨迹只接了快递100,阿里云驱动未实现;轨迹缓存在进程内(PHP 用 Cache 60 分钟),重启即失效,语义一致但非共享缓存。
  4. checkPrivilege(按角色校验 API 权限)仍未实现,目前只校验登录态。

五、下一步

剩余 47 个接口,建议顺序:

  1. 设置类:支付设置(options/update、支付模板 CRUD)、配送模板、运费模板、快递公司、打印机 CRUD(约 20 个,后台「设置」菜单几乎全空);
  2. 营销:优惠券详情/新增/编辑/删除/领取、充值方案增删改(8 个);
  3. 会员:等级增删改、会员删除/充值、充值订单(5 个);
  4. 内容/统计:商品评论 CRUD、客户端设置(h5/wxapp)、统计接口、controller/initialize、订单导出(约 14 个)。