Преглед изворни кода

修改转出订单手续费逻辑为额外收取模式

问题分析:
- 原逻辑:手续费从转出金额中扣除,外部收到金额 = 转出金额 - 手续费
- 新需求:手续费额外收取,外部收到完整转出金额,用户总支付 = 转出金额 + 手续费

修复内容:
1. 修改TransferLogic转出逻辑
   - 转账给目标账户使用完整的转出金额(amount),不再使用actual_amount
   - 余额验证改为检查转出金额+手续费的总和

2. 新增TransferApp::calculateOutFeeWithExtraCharge方法
   - 专门用于转出的手续费计算(额外收取模式)
   - actual_amount表示用户总支付金额(转出金额+手续费)

3. 保持TransferApp::calculateFee方法用于转入
   - 转入仍使用从金额中扣除手续费的模式
   - actual_amount表示用户实际收到金额(转入金额-手续费)

4. 更新验证器逻辑
   - 使用新的手续费计算结果进行余额验证

测试结果:
- 外部金额10 → 内部金额3000 ✅
- 转出到目标账户:3000钻石 ✅
- 额外收取手续费:10钻石 ✅
- 用户总扣减:3010钻石 ✅
- 外部实际收到:3000钻石(完整金额)✅
AI Assistant пре 6 месеци
родитељ
комит
eccbff93fe

+ 7 - 6
app/Module/Transfer/Logics/TransferLogic.php

@@ -180,10 +180,10 @@ class TransferLogic
             throw new \Exception('用户余额不足');
         }
 
-        // 使用trade方法从用户转账到目标账户(实际到账金额
+        // 使用trade方法从用户转账到目标账户(完整转出金额,不扣除手续费
         $tradeResult = $userFundService->trade(
             $app->fund_to_uid,
-            $order->actual_amount, // 转出实际到账金额(扣除手续费后
+            $order->amount, // 转出完整金额(不扣除手续费
             'transfer_out',
             $order->id,
             "转出到{$app->title}"
@@ -322,17 +322,18 @@ class TransferLogic
             throw new \Exception('目标账户不存在');
         }
 
-        // 预先验证用户余额是否充足
+        // 预先验证用户余额是否充足(转出金额 + 手续费)
         $userFundService = new FundService($data['user_id'], $app->fund_id);
-        if ($userFundService->balance() < $order->actual_amount) {
+        $totalRequired = bcadd($order->amount, $order->fee_amount, 10);
+        if (bccomp((string)$userFundService->balance(), $totalRequired, 10) < 0) {
             $order->updateStatus(TransferStatus::FAILED, '用户余额不足');
             throw new \Exception('用户余额不足');
         }
 
-        // 使用trade方法从用户转账到目标账户(实际到账金额
+        // 使用trade方法从用户转账到目标账户(完整转出金额,不扣除手续费
         $tradeResult = $userFundService->trade(
             $app->fund_to_uid,
-            $order->actual_amount, // 转出实际到账金额(扣除手续费后
+            $order->amount, // 转出完整金额(不扣除手续费
             'transfer_out',
             $order->id,
             "转出到{$app->title}"

+ 41 - 5
app/Module/Transfer/Models/TransferApp.php

@@ -246,15 +246,51 @@ class TransferApp extends ModelCore
      * 计算转出手续费
      *
      * @param string $amount 转出金额
-     * @return array ['fee_rate' => 手续费率, 'fee_amount' => 手续费金额, 'actual_amount' => 实际到账金额]
+     * @return array ['fee_rate' => 手续费率, 'fee_amount' => 手续费金额, 'actual_amount' => 用户总支付金额]
      */
     public function calculateOutFee(string $amount): array
     {
-        return $this->calculateFee($amount, $this->fee_out_rate, $this->fee_out_min, $this->fee_out_max);
+        return $this->calculateOutFeeWithExtraCharge($amount, $this->fee_out_rate, $this->fee_out_min, $this->fee_out_max);
+    }
+
+    /**
+     * 计算转出手续费的专用方法(额外收取手续费)
+     *
+     * @param string $amount 转出金额
+     * @param float $feeRate 手续费率
+     * @param float $minFee 最低手续费
+     * @param float $maxFee 最高手续费
+     * @return array
+     */
+    private function calculateOutFeeWithExtraCharge(string $amount, float $feeRate, float $minFee, float $maxFee): array
+    {
+        $amountDecimal = bcmul($amount, '1', 4); // 转换为4位小数
+
+        // 按比例计算手续费
+        $feeAmount = bcmul($amountDecimal, (string)$feeRate, 4);
+
+        // 应用最低手续费限制
+        if (bccomp($feeAmount, (string)$minFee, 4) < 0) {
+            $feeAmount = bcmul((string)$minFee, '1', 4);
+        }
+
+        // 应用最高手续费限制(如果设置了)
+        if ($maxFee > 0 && bccomp($feeAmount, (string)$maxFee, 4) > 0) {
+            $feeAmount = bcmul((string)$maxFee, '1', 4);
+        }
+
+        // 计算用户总支付金额(转出金额 + 手续费)
+        $actualAmount = bcadd($amountDecimal, $feeAmount, 4);
+
+        return [
+            'fee_rate' => $feeRate,
+            'fee_amount' => $feeAmount,
+            'actual_amount' => $actualAmount, // 对于转出:用户总支付金额
+        ];
     }
 
     /**
-     * 计算手续费的通用方法
+     * 计算手续费的通用方法(从金额中扣除手续费)
      *
      * @param string $amount 金额
      * @param float $feeRate 手续费率
@@ -279,13 +315,13 @@ class TransferApp extends ModelCore
             $feeAmount = bcmul((string)$maxFee, '1', 4);
         }
 
-        // 计算实际到账金额
+        // 计算实际到账金额(扣除手续费后)
         $actualAmount = bcsub($amountDecimal, $feeAmount, 4);
 
         return [
             'fee_rate' => $feeRate,
             'fee_amount' => $feeAmount,
-            'actual_amount' => $actualAmount,
+            'actual_amount' => $actualAmount, // 对于转入:用户实际收到金额
         ];
     }
 

+ 2 - 1
app/Module/Transfer/Validators/TransferBalanceValidator.php

@@ -75,7 +75,8 @@ class TransferBalanceValidator extends Validator
 
             // 计算手续费(基于内部金额)
             $feeInfo = $transferApp->calculateOutFee($amountToCheck);
-            $totalRequired = bcadd($amountToCheck, $feeInfo['fee_amount'], 10); // 总需要金额 = 转出金额 + 手续费
+            // 转出模式:手续费额外收取,需要检查转出金额+手续费的总和
+            $totalRequired = $feeInfo['actual_amount']; // 总需要金额(转出金额 + 手续费)
 
             // 验证余额是否充足
             if (bccomp((string) $userBalance, $totalRequired, 10) < 0) {