current_offer_price 全链路(超详细版)

1. 业务定义(一句话)

⚡⚡⚡ 订单级插件(如积分兑换、买家保障、定制服务等)的明细价格逐条汇总,形成 current_offer_price,写入 o_order.current_offer_price 后参与 total_price 汇总。

2. 后台配置到前台计算的关系

2.1 商家后台可控项(配置映射表)

后台配置项典型存储/来源前台读取点对计算的直接影响
插件启用状态各 handler 配置OrderDiyOfferService决定是否写入明细行
插件来源o_order_diy_offer.from_name明细表区分积分/保障/改价等不同插件
插件价格o_order_diy_offer.price明细表正数=附加费,负数=抵扣
订单IDo_order_diy_offer.order_id查询条件保证只汇总当前订单

2.2 全链路时序图(配置 → 计算 → 落库)

flowchart TD
A[插件策略/后台操作] --> B[OrderDiyOfferModel 写 o_order_diy_offer 明细]
B --> C["getOrderDiyOfferPrice(order_id)"]
C --> D[SQL 查询该订单全部明细行]
D --> E["PHP: Σ(price) 求和"]
E --> F[round 保留2位小数]
F --> G[setAttr current_offer_price]
G --> H[renew 重算 total_price]

3. 核心入口与数据结构

3.1 核心方法链路

OrderDiyOfferService.php
  └─ getOrderDiyOfferPrice(OrderModel $orderInfo)    汇总计算
        └─ OrderDiyOfferModel::getDiyOfferList()   查明细
  └─ updateOrderInfo(OrderModel $orderInfo)          触发写回+renew

3.2 插件类型(from_name 典型取值)

from_name含义price 典型符号
points / points_off积分兑换抵扣负数
buyer_protection买家保障附加正数
gift_pack礼品包装附加正数
custom_service定制服务附加正数
assembly_fee组装费附加正数

⚠️ from_name 仅为追踪来源,不参与求和逻辑,所有插件明细的 price 一律求和。

4. 完整计算逻辑

4.1 getOrderDiyOfferPrice

private function getOrderDiyOfferPrice(OrderModel $orderInfo) : float
{
    $list = (new OrderDiyOfferModel())
        ->getDiyOfferList($orderInfo->getStoreId(), $orderInfo->getId());
 
    if ($list->isEmpty()) {
        return 0.00;
    }
 
    return array_sum(array_column($list->toArray(), 'price'));
}
  • SQL 查出订单所有插件明细
  • PHP 一行 array_sum 求和
  • 无明细时返回 0.00

⚡⚡⚡ price 字段本身可正可负——负数表示抵扣(如积分兑换),正数表示附加费,最终汇总后可能相互抵消。

4.2 updateOrderInfo(触发重算)

public function updateOrderInfo(OrderModel $orderInfo)
{
    $newOfferPrice = round($this->getOrderDiyOfferPrice($orderInfo), 2);
    $orderInfo->setAttr('current_offer_price', $newOfferPrice);
    (new OrderService())->renew($orderInfo->getId());
}

5. 字段输出结构

字段类型含义示例
o_order.current_offer_pricefloat汇总金额(可正可负)-7.00
o_order_diy_offer.pricefloat单笔插件金额-10.00 / 3.00
o_order_diy_offer.from_namestring插件来源标识points_off

6. 边界场景说明

6.1 明细为空

getDiyOfferList 返回空集合 → current_offer_price = 0.00

6.2 多插件同时生效且正负相抵

积分抵扣 -10 + 礼品包装 +3 → current_offer_price = -7

6.3 同一插件重复写入

o_order_diy_offer 有重复行,会被重复累计——这是数据质量问题,需在上游写入时做幂等校验。

6.4 updateOrderInfo 后总价未变

可能是 renew 未执行到写入逻辑,检查 renewcurrent_offer_price 的写回分支。

7. 与总价 total_price 的关系

total_price 的组成(9字段):
  subtotal_price        = Σ(final_line_price)              商品行小计
  discount_price        = 整单折扣(负数)
  refund_price          = 退款口径独立(不在此9字段中)
  current_total_price   = subtotal + shipping              仅展示
  total_price           = subtotal - promotion - coupon + shipping + tax + tip + payment + insurance + offer
                        └─ offer_price 在此处被加(可正可负)

⚡⚡⚡ offer_price 可正可负(附加费为正,抵扣为负),在 total_price 中做相应加减。

8. 关键代码索引

逻辑文件:行号
getOrderDiyOfferPriceOrderDiyOfferService.php:181-189
updateOrderInfo(触发renew)OrderDiyOfferService.php:174-179
OrderDiyOfferModel::getDiyOfferListOrderDiyOfferModel.php
明细表字段 schemaOrderDiyOfferModel.php:18
total_price 9字段汇总OrderService.php:2282-2290