Просмотр исходного кода

refactor(AppGame): 优化商店购买逻辑和代码结构

-调整代码格式和缩进,提高可读性
-优化消耗组和奖励组的处理逻辑
- 在消耗组和奖励组处理中添加数量参数
- 优化日志记录格式
notfff 6 месяцев назад
Родитель
Сommit
146cafa667

+ 2 - 0
AiWork/WORK2.md

@@ -80,3 +80,5 @@ URS团队收益记录表 扩展,增加 :‘产生收益的农场用户id’
 农场模块,增加农场配置,先规划文档到 农场模块/Docs
 
  返回数据 ResponsePromotionInfo 增加了 star_level ,修改handler
+
+

+ 180 - 0
app/Module/Game/Logics/ConsumeProcessors/CurrencyConsume.php

@@ -0,0 +1,180 @@
+<?php
+
+namespace App\Module\Game\Logics\ConsumeProcessors;
+
+use App\Module\Fund\Enums\LOG_TYPE as FUND_LOG_TYPE;
+use App\Module\Fund\Logic\User as FundLogic;
+use App\Module\Game\Models\GameConsumeItem;
+use UCore\Dto\Res;
+
+class CurrencyConsume
+{
+
+    /**
+     * 检查币种消耗
+     *
+     * 注意:这里的target_id指向fund_currency表的id(币种ID)
+     * 这个方法会检查用户所有与该币种相关的账户,并计算总余额
+     *
+     * @param int $userId 用户ID
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
+     * @return array 检查结果
+     */
+    public static function checkCurrencyConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): array
+    {
+        $currencyId = $consumeItem->target_id;
+        $amount     = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
+
+        try {
+            // 获取该币种的所有账户种类
+            $fundConfigs = \App\Module\Fund\Models\FundConfigModel::where('currency_id', $currencyId)->get();
+
+            if ($fundConfigs->isEmpty()) {
+                return [
+                    'success'     => false,
+                    'message'     => "币种不存在或没有关联的账户种类",
+                    'currency_id' => $currencyId
+                ];
+            }
+
+            // 获取用户所有与该币种相关的账户
+            $fundConfigIds = $fundConfigs->pluck('id')->toArray();
+            $accounts      = \App\Module\Fund\Models\FundModel::where('user_id', $userId)
+                ->whereIn('fund_id', $fundConfigIds)
+                ->get();
+
+            if ($accounts->isEmpty()) {
+                return [
+                    'success'     => false,
+                    'message'     => "用户没有该币种的账户",
+                    'currency_id' => $currencyId
+                ];
+            }
+
+            // 计算总余额
+            $totalBalance = $accounts->sum('balance');
+
+            // 检查余额是否足够
+            if ($totalBalance < $amount) {
+                return [
+                    'success'     => false,
+                    'message'     => "币种总余额不足,需要 {$amount},实际 {$totalBalance}",
+                    'currency_id' => $currencyId,
+                    'required'    => $amount,
+                    'actual'      => $totalBalance
+                ];
+            }
+
+            return [
+                'success'     => true,
+                'message'     => '币种总余额足够',
+                'currency_id' => $currencyId,
+                'required'    => $amount,
+                'actual'      => $totalBalance,
+                'accounts'    => $accounts->toArray()
+            ];
+        } catch (\Exception $e) {
+            return [
+                'success'     => false,
+                'message'     => '检查币种消耗异常: ' . $e->getMessage(),
+                'currency_id' => $currencyId
+            ];
+        }
+    }
+
+    public static function process(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId,$multiplier): Res
+    {
+
+        // todo 需要优化,迁移到Fund中
+        $currencyId      = $consumeItem->target_id;
+        $amountToConsume = $consumeItem->quantity * $multiplier; // 使用倍数计算实际消耗金额
+
+        try {
+            // 先检查是否有足够的余额(使用相同的倍数)
+            $checkResult = self::checkCurrencyConsume($userId, $consumeItem, $multiplier);
+            if (!$checkResult['success']) {
+                return $checkResult;
+            }
+
+            // 获取该币种的所有账户种类
+            $fundConfigs   = \App\Module\Fund\Models\FundConfigModel::where('currency_id', $currencyId)->get();
+            $fundConfigIds = $fundConfigs->pluck('id')->toArray();
+
+            // 获取用户所有与该币种相关的账户
+            $accounts = \App\Module\Fund\Models\FundModel::where('user_id', $userId)
+                ->whereIn('fund_id', $fundConfigIds)
+                ->orderBy('fund_id') // 按账户种类ID排序,通常可用账户ID较小
+                ->get();
+
+            // 验证事务是否已开启(由调用者负责事务管理)
+            \UCore\Db\Helper::check_tr();
+
+            $remainingAmount  = $amountToConsume;
+            $consumedAccounts = [];
+
+            // 依次从各个账户中扣除
+            foreach ($accounts as $account) {
+                if ($remainingAmount <= 0) {
+                    break;
+                }
+
+                $accountBalance = $account->balance;
+                $amountToDeduct = min($accountBalance, $remainingAmount);
+
+                if ($amountToDeduct > 0) {
+                    // 构建备注
+                    $remark = "币种消耗:{$currencyId},消耗组:{$consumeItem->group_id},来源:{$source}";
+                    if ($sourceId > 0) {
+                        $remark .= ",ID:{$sourceId}";
+                    }
+                    if ($multiplier != 1.0) {
+                        $remark .= ",倍数:{$multiplier}";
+                    }
+
+                    // 从当前账户扣除
+                    $result = FundLogic::handle(
+                        $userId,
+                        $account->fund_id->value,
+                        -$amountToDeduct, // 负数表示消耗
+                        FUND_LOG_TYPE::TRADE,
+                        $sourceId,
+                        $remark
+                    );
+
+                    if ($result !== true) {
+                        return [
+                            'success'        => false,
+                            'message'        => is_string($result) ? $result : "从账户 {$account->fund_id} 扣除失败",
+                            'currency_id'    => $currencyId,
+                            'fund_config_id' => $account->fund_id,
+                            'amount'         => $amountToDeduct
+                        ];
+                    }
+
+                    $consumedAccounts[] = [
+                        'fund_config_id' => $account->fund_id,
+                        'amount'         => $amountToDeduct
+                    ];
+
+                    $remainingAmount -= $amountToDeduct;
+                }
+            }
+
+            return [
+                'success'           => true,
+                'message'           => '币种消耗成功',
+                'currency_id'       => $currencyId,
+                'amount'            => $amountToConsume,
+                'consumed_accounts' => $consumedAccounts
+            ];
+        } catch (\Exception $e) {
+            return [
+                'success'     => false,
+                'message'     => '币种消耗异常: ' . $e->getMessage(),
+                'currency_id' => $currencyId,
+                'amount'      => $amountToConsume
+            ];
+        }
+    }
+}

+ 106 - 0
app/Module/Game/Logics/ConsumeProcessors/FundConfigConsume.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace App\Module\Game\Logics\ConsumeProcessors;
+
+use App\Module\Fund\Enums\LOG_TYPE as FUND_LOG_TYPE;
+use App\Module\Fund\Logic\User as FundLogic;
+use App\Module\Game\Models\GameConsumeItem;
+use UCore\Dto\Res;
+
+class FundConfigConsume
+{
+
+
+    /**
+     * 检查账户种类消耗
+     *
+     * 注意:这里的target_id指向fund_config表的id(账户种类ID)
+     *
+     * @param int $userId 用户ID
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
+     * @return Res 检查结果
+     */
+    public static function checkFundConfigConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
+    {
+        $fundConfigId = $consumeItem->target_id;
+        $amount       = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
+
+        // 获取用户账户
+        $account = FundLogic::get_account($userId, $fundConfigId);
+
+        // 检查账户是否存在
+        if ($account === false) {
+            return Res::error("用户没有该账户种类", [
+                'fund_config_id' => $fundConfigId
+            ]);
+        }
+
+        // 检查余额是否足够
+        if ($account->balance < $amount) {
+            return Res::error("账户余额不足,需要 {$amount},实际 {$account->balance}", [
+                'fund_config_id' => $fundConfigId,
+                'required'       => $amount,
+                'actual'         => $account->balance
+            ]);
+        }
+
+        return Res::success('账户余额足够', [
+            'fund_config_id' => $fundConfigId,
+            'required'       => $amount,
+            'actual'         => $account->balance
+        ]);
+    }
+
+    /**
+     * 执行账户种类消耗
+     *
+     * 注意:这里的target_id指向fund_config表的id(账户种类ID)
+     *
+     * @param int $userId 用户ID
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @param string $source 消耗来源
+     * @param int $sourceId 消耗来源ID
+     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
+     * @return Res 执行结果
+     */
+    public static function process(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId,$multiplier): Res
+    {
+
+        $fundConfigId = $consumeItem->target_id;
+        $amount       = -($consumeItem->quantity * $multiplier); // 使用倍数计算实际消耗金额,负数表示消耗
+
+        // 构建备注
+        $remark = "消耗组:{$consumeItem->group_id},来源:{$source}";
+        if ($sourceId > 0) {
+            $remark .= ",ID:{$sourceId}";
+        }
+        if ($multiplier != 1.0) {
+            $remark .= ",倍数:{$multiplier}";
+        }
+
+        // 消耗账户资金
+        $result = FundLogic::handle(
+            $userId,
+            $fundConfigId,
+            $amount,
+            FUND_LOG_TYPE::TRADE, // 使用TRADE类型,因为CONSUME可能不存在
+            $sourceId,
+            $remark
+        );
+
+        if ($result !== true) {
+            $errorMessage = is_string($result) ? $result : '账户资金消耗失败';
+
+            return Res::error($errorMessage, [
+                'fund_config_id' => $fundConfigId,
+                'amount'         => abs($amount)
+            ]);
+        }
+
+        return Res::success('账户资金消耗成功', [
+            'fund_config_id' => $fundConfigId,
+            'amount'         => abs($amount)
+        ]);
+    }
+}

+ 195 - 0
app/Module/Game/Logics/ConsumeProcessors/FundConfigsConsume.php

@@ -0,0 +1,195 @@
+<?php
+
+namespace App\Module\Game\Logics\ConsumeProcessors;
+
+use App\Module\Fund\Enums\LOG_TYPE as FUND_LOG_TYPE;
+use App\Module\Fund\Logic\User as FundLogic;
+use App\Module\Game\Models\GameConsumeItem;
+use UCore\Dto\Res;
+
+class FundConfigsConsume
+{
+
+    /**
+     * 检查多账户种类消耗
+     *
+     * 注意:这里的target_id指向fund_config表的id(主账户种类ID),
+     * extra_data中存储多个账户种类ID的数组,按照顺序依次消耗
+     *
+     * @param int $userId 用户ID
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
+     * @return Res 检查结果
+     */
+    public static function checkFundConfigsConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
+    {
+        $amount = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
+
+        // 获取账户种类ID列表
+        $fundConfigIds = self::getFundConfigIds($consumeItem);
+
+        if (empty($fundConfigIds)) {
+            return Res::error("多账户种类配置错误:未找到有效的账户种类ID", [
+                'fund_config_ids' => []
+            ]);
+        }
+
+        // 检查每个账户的余额
+        $totalBalance = 0;
+        $accountBalances = [];
+
+        foreach ($fundConfigIds as $fundConfigId) {
+            // 获取用户账户
+            $account = FundLogic::get_account($userId, $fundConfigId);
+
+            if ($account === false) {
+                // 如果某个账户不存在,余额为0
+                $accountBalances[$fundConfigId] = 0;
+            } else {
+                $accountBalances[$fundConfigId] = $account->balance;
+                $totalBalance += $account->balance;
+            }
+        }
+
+        // 检查总余额是否足够
+        if ($totalBalance < $amount) {
+            return Res::error("多账户种类总余额不足,需要 {$amount},实际 {$totalBalance}", [
+                'fund_config_ids' => $fundConfigIds,
+                'required'        => $amount,
+                'actual'          => $totalBalance,
+                'account_balances' => $accountBalances
+            ]);
+        }
+
+        return Res::success('多账户种类总余额足够', [
+            'fund_config_ids'  => $fundConfigIds,
+            'required'         => $amount,
+            'actual'           => $totalBalance,
+            'account_balances' => $accountBalances
+        ]);
+    }
+
+    public static function process(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId,$multiplier): Res
+    {
+
+        $amountToConsume = $consumeItem->quantity * $multiplier; // 使用倍数计算实际消耗金额
+
+        // 获取账户种类ID列表
+        $fundConfigIds = self::getFundConfigIds($consumeItem);
+
+        if (empty($fundConfigIds)) {
+            return Res::error("多账户种类配置错误:未找到有效的账户种类ID", [
+                'fund_config_ids' => []
+            ]);
+        }
+
+        // 先检查是否有足够的余额(使用相同的倍数)
+        $checkResult = self::checkFundConfigsConsume($userId, $consumeItem, $multiplier);
+        if (!$checkResult->success) {
+            return $checkResult;
+        }
+
+        try {
+            // 验证事务是否已开启(由调用者负责事务管理)
+            \UCore\Db\Helper::check_tr();
+
+            $remainingAmount = $amountToConsume;
+            $consumedAccounts = [];
+
+            // 按照配置的顺序依次从各个账户中扣除
+            foreach ($fundConfigIds as $fundConfigId) {
+                if ($remainingAmount <= 0) {
+                    break;
+                }
+
+                // 获取用户账户
+                $account = FundLogic::get_account($userId, $fundConfigId);
+
+                if ($account === false || $account->balance <= 0) {
+                    // 账户不存在或余额为0,跳过
+                    continue;
+                }
+
+                $accountBalance = $account->balance;
+                $amountToDeduct = min($accountBalance, $remainingAmount);
+
+                if ($amountToDeduct > 0) {
+                    // 构建备注
+                    $remark = "多账户消耗组:{$consumeItem->group_id},来源:{$source}";
+                    if ($sourceId > 0) {
+                        $remark .= ",ID:{$sourceId}";
+                    }
+                    if ($multiplier != 1.0) {
+                        $remark .= ",倍数:{$multiplier}";
+                    }
+
+                    // 从当前账户扣除
+                    $result = FundLogic::handle(
+                        $userId,
+                        $fundConfigId,
+                        -$amountToDeduct, // 负数表示消耗
+                        FUND_LOG_TYPE::TRADE,
+                        $sourceId,
+                        $remark
+                    );
+
+                    if ($result !== true) {
+                        $errorMessage = is_string($result) ? $result : "从账户 {$fundConfigId} 扣除失败";
+                        return Res::error($errorMessage, [
+                            'fund_config_ids' => $fundConfigIds,
+                            'fund_config_id'  => $fundConfigId,
+                            'amount'          => $amountToDeduct
+                        ]);
+                    }
+
+                    $consumedAccounts[] = [
+                        'fund_config_id' => $fundConfigId,
+                        'amount'         => $amountToDeduct
+                    ];
+
+                    $remainingAmount -= $amountToDeduct;
+                }
+            }
+
+            return Res::success('多账户种类消耗成功', [
+                'fund_config_ids'  => $fundConfigIds,
+                'amount'           => $amountToConsume,
+                'consumed_accounts' => $consumedAccounts
+            ]);
+        } catch (\Exception $e) {
+            return Res::error('多账户种类消耗异常: ' . $e->getMessage(), [
+                'fund_config_ids' => $fundConfigIds,
+                'amount'          => $amountToConsume
+            ]);
+        }
+    }
+
+    /**
+     * 获取消耗项的账户种类ID列表
+     *
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @return array 账户种类ID列表
+     */
+    protected static function getFundConfigIds(GameConsumeItem $consumeItem): array
+    {
+        $fundConfigIds = [];
+
+        // 首先添加主账户种类ID(target_id)
+        if ($consumeItem->target_id > 0) {
+            $fundConfigIds[] = $consumeItem->target_id;
+        }
+
+        // 然后从extra_data中获取额外的账户种类ID
+        if (!empty($consumeItem->extra_data) && is_array($consumeItem->extra_data)) {
+            if (isset($consumeItem->extra_data['fund_config_ids']) && is_array($consumeItem->extra_data['fund_config_ids'])) {
+                foreach ($consumeItem->extra_data['fund_config_ids'] as $id) {
+                    if (is_numeric($id) && $id > 0 && !in_array($id, $fundConfigIds)) {
+                        $fundConfigIds[] = (int)$id;
+                    }
+                }
+            }
+        }
+
+        return $fundConfigIds;
+    }
+}

+ 93 - 0
app/Module/Game/Logics/ConsumeProcessors/ItemConsume.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Module\Game\Logics\ConsumeProcessors;
+
+use App\Module\Game\Models\GameConsumeItem;
+use App\Module\GameItems\Services\ItemService;
+use UCore\Dto\Res;
+
+class ItemConsume
+{
+
+
+
+
+    /**
+     * 检查物品消耗
+     *
+     * @param int $userId 用户ID
+     * @param GameConsumeItem $consumeItem 消耗项
+     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
+     * @return Res 检查结果
+     */
+    public static function checkItemConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
+    {
+        $itemId   = $consumeItem->target_id;
+        $quantity = ceil($consumeItem->quantity * $multiplier); // 使用倍数计算所需数量,向上取整
+
+        // 获取用户物品
+        $userItems = ItemService::getUserItems($userId, [ 'item_id' => $itemId ]);
+
+        // 计算用户拥有的物品总数
+        $totalQuantity = 0;
+        foreach ($userItems as $userItem) {
+            $totalQuantity += $userItem->quantity;
+        }
+
+        // 检查数量是否足够
+        if ($totalQuantity < $quantity) {
+            return Res::error("物品 $itemId 数量不足,需要 {$quantity},实际 {$totalQuantity}", [
+                'item_id'  => $itemId,
+                'required' => $quantity,
+                'actual'   => $totalQuantity
+            ]);
+        }
+
+        return Res::success('物品数量足够', [
+            'item_id'  => $itemId,
+            'required' => $quantity,
+            'actual'   => $totalQuantity
+        ]);
+    }
+
+    /**
+     * 物品消耗执行
+     *
+     * @param int $userId
+     * @param GameConsumeItem $consumeItem
+     * @param string $source
+     * @param int $sourceId
+     * @param $multiplier
+     * @return Res
+     * @throws \Exception
+     */
+    public static function process(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId,$multiplier): Res
+    {
+
+        $itemId   = $consumeItem->target_id;
+        $quantity = ceil($consumeItem->quantity * $multiplier); // 使用倍数计算实际消耗数量,向上取整
+
+        // 消耗物品
+        $result = ItemService::consumeItem($userId, $itemId, null, $quantity, [
+            'source_type' => $source,
+            'source_id'   => $sourceId,
+            'details'     => [
+                'consume_item_id'  => $consumeItem->id,
+                'consume_group_id' => $consumeItem->group_id,
+                'multiplier'       => $multiplier // 记录倍数信息
+            ]
+        ]);
+
+        if (!$result['success']) {
+            return Res::error($result['message'] ?? '物品消耗失败', [
+                'item_id'  => $itemId,
+                'quantity' => $quantity
+            ]);
+        }
+
+        return Res::success('物品消耗成功', [
+            'item_id'  => $itemId,
+            'quantity' => $quantity
+        ]);
+    }
+}

+ 100 - 0
app/Module/Game/Logics/ConsumeProcessors/ProcessorDispatcher.php

@@ -0,0 +1,100 @@
+<?php
+
+namespace App\Module\Game\Logics\ConsumeProcessors;
+
+use App\Module\Game\Dtos\ConsumeItemDto;
+use App\Module\Game\Dtos\RewardItemDto;
+use App\Module\Game\Enums\CONSUME_TYPE;
+use App\Module\Game\Enums\REWARD_TYPE;
+use App\Module\Game\Logics\RewardProcessors\CurrencyRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\FarmShrineRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\FundConfigRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\ItemRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\OtherRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\PetEnergyRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\PetExpRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\PetPowerRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\PetRewardProcessor;
+use App\Module\Game\Logics\RewardProcessors\SkinRewardProcessor;
+use App\Module\Game\Models\GameConsumeItem;
+use App\Module\Game\Services\ConsumeService;
+use Exception;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 奖励处理器分发器
+ *
+ * 根据奖励类型分发到对应的处理器进行处理
+ */
+class ProcessorDispatcher
+{
+
+    /**
+     * 处理单个奖励项
+     *
+     * @param int $userId 用户ID
+     * @param RewardItemDto $item 奖励项
+     * @param string $sourceType 来源类型
+     * @param int $sourceId 来源ID
+     * @return void
+     * @throws Exception
+     */
+    public static function process(int $userId, GameConsumeItem $consumeItem, string $sourceType, int $sourceId, $multiplier): array
+    {
+
+        switch ($consumeItem->consume_type) {
+            case CONSUME_TYPE::ITEM->value:
+                $res = ItemConsume::process($userId, $consumeItem, $sourceType, $sourceId, $multiplier);
+
+
+                // 将 Res 对象转换为数组格式
+                $result = [
+                    'success'  => $res->success,
+                    'message'  => $res->message,
+                    'item_id'  => $res->data['item_id'] ?? null,
+                    'quantity' => $res->data['quantity'] ?? null
+                ];
+                break;
+
+            case CONSUME_TYPE::FUND_CONFIG->value:
+                $res = FundConfigConsume::process($userId, $consumeItem, $sourceType, $sourceId, $multiplier);
+
+
+                // 将 Res 对象转换为数组格式
+                $result = [
+                    'success'        => $res->success,
+                    'message'        => $res->message,
+                    'fund_config_id' => $res->data['fund_config_id'] ?? null,
+                    'amount'         => $res->data['amount'] ?? null
+                ];
+                break;
+
+            case CONSUME_TYPE::CURRENCY->value:
+                $result = FundConfigConsume::process($userId, $consumeItem, $sourceType, $sourceId, $multiplier);
+
+
+                break;
+            case CONSUME_TYPE::FUND_CONFIGS->value:
+                $res = FundConfigsConsume::process($userId, $consumeItem, $sourceType, $sourceId, $multiplier);
+
+
+                // 将 Res 对象转换为数组格式
+                $result = [
+                    'success'         => $res->success,
+                    'message'         => $res->message,
+                    'fund_config_ids' => $res->data['fund_config_ids'] ?? null,
+                    'amount'          => $res->data['amount'] ?? null
+                ];
+                break;
+
+            default:
+                $result = [
+                    'success' => false,
+                    'message' => "不支持的消耗类型: {$consumeItem->consume_type}"
+                ];
+        }
+
+        return $result;
+    }
+
+}

+ 2 - 1
app/Module/Game/Logics/UserLogCollectors/ItemLogCollector.php

@@ -105,6 +105,7 @@ class ItemLogCollector extends BaseLogCollector
             }
 
             // 根据操作类型选择合适的source_type
+            dump($record);
             $sourceType = $this->getSourceTypeByOperation($record->source_type);
 
             return $this->createUserLogDataWithSourceType(
@@ -402,7 +403,7 @@ class ItemLogCollector extends BaseLogCollector
         // 可以添加更多过滤条件
         // 例如:跳过某些物品类型
         // 例如:跳过临时物品
-        
+
         return true;
     }
 

+ 14 - 657
app/Module/Game/Services/ConsumeService.php

@@ -5,6 +5,12 @@ namespace App\Module\Game\Services;
 use App\Module\Fund\Logic\User as FundLogic;
 use App\Module\Fund\Enums\LOG_TYPE as FUND_LOG_TYPE;
 use App\Module\Game\Enums\CONSUME_TYPE;
+use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
+use App\Module\Game\Logics\ConsumeProcessors\CurrencyConsume;
+use App\Module\Game\Logics\ConsumeProcessors\FundConfigConsume;
+use App\Module\Game\Logics\ConsumeProcessors\FundConfigsConsume;
+use App\Module\Game\Logics\ConsumeProcessors\ItemConsume;
+use App\Module\Game\Logics\ConsumeProcessors\ProcessorDispatcher;
 use App\Module\Game\Models\GameConsumeGroup;
 use App\Module\Game\Models\GameConsumeItem;
 use App\Module\Game\Dtos\ConsumeGroupDto;
@@ -132,7 +138,7 @@ class ConsumeService
      * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
      * @return Res 执行结果
      */
-    public static function executeConsume(int $userId, $consumeGroupCode, string $source, int $sourceId = 0, $check = true, float $multiplier = 1.0): Res
+    public static function executeConsume(int $userId, $consumeGroupCode, REWARD_SOURCE_TYPE $source, int $sourceId = 0, $check = true, float $multiplier = 1.0): Res
     {
         if ($check) {
             // 先检查是否满足消耗条件(使用相同的倍数)
@@ -174,7 +180,8 @@ class ConsumeService
 
             // 执行每个消耗项
             foreach ($consumeItems as $item) {
-                $consumeResult = self::executeConsumeItem($userId, $item, $source, $sourceId, $multiplier);
+                $consumeResult = ProcessorDispatcher::process($userId, $item, $source, $sourceId, $multiplier);
+
                 if (!$consumeResult['success']) {
                     return Res::error($consumeResult['message'], $consumeResult);
                 }
@@ -213,7 +220,7 @@ class ConsumeService
     {
         switch ($consumeItem->consume_type) {
             case CONSUME_TYPE::ITEM->value:
-                $result = self::checkItemConsume($userId, $consumeItem, $multiplier);
+                $result = ItemConsume::checkItemConsume($userId,$consumeItem,$multiplier);
 
                 // 将 Res 对象转换为数组格式
                 return [
@@ -225,7 +232,7 @@ class ConsumeService
                 ];
 
             case CONSUME_TYPE::FUND_CONFIG->value:
-                $result = self::checkFundConfigConsume($userId, $consumeItem, $multiplier);
+                $result = FundConfigConsume::checkFundConfigConsume($userId,$consumeItem,$multiplier);
 
                 // 将 Res 对象转换为数组格式
                 return [
@@ -237,10 +244,11 @@ class ConsumeService
                 ];
 
             case CONSUME_TYPE::CURRENCY->value:
-                return self::checkCurrencyConsume($userId, $consumeItem, $multiplier);
+                return  CurrencyConsume::checkCurrencyConsume($userId,$consumeItem,$multiplier);
+
 
             case CONSUME_TYPE::FUND_CONFIGS->value:
-                $result = self::checkFundConfigsConsume($userId, $consumeItem, $multiplier);
+                $result =  FundConfigsConsume::checkFundConfigsConsume($userId,$consumeItem,$multiplier);
 
                 // 将 Res 对象转换为数组格式
                 return [
@@ -259,656 +267,5 @@ class ConsumeService
         }
     }
 
-    /**
-     * 执行单个消耗项
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param string $source 消耗来源
-     * @param int $sourceId 消耗来源ID
-     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
-     * @return array 执行结果
-     */
-    protected static function executeConsumeItem(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId, float $multiplier = 1.0): array
-    {
-        switch ($consumeItem->consume_type) {
-            case CONSUME_TYPE::ITEM->value:
-                $result = self::executeItemConsume($userId, $consumeItem, $source, $sourceId, $multiplier);
-
-                // 将 Res 对象转换为数组格式
-                return [
-                    'success'  => $result->success,
-                    'message'  => $result->message,
-                    'item_id'  => $result->data['item_id'] ?? null,
-                    'quantity' => $result->data['quantity'] ?? null
-                ];
-
-            case CONSUME_TYPE::FUND_CONFIG->value:
-                $result = self::executeFundConfigConsume($userId, $consumeItem, $source, $sourceId, $multiplier);
-
-                // 将 Res 对象转换为数组格式
-                return [
-                    'success'        => $result->success,
-                    'message'        => $result->message,
-                    'fund_config_id' => $result->data['fund_config_id'] ?? null,
-                    'amount'         => $result->data['amount'] ?? null
-                ];
-
-            case CONSUME_TYPE::CURRENCY->value:
-                return self::executeCurrencyConsume($userId, $consumeItem, $source, $sourceId, $multiplier);
-
-            case CONSUME_TYPE::FUND_CONFIGS->value:
-                $result = self::executeFundConfigsConsume($userId, $consumeItem, $source, $sourceId, $multiplier);
-
-                // 将 Res 对象转换为数组格式
-                return [
-                    'success'         => $result->success,
-                    'message'         => $result->message,
-                    'fund_config_ids' => $result->data['fund_config_ids'] ?? null,
-                    'amount'          => $result->data['amount'] ?? null
-                ];
-
-            default:
-                return [
-                    'success' => false,
-                    'message' => "不支持的消耗类型: {$consumeItem->consume_type}"
-                ];
-        }
-    }
-
-    /**
-     * 检查物品消耗
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
-     * @return Res 检查结果
-     */
-    protected static function checkItemConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
-    {
-        $itemId   = $consumeItem->target_id;
-        $quantity = ceil($consumeItem->quantity * $multiplier); // 使用倍数计算所需数量,向上取整
-
-        // 获取用户物品
-        $userItems = ItemService::getUserItems($userId, [ 'item_id' => $itemId ]);
-
-        // 计算用户拥有的物品总数
-        $totalQuantity = 0;
-        foreach ($userItems as $userItem) {
-            $totalQuantity += $userItem->quantity;
-        }
-
-        // 检查数量是否足够
-        if ($totalQuantity < $quantity) {
-            return Res::error("物品 $itemId 数量不足,需要 {$quantity},实际 {$totalQuantity}", [
-                'item_id'  => $itemId,
-                'required' => $quantity,
-                'actual'   => $totalQuantity
-            ]);
-        }
-
-        return Res::success('物品数量足够', [
-            'item_id'  => $itemId,
-            'required' => $quantity,
-            'actual'   => $totalQuantity
-        ]);
-    }
-
-    /**
-     * 检查账户种类消耗
-     *
-     * 注意:这里的target_id指向fund_config表的id(账户种类ID)
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
-     * @return Res 检查结果
-     */
-    protected static function checkFundConfigConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
-    {
-        $fundConfigId = $consumeItem->target_id;
-        $amount       = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
-
-        // 获取用户账户
-        $account = FundLogic::get_account($userId, $fundConfigId);
-
-        // 检查账户是否存在
-        if ($account === false) {
-            return Res::error("用户没有该账户种类", [
-                'fund_config_id' => $fundConfigId
-            ]);
-        }
-
-        // 检查余额是否足够
-        if ($account->balance < $amount) {
-            return Res::error("账户余额不足,需要 {$amount},实际 {$account->balance}", [
-                'fund_config_id' => $fundConfigId,
-                'required'       => $amount,
-                'actual'         => $account->balance
-            ]);
-        }
-
-        return Res::success('账户余额足够', [
-            'fund_config_id' => $fundConfigId,
-            'required'       => $amount,
-            'actual'         => $account->balance
-        ]);
-    }
-
-    /**
-     * 检查代币账户消耗
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @return array 检查结果
-     */
-    protected static function checkFundConsume(int $userId, GameConsumeItem $consumeItem): array
-    {
-        $fundId = $consumeItem->target_id;
-        $amount = $consumeItem->quantity;
-
-        try {
-            // 获取用户代币账户
-            $fundService = new \App\Module\Fund\Services\FundService($userId, $fundId);
-            $account     = $fundService->getAccount();
-
-            // 检查账户是否存在
-            if (!$account) {
-                return [
-                    'success' => false,
-                    'message' => "用户没有该代币账户",
-                    'fund_id' => $fundId
-                ];
-            }
-
-            // 检查余额是否足够
-            $balance = $account->balance;
-            if ($balance < $amount) {
-                return [
-                    'success'  => false,
-                    'message'  => "代币账户余额不足,需要 {$amount},实际 {$balance}",
-                    'fund_id'  => $fundId,
-                    'required' => $amount,
-                    'actual'   => $balance
-                ];
-            }
-
-            return [
-                'success' => true,
-                'message' => '代币账户余额足够'
-            ];
-        } catch (\Exception $e) {
-            return [
-                'success' => false,
-                'message' => '检查代币账户异常: ' . $e->getMessage(),
-                'fund_id' => $fundId
-            ];
-        }
-    }
-
-    /**
-     * 执行物品消耗
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param string $source 消耗来源
-     * @param int $sourceId 消耗来源ID
-     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
-     * @return Res 执行结果
-     */
-    protected static function executeItemConsume(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId, float $multiplier = 1.0): Res
-    {
-        $itemId   = $consumeItem->target_id;
-        $quantity = ceil($consumeItem->quantity * $multiplier); // 使用倍数计算实际消耗数量,向上取整
-
-        // 消耗物品
-        $result = ItemService::consumeItem($userId, $itemId, null, $quantity, [
-            'source_type' => $source,
-            'source_id'   => $sourceId,
-            'details'     => [
-                'consume_item_id'  => $consumeItem->id,
-                'consume_group_id' => $consumeItem->group_id,
-                'multiplier'       => $multiplier // 记录倍数信息
-            ]
-        ]);
-
-        if (!$result['success']) {
-            return Res::error($result['message'] ?? '物品消耗失败', [
-                'item_id'  => $itemId,
-                'quantity' => $quantity
-            ]);
-        }
-
-        return Res::success('物品消耗成功', [
-            'item_id'  => $itemId,
-            'quantity' => $quantity
-        ]);
-    }
-
-    /**
-     * 执行账户种类消耗
-     *
-     * 注意:这里的target_id指向fund_config表的id(账户种类ID)
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param string $source 消耗来源
-     * @param int $sourceId 消耗来源ID
-     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
-     * @return Res 执行结果
-     */
-    protected static function executeFundConfigConsume(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId, float $multiplier = 1.0): Res
-    {
-        $fundConfigId = $consumeItem->target_id;
-        $amount       = -($consumeItem->quantity * $multiplier); // 使用倍数计算实际消耗金额,负数表示消耗
-
-        // 构建备注
-        $remark = "消耗组:{$consumeItem->group_id},来源:{$source}";
-        if ($sourceId > 0) {
-            $remark .= ",ID:{$sourceId}";
-        }
-        if ($multiplier != 1.0) {
-            $remark .= ",倍数:{$multiplier}";
-        }
-
-        // 消耗账户资金
-        $result = FundLogic::handle(
-            $userId,
-            $fundConfigId,
-            $amount,
-            FUND_LOG_TYPE::TRADE, // 使用TRADE类型,因为CONSUME可能不存在
-            $sourceId,
-            $remark
-        );
-
-        if ($result !== true) {
-            $errorMessage = is_string($result) ? $result : '账户资金消耗失败';
-
-            return Res::error($errorMessage, [
-                'fund_config_id' => $fundConfigId,
-                'amount'         => abs($amount)
-            ]);
-        }
-
-        return Res::success('账户资金消耗成功', [
-            'fund_config_id' => $fundConfigId,
-            'amount'         => abs($amount)
-        ]);
-    }
-
-    /**
-     * 检查币种消耗
-     *
-     * 注意:这里的target_id指向fund_currency表的id(币种ID)
-     * 这个方法会检查用户所有与该币种相关的账户,并计算总余额
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
-     * @return array 检查结果
-     */
-    protected static function checkCurrencyConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): array
-    {
-        $currencyId = $consumeItem->target_id;
-        $amount     = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
-
-        try {
-            // 获取该币种的所有账户种类
-            $fundConfigs = \App\Module\Fund\Models\FundConfigModel::where('currency_id', $currencyId)->get();
-
-            if ($fundConfigs->isEmpty()) {
-                return [
-                    'success'     => false,
-                    'message'     => "币种不存在或没有关联的账户种类",
-                    'currency_id' => $currencyId
-                ];
-            }
-
-            // 获取用户所有与该币种相关的账户
-            $fundConfigIds = $fundConfigs->pluck('id')->toArray();
-            $accounts      = \App\Module\Fund\Models\FundModel::where('user_id', $userId)
-                ->whereIn('fund_id', $fundConfigIds)
-                ->get();
-
-            if ($accounts->isEmpty()) {
-                return [
-                    'success'     => false,
-                    'message'     => "用户没有该币种的账户",
-                    'currency_id' => $currencyId
-                ];
-            }
-
-            // 计算总余额
-            $totalBalance = $accounts->sum('balance');
-
-            // 检查余额是否足够
-            if ($totalBalance < $amount) {
-                return [
-                    'success'     => false,
-                    'message'     => "币种总余额不足,需要 {$amount},实际 {$totalBalance}",
-                    'currency_id' => $currencyId,
-                    'required'    => $amount,
-                    'actual'      => $totalBalance
-                ];
-            }
-
-            return [
-                'success'     => true,
-                'message'     => '币种总余额足够',
-                'currency_id' => $currencyId,
-                'required'    => $amount,
-                'actual'      => $totalBalance,
-                'accounts'    => $accounts->toArray()
-            ];
-        } catch (\Exception $e) {
-            return [
-                'success'     => false,
-                'message'     => '检查币种消耗异常: ' . $e->getMessage(),
-                'currency_id' => $currencyId
-            ];
-        }
-    }
-
-    /**
-     * 执行币种消耗
-     *
-     * 注意:这里的target_id指向fund_currency表的id(币种ID)
-     * 这个方法会优先从用户的可用账户中扣除,如果不足则依次从其他账户扣除
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param string $source 消耗来源
-     * @param int $sourceId 消耗来源ID
-     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
-     * @return array 执行结果
-     */
-    protected static function executeCurrencyConsume(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId, float $multiplier = 1.0): array
-    {
-        // todo 需要优化,迁移到Fund中
-        $currencyId      = $consumeItem->target_id;
-        $amountToConsume = $consumeItem->quantity * $multiplier; // 使用倍数计算实际消耗金额
-
-        try {
-            // 先检查是否有足够的余额(使用相同的倍数)
-            $checkResult = self::checkCurrencyConsume($userId, $consumeItem, $multiplier);
-            if (!$checkResult['success']) {
-                return $checkResult;
-            }
-
-            // 获取该币种的所有账户种类
-            $fundConfigs   = \App\Module\Fund\Models\FundConfigModel::where('currency_id', $currencyId)->get();
-            $fundConfigIds = $fundConfigs->pluck('id')->toArray();
-
-            // 获取用户所有与该币种相关的账户
-            $accounts = \App\Module\Fund\Models\FundModel::where('user_id', $userId)
-                ->whereIn('fund_id', $fundConfigIds)
-                ->orderBy('fund_id') // 按账户种类ID排序,通常可用账户ID较小
-                ->get();
-
-            // 验证事务是否已开启(由调用者负责事务管理)
-            \UCore\Db\Helper::check_tr();
-
-            $remainingAmount  = $amountToConsume;
-            $consumedAccounts = [];
-
-            // 依次从各个账户中扣除
-            foreach ($accounts as $account) {
-                if ($remainingAmount <= 0) {
-                    break;
-                }
-
-                $accountBalance = $account->balance;
-                $amountToDeduct = min($accountBalance, $remainingAmount);
-
-                if ($amountToDeduct > 0) {
-                    // 构建备注
-                    $remark = "币种消耗:{$currencyId},消耗组:{$consumeItem->group_id},来源:{$source}";
-                    if ($sourceId > 0) {
-                        $remark .= ",ID:{$sourceId}";
-                    }
-                    if ($multiplier != 1.0) {
-                        $remark .= ",倍数:{$multiplier}";
-                    }
-
-                    // 从当前账户扣除
-                    $result = FundLogic::handle(
-                        $userId,
-                        $account->fund_id->value,
-                        -$amountToDeduct, // 负数表示消耗
-                        FUND_LOG_TYPE::TRADE,
-                        $sourceId,
-                        $remark
-                    );
-
-                    if ($result !== true) {
-                        return [
-                            'success'        => false,
-                            'message'        => is_string($result) ? $result : "从账户 {$account->fund_id} 扣除失败",
-                            'currency_id'    => $currencyId,
-                            'fund_config_id' => $account->fund_id,
-                            'amount'         => $amountToDeduct
-                        ];
-                    }
-
-                    $consumedAccounts[] = [
-                        'fund_config_id' => $account->fund_id,
-                        'amount'         => $amountToDeduct
-                    ];
-
-                    $remainingAmount -= $amountToDeduct;
-                }
-            }
-
-            return [
-                'success'           => true,
-                'message'           => '币种消耗成功',
-                'currency_id'       => $currencyId,
-                'amount'            => $amountToConsume,
-                'consumed_accounts' => $consumedAccounts
-            ];
-        } catch (\Exception $e) {
-            return [
-                'success'     => false,
-                'message'     => '币种消耗异常: ' . $e->getMessage(),
-                'currency_id' => $currencyId,
-                'amount'      => $amountToConsume
-            ];
-        }
-    }
-
-    /**
-     * 检查多账户种类消耗
-     *
-     * 注意:这里的target_id指向fund_config表的id(主账户种类ID),
-     * extra_data中存储多个账户种类ID的数组,按照顺序依次消耗
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param float $multiplier 倍数,用于验证几倍消耗,默认为1
-     * @return Res 检查结果
-     */
-    protected static function checkFundConfigsConsume(int $userId, GameConsumeItem $consumeItem, float $multiplier = 1.0): Res
-    {
-        $amount = $consumeItem->quantity * $multiplier; // 使用倍数计算所需金额
-
-        // 获取账户种类ID列表
-        $fundConfigIds = self::getFundConfigIds($consumeItem);
-
-        if (empty($fundConfigIds)) {
-            return Res::error("多账户种类配置错误:未找到有效的账户种类ID", [
-                'fund_config_ids' => []
-            ]);
-        }
-
-        // 检查每个账户的余额
-        $totalBalance = 0;
-        $accountBalances = [];
-
-        foreach ($fundConfigIds as $fundConfigId) {
-            // 获取用户账户
-            $account = FundLogic::get_account($userId, $fundConfigId);
-
-            if ($account === false) {
-                // 如果某个账户不存在,余额为0
-                $accountBalances[$fundConfigId] = 0;
-            } else {
-                $accountBalances[$fundConfigId] = $account->balance;
-                $totalBalance += $account->balance;
-            }
-        }
-
-        // 检查总余额是否足够
-        if ($totalBalance < $amount) {
-            return Res::error("多账户种类总余额不足,需要 {$amount},实际 {$totalBalance}", [
-                'fund_config_ids' => $fundConfigIds,
-                'required'        => $amount,
-                'actual'          => $totalBalance,
-                'account_balances' => $accountBalances
-            ]);
-        }
-
-        return Res::success('多账户种类总余额足够', [
-            'fund_config_ids'  => $fundConfigIds,
-            'required'         => $amount,
-            'actual'           => $totalBalance,
-            'account_balances' => $accountBalances
-        ]);
-    }
-
-    /**
-     * 执行多账户种类消耗
-     *
-     * 注意:这里的target_id指向fund_config表的id(主账户种类ID),
-     * extra_data中存储多个账户种类ID的数组,按照顺序依次消耗
-     *
-     * @param int $userId 用户ID
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @param string $source 消耗来源
-     * @param int $sourceId 消耗来源ID
-     * @param float $multiplier 倍数,用于执行几倍消耗,默认为1
-     * @return Res 执行结果
-     */
-    protected static function executeFundConfigsConsume(int $userId, GameConsumeItem $consumeItem, string $source, int $sourceId, float $multiplier = 1.0): Res
-    {
-        $amountToConsume = $consumeItem->quantity * $multiplier; // 使用倍数计算实际消耗金额
-
-        // 获取账户种类ID列表
-        $fundConfigIds = self::getFundConfigIds($consumeItem);
-
-        if (empty($fundConfigIds)) {
-            return Res::error("多账户种类配置错误:未找到有效的账户种类ID", [
-                'fund_config_ids' => []
-            ]);
-        }
-
-        // 先检查是否有足够的余额(使用相同的倍数)
-        $checkResult = self::checkFundConfigsConsume($userId, $consumeItem, $multiplier);
-        if (!$checkResult->success) {
-            return $checkResult;
-        }
-
-        try {
-            // 验证事务是否已开启(由调用者负责事务管理)
-            \UCore\Db\Helper::check_tr();
-
-            $remainingAmount = $amountToConsume;
-            $consumedAccounts = [];
-
-            // 按照配置的顺序依次从各个账户中扣除
-            foreach ($fundConfigIds as $fundConfigId) {
-                if ($remainingAmount <= 0) {
-                    break;
-                }
-
-                // 获取用户账户
-                $account = FundLogic::get_account($userId, $fundConfigId);
-
-                if ($account === false || $account->balance <= 0) {
-                    // 账户不存在或余额为0,跳过
-                    continue;
-                }
-
-                $accountBalance = $account->balance;
-                $amountToDeduct = min($accountBalance, $remainingAmount);
-
-                if ($amountToDeduct > 0) {
-                    // 构建备注
-                    $remark = "多账户消耗组:{$consumeItem->group_id},来源:{$source}";
-                    if ($sourceId > 0) {
-                        $remark .= ",ID:{$sourceId}";
-                    }
-                    if ($multiplier != 1.0) {
-                        $remark .= ",倍数:{$multiplier}";
-                    }
-
-                    // 从当前账户扣除
-                    $result = FundLogic::handle(
-                        $userId,
-                        $fundConfigId,
-                        -$amountToDeduct, // 负数表示消耗
-                        FUND_LOG_TYPE::TRADE,
-                        $sourceId,
-                        $remark
-                    );
-
-                    if ($result !== true) {
-                        $errorMessage = is_string($result) ? $result : "从账户 {$fundConfigId} 扣除失败";
-                        return Res::error($errorMessage, [
-                            'fund_config_ids' => $fundConfigIds,
-                            'fund_config_id'  => $fundConfigId,
-                            'amount'          => $amountToDeduct
-                        ]);
-                    }
-
-                    $consumedAccounts[] = [
-                        'fund_config_id' => $fundConfigId,
-                        'amount'         => $amountToDeduct
-                    ];
-
-                    $remainingAmount -= $amountToDeduct;
-                }
-            }
-
-            return Res::success('多账户种类消耗成功', [
-                'fund_config_ids'  => $fundConfigIds,
-                'amount'           => $amountToConsume,
-                'consumed_accounts' => $consumedAccounts
-            ]);
-        } catch (\Exception $e) {
-            return Res::error('多账户种类消耗异常: ' . $e->getMessage(), [
-                'fund_config_ids' => $fundConfigIds,
-                'amount'          => $amountToConsume
-            ]);
-        }
-    }
-
-    /**
-     * 获取消耗项的账户种类ID列表
-     *
-     * @param GameConsumeItem $consumeItem 消耗项
-     * @return array 账户种类ID列表
-     */
-    protected static function getFundConfigIds(GameConsumeItem $consumeItem): array
-    {
-        $fundConfigIds = [];
-
-        // 首先添加主账户种类ID(target_id)
-        if ($consumeItem->target_id > 0) {
-            $fundConfigIds[] = $consumeItem->target_id;
-        }
-
-        // 然后从extra_data中获取额外的账户种类ID
-        if (!empty($consumeItem->extra_data) && is_array($consumeItem->extra_data)) {
-            if (isset($consumeItem->extra_data['fund_config_ids']) && is_array($consumeItem->extra_data['fund_config_ids'])) {
-                foreach ($consumeItem->extra_data['fund_config_ids'] as $id) {
-                    if (is_numeric($id) && $id > 0 && !in_array($id, $fundConfigIds)) {
-                        $fundConfigIds[] = (int)$id;
-                    }
-                }
-            }
-        }
-
-        return $fundConfigIds;
-    }
 
 }