Browse Source

feat: 增强OrderService中的退款处理

-添加了用于余额和付款退款的FinanceRecord创建,捕获了详细的交易数据。
-执行平台流量费和订单取消时的罚款收入记录。
-包括交通费和罚款的代理收入记录(如适用)。
-引入了一种生成唯一退款号码的新方法,改进了退款的跟踪和组织。
-更新了流程取消退款方法,以简化退款处理并确保准确的记录保存。
刘学玺 2 months ago
parent
commit
e354e85fe1
2 changed files with 183 additions and 3 deletions
  1. 64 0
      app/Models/FinanceRecord.php
  2. 119 3
      app/Services/Client/OrderService.php

+ 64 - 0
app/Models/FinanceRecord.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class FinanceRecord extends Model
+{
+    protected $fillable = [
+        'record_no',
+        'owner_type',
+        'agent_id',
+        'order_id',
+        'withdraw_id',
+        'recharge_id',
+        'type',
+        'business_type',
+        'amount',
+        'payment_type',
+        'region_code',
+        'user_id',
+        'coach_id',
+        'remark'
+    ];
+
+    protected $casts = [
+        'amount' => 'decimal:2',
+        'created_at' => 'datetime',
+        'updated_at' => 'datetime'
+    ];
+
+    /**
+     * 关联订单
+     */
+    public function order(): BelongsTo
+    {
+        return $this->belongsTo(Order::class);
+    }
+
+    /**
+     * 关联用户
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(MemberUser::class, 'user_id');
+    }
+
+    /**
+     * 关联技师
+     */
+    public function coach(): BelongsTo
+    {
+        return $this->belongsTo(CoachUser::class, 'coach_id');
+    }
+
+    /**
+     * 关联代理商
+     */
+    public function agent(): BelongsTo
+    {
+        return $this->belongsTo(AgentInfo::class, 'agent_id');
+    }
+}

+ 119 - 3
app/Services/Client/OrderService.php

@@ -37,6 +37,7 @@ use App\Services\Client\Traits\HandlesOrderRecords;
 use App\Services\Client\Traits\ValidatesServiceTime;
 use App\Services\Client\Traits\CalculatesOrderAmounts;
 use App\Models\CoachStatistic;
+use App\Models\FinanceRecord;
 
 readonly class OrderService
 {
@@ -927,24 +928,116 @@ readonly class OrderService
      */
     private function processCancelRefund(Order $order, array $refundAmounts): void
     {
-        // 处理余额退款
+        // 1. 处理余额退款
         if ($refundAmounts['balance_refund'] > 0) {
             $this->processBalanceCancelRefund($order, $refundAmounts['balance_refund']);
+
+            // 记录余额退款支出
+            FinanceRecord::create([
+                'owner_type' => 'platform',
+                'order_id' => $order->id,
+                'type' => 'expense',
+                'business_type' => 'refund',
+                'amount' => $refundAmounts['balance_refund'],
+                'payment_type' => 'balance',
+                'user_id' => $order->user_id,
+                'remark' => '订单取消余额退款'
+            ]);
         }
 
-        // 处理支付退款
+        // 2. 处理支付退款
         if ($refundAmounts['payment_refund'] > 0) {
             $this->processPaymentCancelRefund($order, $refundAmounts['payment_refund']);
+
+            // 记录支付退款支出
+            FinanceRecord::create([
+                'owner_type' => 'platform',
+                'order_id' => $order->id,
+                'type' => 'expense',
+                'business_type' => 'refund',
+                'amount' => $refundAmounts['payment_refund'],
+                'payment_type' => 'wechat',
+                'user_id' => $order->user_id,
+                'remark' => '订单取消微信支付退款'
+            ]);
         }
 
-        // 创建退款记录
+        // 3. 记录平台路费收入
+        if ($refundAmounts['platform_traffic_fee'] > 0) {
+            FinanceRecord::create([
+                'owner_type' => 'platform',
+                'order_id' => $order->id,
+                'type' => 'income',
+                'business_type' => 'traffic_fee',
+                'amount' => $refundAmounts['platform_traffic_fee'],
+                'user_id' => $order->user_id,
+                'coach_id' => $order->coach_id,
+                'remark' => '订单取消平台路费分成'
+            ]);
+        }
+
+        // 4. 记录平台违约金收入
+        if ($refundAmounts['platform_penalty'] > 0) {
+            FinanceRecord::create([
+                'owner_type' => 'platform',
+                'order_id' => $order->id,
+                'type' => 'income',
+                'business_type' => 'penalty',
+                'amount' => $refundAmounts['platform_penalty'],
+                'user_id' => $order->user_id,
+                'coach_id' => $order->coach_id,
+                'remark' => '订单取消违约金'
+            ]);
+        }
+
+        // 5. 如果有代理商,记录代理商收入
+        if ($order->agent_id && ($refundAmounts['agent_traffic_fee'] > 0 || $refundAmounts['agent_penalty'] > 0)) {
+            // 记录代理商路费分成
+            if ($refundAmounts['agent_traffic_fee'] > 0) {
+                FinanceRecord::create([
+                    'owner_type' => 'agent',
+                    'agent_id' => $order->agent_id,
+                    'order_id' => $order->id,
+                    'type' => 'income',
+                    'business_type' => 'traffic_fee',
+                    'amount' => $refundAmounts['agent_traffic_fee'],
+                    'user_id' => $order->user_id,
+                    'coach_id' => $order->coach_id,
+                    'region_code' => $order->region_code,
+                    'remark' => '订单取消代理商路费分成'
+                ]);
+            }
+
+            // 记录代理商违约金分成
+            if ($refundAmounts['agent_penalty'] > 0) {
+                FinanceRecord::create([
+                    'owner_type' => 'agent',
+                    'agent_id' => $order->agent_id,
+                    'order_id' => $order->id,
+                    'type' => 'income',
+                    'business_type' => 'penalty',
+                    'amount' => $refundAmounts['agent_penalty'],
+                    'user_id' => $order->user_id,
+                    'coach_id' => $order->coach_id,
+                    'region_code' => $order->region_code,
+                    'remark' => '订单取消代理商违约金分成'
+                ]);
+            }
+        }
+
+        // 6. 创建退款记录
         $order->refundRecords()->create([
             'total_refund_amount' => $refundAmounts['total_refund'],
             'balance_refund_amount' => $refundAmounts['balance_refund'],
             'payment_refund_amount' => $refundAmounts['payment_refund'],
             'penalty_amount' => $refundAmounts['penalty_amount'],
+            'coach_fee' => $refundAmounts['coach_fee'],
+            'platform_traffic_fee' => $refundAmounts['platform_traffic_fee'],
+            'platform_penalty' => $refundAmounts['platform_penalty'],
+            'refund_no' => $this->generateRefundNo($order),
             'state' => 'success',
             'remark' => '订单取消退款',
+            'refund_time' => now()
         ]);
     }
 
@@ -3002,4 +3095,27 @@ readonly class OrderService
             );
         }
     }
+
+    /**
+     * 生成退款单号
+     * 格式:RF + 年月日时分秒 + 订单ID后4位 + 4位随机数
+     * 示例:RF202403151428120001RAND
+     *
+     * @param Order $order 订单对象
+     * @return string 退款单号
+     */
+    private function generateRefundNo(Order $order): string
+    {
+        // 获取时间戳
+        $timestamp = now()->format('YmdHis');
+
+        // 获取订单ID后4位,不足4位前面补0
+        $orderIdSuffix = str_pad(substr($order->id, -4), 4, '0', STR_PAD_LEFT);
+
+        // 生成4位随机数
+        $random = str_pad(random_int(0, 9999), 4, '0', STR_PAD_LEFT);
+
+        // 组合退款单号:前缀 + 时间戳 + 订单ID后缀 + 随机数
+        return "RF{$timestamp}{$orderIdSuffix}{$random}";
+    }
 }