diff --git a/app/common/dao/store/consumption/StoreConsumptionUserDao.php b/app/common/dao/store/consumption/StoreConsumptionUserDao.php index fe245447..6a09e7d6 100755 --- a/app/common/dao/store/consumption/StoreConsumptionUserDao.php +++ b/app/common/dao/store/consumption/StoreConsumptionUserDao.php @@ -44,6 +44,10 @@ class StoreConsumptionUserDao extends BaseDao public $consumptionTotalAmount; /** @var int $orderType 订单类型:1 groupOrder,2 order */ public $orderType = 2; + /** @var float $consumptionUsed 已使用的红包金额 */ + public $consumptionUsed; + /** @var float $profitRate 商品毛利率 */ + public $profitRate; protected function getModel(): string { @@ -353,6 +357,7 @@ class StoreConsumptionUserDao extends BaseDao } /** + * @deprecated 已废弃,用下面的 typeTwoByProduct 和 typeOneByProduct * 根据订单计算实际金额和红包金额 * @return array */ @@ -452,4 +457,83 @@ class StoreConsumptionUserDao extends BaseDao ]); } + /** + * 红包类型为 现金抵扣红包 + * 根据商品毛利率计算红包金额 + * @return array + */ + public function typeTwoByProduct() + { + // 把所有金额转换成分,避免红包金额产生误差 + $totalPrice = $this->orderProductPrice * 100; + $consumptionUsed = $this->consumptionUsed * 100; + $consumptionTotal = $this->consumptionTotalAmount * 100; + $consumptionBalance = $consumptionTotal - $consumptionUsed; + if ($consumptionBalance <= 0) { + return [$this->orderProductPrice, '0.00', $this->consumptionUsed]; + } + $rate = $this->getRate($this->profitRate); + $useAmount = bcmul($totalPrice, $rate, 2); + if ($useAmount >= $consumptionBalance) { + $useAmount = $consumptionBalance; + } + $payPrice = $totalPrice - $useAmount; + $consumptionUsed += $useAmount; + $payPrice = bcdiv($payPrice, 100, 2); + $useAmount = bcdiv($useAmount, 100, 2); + $consumptionUsed = bcdiv($consumptionUsed, 100, 2); + /** $payPrice:实际支付的金额,$useAmount:当前商品使用的红包金额,$consumptionUsed:使用的红包金额总计 */ + return [$payPrice, $useAmount, $consumptionUsed]; + } + + /** + * 红包类型为 无门槛红包 + * 根据商品毛利率计算红包金额 + * @return array + */ + public function typeOneByProduct() + { + // 把所有金额转换成分,避免红包金额产生误差 + $totalPrice = $this->orderProductPrice * 100; + $consumptionUsed = $this->consumptionUsed * 100; + $consumptionTotal = $this->consumptionTotalAmount * 100; + $groupOrderTotalPrice = $this->groupOrderTotalPrice * 100; + $rate = bcdiv($totalPrice, $groupOrderTotalPrice, 5); + if ($consumptionTotal >= $groupOrderTotalPrice) { + $useAmount = $totalPrice; + } else { + $useAmount = $this->isLast ? $consumptionTotal - $consumptionUsed : round(bcmul($consumptionTotal, $rate, 1)); + } + $payPrice = $totalPrice - $useAmount; + $consumptionUsed += $useAmount; + $payPrice = bcdiv($payPrice, 100, 2); + $useAmount = bcdiv($useAmount, 100, 2); + $consumptionUsed = bcdiv($consumptionUsed, 100, 2); + /** $payPrice:实际支付的金额,$useAmount:当前商品使用的红包金额,$consumptionUsed:使用的红包金额总计 */ + return [$payPrice, $useAmount, $consumptionUsed]; + } + + /** + * 根据商品毛利率计算红包抵扣比例 + * @param float $profitRate 毛利率 + * @return float|int + */ + public function getRate($profitRate) + { + $rateArray = [ + '0.25' => 0.4, + '0.2' => 0.3, + '0.15' => 0.2, + '0.1' => 0.1, + ]; + $rate = 0; + foreach ($rateArray as $k => $item) { + if ($profitRate >= $k) { + $rate = $item; + break; + } + } + return $rate; + } + } diff --git a/app/common/dao/user/UserBillDao.php b/app/common/dao/user/UserBillDao.php index 8e5e2153..773080fe 100755 --- a/app/common/dao/user/UserBillDao.php +++ b/app/common/dao/user/UserBillDao.php @@ -91,7 +91,7 @@ class UserBillDao extends BaseDao $lockMoney = 0; if (count($lst)) { $lockMoney = -1 * UserBill::getDB()->whereIn('link_id', array_column($lst, 'link_id')) - ->where('category', 'mer_refund_money')->sum('number'); + ->where('category', 'mer_refund_money')->where('mer_id', $merId)->sum('number'); } foreach ($lst as $bill) { $lockMoney = bcadd($lockMoney, $bill['number'], 2); diff --git a/app/common/repositories/store/order/StoreOrderCreateRepository.php b/app/common/repositories/store/order/StoreOrderCreateRepository.php index 3689a086..62bf8489 100755 --- a/app/common/repositories/store/order/StoreOrderCreateRepository.php +++ b/app/common/repositories/store/order/StoreOrderCreateRepository.php @@ -457,6 +457,7 @@ class StoreOrderCreateRepository extends StoreOrderRepository $cart['true_price'] = $cartTotalPrice; $procure = $this->cartByPrice($cart, 1); $procure_price = bcmul($cart['cart_num'], $procure, 2); + $cart['profit_rate'] = bcdiv(($cartTotalPrice - $procure_price), $cartTotalPrice, 2); $orderProcurePrice = bcadd($orderProcurePrice, $procure_price, 2); } unset($cart, $_k); @@ -621,42 +622,49 @@ class StoreOrderCreateRepository extends StoreOrderRepository $allow_no_address = false; } - // 计算红包总金额 - $consumptionTotal = 0; - if ($consumption_id > 0 && $this->store_consumption_user && $source == 103) { - if ($this->store_consumption_user['type'] == 2 && $order_total_price >= 6) { - if ($this->payType == 'balance') { - throw new ValidateException('余额支付时,不能使用抵扣红包'); - } - $consumptionTotal = bcdiv($order_total_price, 6, 2); - } - if ($this->store_consumption_user['type'] == 1) { - $consumptionTotal = min($order_total_price, $this->balance); - } - $consumptionTotal = min($consumptionTotal, $this->balance); + if ($this->store_consumption_user['type'] == 2 && $order_total_price >= 6 && $this->payType == 'balance') { + throw new ValidateException('余额支付时,不能使用抵扣红包'); } - $groupOrderPayPrice = $order_total_price; - foreach ($merchantCartList as $k => &$merchantCart) { - $isLast = count($merchantCartList) == $k + 1; - foreach ($merchantCart['list'] as &$cart) { - $cart['total_price'] = bcadd($cart['total_price'], $cart['svip_discount'], 2); - } - $orderPayPrice = $merchantCart['order']['total_price']; - if ($consumptionTotal) { - $storeConsumptionUserDao = new StoreConsumptionUserDao(); - $storeConsumptionUserDao->groupOrderTotalPrice = $groupOrderPayPrice; - $storeConsumptionUserDao->orderTotalPrice = $orderPayPrice; - $storeConsumptionUserDao->consumptionTotalAmount = $consumptionTotal; - $storeConsumptionUserDao->isLast = $isLast; - [$orderPayPrice, $groupOrderPayPrice, $useAmount, $consumptionTotal] = $storeConsumptionUserDao->calculateByOrder(); - $this->consumption_money = bcadd($this->consumption_money, $useAmount, 2); - $this->balance = bcsub($this->balance, $useAmount, 2); + $consumptionTotal = 0; + $consumptionUsed = 0; + $groupOrderPayPrice = 0; + if ($consumption_id > 0 && $this->store_consumption_user && $source == 103) { + $consumptionTotal = min($order_total_price, $this->balance); + } + foreach ($merchantCartList as $k => &$merchantCart) { + $lastOrder = count($merchantCartList) == $k + 1; + $orderPayPrice = 0; + $orderConsumptionAmount = 0; + foreach ($merchantCart['list'] as $key => &$cart) { + $cart['total_price'] = bcadd($cart['total_price'], $cart['svip_discount'], 2); + if ($consumptionTotal) { + $lastProduct = count($merchantCart['list']) == $key + 1; + $storeConsumptionUserDao = new StoreConsumptionUserDao(); + $storeConsumptionUserDao->groupOrderTotalPrice = $order_total_price; + $storeConsumptionUserDao->orderProductPrice = $cart['total_price']; + $storeConsumptionUserDao->profitRate = $cart['profit_rate']; + $storeConsumptionUserDao->consumptionTotalAmount = $consumptionTotal; + $storeConsumptionUserDao->consumptionUsed = $consumptionUsed; + $storeConsumptionUserDao->isLast = $lastOrder && $lastProduct; + if ($this->store_consumption_user['type'] == 2) { + [$payPrice, $useAmount, $consumptionUsed] = $storeConsumptionUserDao->typeTwoByProduct(); + } else { + [$payPrice, $useAmount, $consumptionUsed] = $storeConsumptionUserDao->typeOneByProduct(); + } + $this->consumption_money = bcadd($this->consumption_money, $useAmount, 2); + $this->balance = bcsub($this->balance, $useAmount, 2); + } + $cart['pay_price'] = $payPrice ?? $cart['total_price']; + $cart['consumption_price'] = $useAmount ?? 0; + $orderPayPrice = bcadd($orderPayPrice, $cart['pay_price'], 2); + $orderConsumptionAmount = bcadd($orderConsumptionAmount, $cart['consumption_price'], 2); + $groupOrderPayPrice = bcadd($groupOrderPayPrice, $cart['pay_price'], 2); } if ($source == 105) { $this->consumption_money = bcsub($orderPayPrice, 2, 2); - $useAmount = $this->consumption_money; + $orderConsumptionAmount = $this->consumption_money; $orderPayPrice = '2.00'; $groupOrderPayPrice = $orderPayPrice; $order_total_price = $orderPayPrice; @@ -665,7 +673,7 @@ class StoreOrderCreateRepository extends StoreOrderRepository } unset($cart); - $merchantCart['order']['consumption_money'] = $useAmount ?? '0.00'; + $merchantCart['order']['consumption_money'] = $orderConsumptionAmount; $merchantCart['order']['pay_price'] = $orderPayPrice; $merchantCart['order']['total_price'] = bcadd($merchantCart['order']['total_price'], $merchantCart['order']['svip_discount'], 2); $order_total_price = bcadd($order_total_price, $merchantCart['order']['svip_discount'], 2); @@ -1177,6 +1185,8 @@ class StoreOrderCreateRepository extends StoreOrderRepository 'cart_info' => json_encode($order_cart), 'product_source_id' => $product_source_id, 'product_mer_id' => $product_mer_id, + 'pay_price' => $cart['pay_price'], + 'consumption_price' => $cart['consumption_price'], ]; } diff --git a/app/common/repositories/store/order/StoreRefundOrderRepository.php b/app/common/repositories/store/order/StoreRefundOrderRepository.php index 57167173..bbdd3bdc 100755 --- a/app/common/repositories/store/order/StoreRefundOrderRepository.php +++ b/app/common/repositories/store/order/StoreRefundOrderRepository.php @@ -1343,7 +1343,6 @@ class StoreRefundOrderRepository extends BaseRepository $orderType = (isset($item['presell']) && $item['presell']) ? 'presell' : 'order'; if ($item['type'] == 0) { $this->refundBill($item, $res->uid, $id); - app()->make(MerchantRepository::class)->subLockMoney($res->mer_id, $orderType, $item['id'], $refundPrice); } else { if ($item['type'] == 10) $server = WechatService::create()->combinePay(); if (in_array($item['type'], [2])) $server = MiniProgramService::create();