Sfoglia il codice sorgente

订单佣金计算优化

ouyang 1 settimana fa
parent
commit
bba9f112a1
1 ha cambiato i file con 48 aggiunte e 26 eliminazioni
  1. 48 26
      biz-hd/distribution/classes/DistributionCommissionClass.php

+ 48 - 26
biz-hd/distribution/classes/DistributionCommissionClass.php

@@ -235,36 +235,34 @@ class DistributionCommissionClass
 
     /**
      * 统一计佣:商品实付、范围、比例、落库快照
+     * 计佣基数 = xhOrder.goodsPrice - xhOrder.tkPrice(不再拆 OrderGoods/OrderItem)
      */
     protected static function computeCommissionSnapshot(array $context)
     {
         $order = $context['order'];
         $rule = $context['rule'];
         $shopId = $context['shopId'];
-        $mainId = $context['mainId'];
         $buyerId = $context['buyerId'];
         $distId = $context['distId'];
         $bindTime = $context['bindTime'];
         $orderTime = $context['orderTime'];
 
         $bindDays = self::calcBindDaysAt($bindTime, $orderTime);
-        $payAmount = round((float)($order->actPrice ?? 0), 2);
-        $sendCost = round((float)($order->sendCost ?? 0), 2);
-        $goodsPayAmount = self::resolveGoodsPayAmount($order);
-        $orderAmount = $goodsPayAmount;
-
-        $commissionBase = self::adjustCommissionBaseByScope(
-            $rule,
-            $order->orderSn ?? '',
-            $goodsPayAmount,
-            $shopId,
-            $mainId
-        );
-        // 订单有累计退款时,计佣基数扣减 tkPrice(与 xhOrder.tkPrice 一致)
-        $commissionBase = self::applyRefundToCommissionBase($commissionBase, $order);
+        $payAmount = (float)self::bcMoney($order->actPrice ?? 0);
+        $sendCost = (float)self::bcMoney($order->sendCost ?? 0);
+
+        // 计佣基数:直接用商品金额减累计退款,避免按行明细/优惠比例二次折算导致误差
+        $goodsPrice = self::bcMoney($order->goodsPrice ?? 0);
+        $tkPrice = self::bcMoney($order->tkPrice ?? 0);
+        $commissionBase = self::bcMoney(bcsub($goodsPrice, $tkPrice, 2));
+        if (bccomp($commissionBase, '0', 2) < 0) {
+            $commissionBase = '0.00';
+        }
+        $orderAmount = (float)$goodsPrice;
+        $goodsPayAmount = (float)$commissionBase;
 
         $calc = self::resolveCommissionRate($rule, $bindDays);
-        $commissionRate = $calc['rate'];
+        $commissionRate = self::bcMoney($calc['rate'] ?? 0);
         $invalidReason = $calc['invalidReason'];
         $settleStatus = 0;
         $commissionAmount = 0;
@@ -279,9 +277,16 @@ class DistributionCommissionClass
 
         if ($invalidReason !== '') {
             $settleStatus = 2;
-        } elseif ($commissionBase > 0 && $commissionRate > 0) {
-            $commissionAmount = round($commissionBase * $commissionRate / 100, 2);
+        } elseif (bccomp($commissionBase, '0', 2) > 0 && bccomp($commissionRate, '0', 2) > 0) {
+            // 佣金 = 基数 × 比例 / 100,全程 bcmath,保留两位小数
+            $commissionAmount = (float)bcmul(
+                $commissionBase,
+                bcdiv($commissionRate, '100', 6),
+                2
+            );
         }
+        $commissionBase = (float)$commissionBase;
+        $commissionRate = (float)$commissionRate;
         // 完成不等于已结算:须 finishTime + settleDays 到期后才 settleStatus=1
         if ($settleStatus !== 2 && $commissionAmount > 0) {
             $canSettle = false;
@@ -342,7 +347,8 @@ class DistributionCommissionClass
                 'commissionRate' => $commissionRate,
                 'commissionBase' => $commissionBase,
                 'goodsPayAmount' => $goodsPayAmount,
-                'tkPrice' => round((float)($order->tkPrice ?? 0), 2),
+                'goodsPrice' => (float)$goodsPrice,
+                'tkPrice' => (float)$tkPrice,
                 'commissionAmount' => $commissionAmount,
                 'settleStatus' => $settleStatus,
                 'invalidReason' => $invalidReason,
@@ -704,20 +710,36 @@ class DistributionCommissionClass
     }
 
     /**
-     * 计佣基数扣减订单累计退款金额
+     * 金额规范为两位小数字符串(计佣加减乘除用,避免 float 精度误差)
+     * @param mixed $amount
+     * @return string
+     */
+    protected static function bcMoney($amount)
+    {
+        if ($amount === null || $amount === '') {
+            return '0.00';
+        }
+        return bcadd((string)$amount, '0', 2);
+    }
+
+    /**
+     * 计佣基数扣减订单累计退款金额(历史方法;现已改为 goodsPrice-tkPrice 直接算)
      * @param float $commissionBase 范围调整后的基数
      * @param object $order xhOrder
      * @return float
      */
     protected static function applyRefundToCommissionBase($commissionBase, $order)
     {
-        $commissionBase = round((float)$commissionBase, 2);
-        $tkPrice = round((float)($order->tkPrice ?? 0), 2);
-        if ($tkPrice <= 0 || $commissionBase <= 0) {
-            return $commissionBase;
+        $commissionBase = self::bcMoney($commissionBase);
+        $tkPrice = self::bcMoney($order->tkPrice ?? 0);
+        if (bccomp($tkPrice, '0', 2) <= 0 || bccomp($commissionBase, '0', 2) <= 0) {
+            return (float)$commissionBase;
+        }
+        $after = bcsub($commissionBase, $tkPrice, 2);
+        if (bccomp($after, '0', 2) < 0) {
+            return 0.0;
         }
-        $after = bcsub((string)$commissionBase, (string)$tkPrice, 2);
-        return round(max(0, (float)$after), 2);
+        return (float)$after;
     }
 
     protected static function resolveCommissionRate($rule, $bindDays)