moonsflyer 5 месяцев назад
Родитель
Сommit
dee6fa6e14
2 измененных файлов с 151 добавлено и 19 удалено
  1. 30 0
      app/common/logic/RefundLogic.php
  2. 121 19
      app/common/service/pay/MixedPayService.php

+ 30 - 0
app/common/logic/RefundLogic.php

@@ -116,6 +116,10 @@ class RefundLogic extends BaseLogic
             case PayEnum::BYTE_PAY:
                 self::bytePayRefund($order, $refundAmount);
                 break;
+             //混合支付退款
+            case PayEnum::MIXED_PAY:
+                self::mixedPayRefund($order, $refundAmount, $afterSaleId);
+                break;
             // 线下支付 直接完成
             case PayEnum::OFFLINE_PAY:
                 return true;
@@ -215,7 +219,33 @@ class RefundLogic extends BaseLogic
     }
 
 
+    /**
+     * @notes 混合支付退款
+     * @param $order 订单信息
+     * @param $refundAmount 退款金额
+     * @param $afterSaleId 售后ID
+     * @return bool
+     * @author 系统
+     * @date 2024/12/19
+     */
+    public static function mixedPayRefund($order, $refundAmount, $afterSaleId)
+    {
+        try {
+            $mixedPayService = new MixedPayService($order['order_terminal'], $order['user_id']);
+            $result = $mixedPayService->refund($order, $refundAmount, $afterSaleId);
+            
+            if ($result === false) {
+                throw new \Exception('混合支付退款失败:' . $mixedPayService->getError());
+            }
+            
+            return true;
+        } catch (\Exception $e) {
+            throw new \Exception('混合支付退款处理失败:' . $e->getMessage());
+        }
+    }
 
+
+    
     /**
      * @notes 退款日志
      * @param $order

+ 121 - 19
app/common/service/pay/MixedPayService.php

@@ -21,6 +21,11 @@ namespace app\common\service\pay;
 
 use app\common\enum\AccountLogEnum;
 use app\common\enum\PayEnum;
+use app\common\enum\AfterSaleEnum;
+use app\common\enum\AfterSaleLogEnum;
+use app\common\enum\NoticeEnum;
+use app\common\model\AfterSale;
+use app\common\service\after_sale\AfterSaleService;
 use app\common\logic\AccountLogLogic;
 use app\common\model\User;
 use think\facade\Db;
@@ -191,42 +196,139 @@ class MixedPayService extends BasePayService
      */
     public function refund($order, $refundAmount, $afterSaleId)
     {
+        Db::startTrans();
         try {
+            // 记录退款日志
+            file_put_contents(
+                runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                "[" . date('Y-m-d H:i:s') . "] 混合支付退款开始 - 订单号: {$order['sn']}, 退款金额: {$refundAmount}" . PHP_EOL,
+                FILE_APPEND | LOCK_EX
+            );
+
             // 获取订单的余额支付金额和微信支付金额
             $balanceAmount = $order['balance_amount'] ?? 0;
             $wechatAmount = $order['order_amount'] - $balanceAmount;
 
-            // 按比例退款
-            if ($refundAmount >= $order['order_amount']) {
-                // 全额退款
-                $refundBalanceAmount = $balanceAmount;
-                $refundWechatAmount = $wechatAmount;
-            } else {
-                // 部分退款,按比例分配
-                $refundRatio = $refundAmount / $order['order_amount'];
-                $refundBalanceAmount = $balanceAmount * $refundRatio;
-                $refundWechatAmount = $wechatAmount * $refundRatio;
+            // 计算退款比例
+            $refundRatio = $refundAmount / $order['order_amount'];
+            $refundBalanceAmount = round($balanceAmount * $refundRatio, 2);
+            $refundWechatAmount = round($wechatAmount * $refundRatio, 2);
+
+            // 确保退款金额精确
+            $totalCalculated = $refundBalanceAmount + $refundWechatAmount;
+            if ($totalCalculated != $refundAmount) {
+                $diff = $refundAmount - $totalCalculated;
+                if ($refundWechatAmount > 0) {
+                    $refundWechatAmount += $diff;
+                } else {
+                    $refundBalanceAmount += $diff;
+                }
             }
 
-            // 退回余额
+            file_put_contents(
+                runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                "[" . date('Y-m-d H:i:s') . "] 退款分配 - 余额退款: {$refundBalanceAmount}, 微信退款: {$refundWechatAmount}" . PHP_EOL,
+                FILE_APPEND | LOCK_EX
+            );
+
+            // 处理余额退款
             if ($refundBalanceAmount > 0) {
-                $this->balancePayService->refund($order, $refundBalanceAmount, $afterSaleId);
+                // 返回余额
+                User::update([
+                    'user_money' => ['inc', $refundBalanceAmount]
+                ], ['id' => $order['user_id']]);
+
+                // 记录余额流水
+                $afterSale = AfterSale::findOrEmpty($afterSaleId);
+                AccountLogLogic::add(
+                    $order['user_id'],
+                    AccountLogEnum::BNW_INC_AFTER_SALE,
+                    AccountLogEnum::INC,
+                    $refundBalanceAmount,
+                    $afterSale->sn,
+                    '混合支付退款-余额部分'
+                );
+
+                file_put_contents(
+                    runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                    "[" . date('Y-m-d H:i:s') . "] 余额退款完成: {$refundBalanceAmount}" . PHP_EOL,
+                    FILE_APPEND | LOCK_EX
+                );
             }
 
-            // 微信退款
+            // 处理微信退款
             if ($refundWechatAmount > 0) {
-                // 这里需要调用微信退款接口
                 $refundData = [
-                    'out_trade_no' => $order['sn'],
-                    'out_refund_no' => 'refund_' . $order['sn'] . '_' . time(),
-                    'total_fee' => $wechatAmount * 100, // 原订单金额(分)
-                    'refund_fee' => $refundWechatAmount * 100, // 退款金额(分)
+                    'transaction_id' => $order['transaction_id'],
+                    'refund_sn' => 'mixed_refund_' . $order['sn'] . '_' . time(),
+                    'total_fee' => $wechatAmount,
+                    'refund_fee' => $refundWechatAmount,
                 ];
-                $this->wechatPayService->refund($refundData);
+
+                $result = $this->wechatPayService->refund($refundData);
+                if ($result !== true) {
+                    throw new \Exception('微信退款失败:' . $this->wechatPayService->getError());
+                }
+
+                file_put_contents(
+                    runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                    "[" . date('Y-m-d H:i:s') . "] 微信退款完成: {$refundWechatAmount}" . PHP_EOL,
+                    FILE_APPEND | LOCK_EX
+                );
+            }
+
+            // 更新售后状态
+            $afterSale = AfterSale::findOrEmpty($afterSaleId);
+            if (!$afterSale->isEmpty()) {
+                // 判断退款状态
+                $refundStatus = ($refundAmount >= $order['order_amount']) ? 
+                    AfterSaleEnum::FULL_REFUND : AfterSaleEnum::PARTIAL_REFUND;
+
+                $afterSale->status = AfterSaleEnum::STATUS_SUCCESS;
+                $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_SELLER_REFUND_SUCCESS;
+                $afterSale->refund_status = $refundStatus;
+                $afterSale->save();
+
+                // 添加售后日志
+                AfterSaleService::createAfterLog(
+                    $afterSale->id, 
+                    '系统已完成混合支付退款', 
+                    0, 
+                    AfterSaleLogEnum::ROLE_SYS
+                );
+
+                // 发送退款成功通知
+                event('Notice', [
+                    'scene_id' => NoticeEnum::REFUND_SUCCESS_NOTICE,
+                    'params' => [
+                        'user_id' => $afterSale->user_id,
+                        'order_sn' => $order['sn'],
+                        'after_sale_sn' => $afterSale->sn,
+                        'refund_type' => AfterSaleEnum::getRefundTypeDesc($afterSale->refund_type),
+                        'refund_total_amount' => $afterSale->refund_total_amount,
+                        'refund_time' => date('Y-m-d H:i:s'),
+                    ]
+                ]);
             }
 
+            file_put_contents(
+                runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                "[" . date('Y-m-d H:i:s') . "] 混合支付退款成功" . PHP_EOL,
+                FILE_APPEND | LOCK_EX
+            );
+
+            Db::commit();
             return true;
+
         } catch (\Exception $e) {
+            Db::rollback();
+
+            file_put_contents(
+                runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_refund_debug_' . date('Y-m-d') . '.log',
+                "[" . date('Y-m-d H:i:s') . "] 混合支付退款失败: " . $e->getMessage() . PHP_EOL,
+                FILE_APPEND | LOCK_EX
+            );
+
             $this->setError($e->getMessage());
             return false;
         }