Browse Source

重构条件组类型和消耗组类型处理逻辑,统一处理重复硬编码

- 创建ConditionTypeDescriptor统一条件类型描述器,集中处理所有条件类型的名称获取和描述生成逻辑
- 创建ConsumeTypeDescriptor统一消耗类型描述器,集中处理所有消耗类型的名称获取和描述生成逻辑
- 扩展CONDITION_TYPE和CONSUME_TYPE枚举,添加getTypeInfo方法提供详细的类型信息
- 重构GameConditionItem、GameConditionGroup相关模型和服务,使用统一的描述器替换重复的switch语句
- 重构GameConsumeItem、GameConsumeGroup相关模型和服务,使用统一的描述器替换重复的switch语句
- 重构AdminController中的条件和消耗类型显示逻辑,消除硬编码的类型判断
- 重构ConditionGroupService、ConsumeGroupService,简化类型名称获取逻辑
- 删除各个类中重复的getTargetName、类型判断等方法
- 提升代码维护性,避免硬编码,统一条件组和消耗组类型处理标准
notfff 7 months ago
parent
commit
ace00e3f2a

+ 3 - 21
app/Module/Game/AdminControllers/GameConditionItemController.php

@@ -2,15 +2,10 @@
 
 namespace App\Module\Game\AdminControllers;
 
-use App\Module\Farm\Models\FarmLandType;
-use App\Module\Fund\Models\FundConfigModel;
-use App\Module\Fund\Models\FundCurrencyModel;
 use App\Module\Game\Enums\CONDITION_OPERATOR;
 use App\Module\Game\Enums\CONDITION_TYPE;
 use App\Module\Game\Models\GameConditionGroup;
 use App\Module\Game\Repositorys\GameConditionItemRepository;
-use App\Module\GameItems\Models\Item;
-use App\Module\Pet\Models\PetConfig;
 
 use Dcat\Admin\Admin;
 use Dcat\Admin\Form;
@@ -125,22 +120,9 @@ class GameConditionItemController extends AdminController
             // 根据条件类型显示不同的提示信息
             $form->select('target_id', '目标ID')
                 ->options(function () {
-                    $conditionType = request()->input('condition_type',$this->condition_type);
-
-                    // 根据条件类型返回不同的选项
-                    if ($conditionType == CONDITION_TYPE::LAND_LEVEL->value) {
-                        return FarmLandType::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONDITION_TYPE::PET_LEVEL->value) {
-                        return PetConfig::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONDITION_TYPE::ITEM_COUNT->value) {
-                        return Item::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONDITION_TYPE::CURRENCY_COUNT->value) {
-                        return FundCurrencyModel::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONDITION_TYPE::FUND_COUNT->value) {
-                        return FundConfigModel::pluck('name', 'id')->toArray();
-                    }
-
-                    return [];
+                    $conditionType = request()->input('condition_type', 0);
+                    // 使用统一的条件类型描述器获取目标选项
+                    return \App\Module\Game\Services\ConditionTypeDescriptor::getTargetOptions($conditionType);
                 })
                 ->help('根据条件类型不同,表示土地类型ID、宠物ID、物品ID、代币ID等。房屋等级条件可填0。');
 

+ 3 - 12
app/Module/Game/AdminControllers/GameConsumeGroupController.php

@@ -144,18 +144,9 @@ class GameConsumeGroupController extends AdminController
                         return $targetId;
                     }
 
-                    // 根据消耗类型显示目标名称
-                    if ($consumeItem->consume_type == CONSUME_TYPE::ITEM->value) {
-                        $item = \App\Module\GameItems\Models\Item::find($targetId);
-                        return $item ? "{$item->name} (ID: {$targetId})" : "物品 (ID: {$targetId})";
-                    } elseif ($consumeItem->consume_type == CONSUME_TYPE::CURRENCY->value) {
-                        $currency = \App\Module\Fund\Models\FundCurrencyModel::find($targetId);
-                        return $currency ? "{$currency->name} (ID: {$targetId})" : "货币 (ID: {$targetId})";
-                    } elseif ($consumeItem->consume_type == CONSUME_TYPE::FUND_CONFIG->value) {
-                        $fund = \App\Module\Fund\Models\FundConfigModel::find($targetId);
-                        return $fund ? "{$fund->name} (ID: {$targetId})" : "代币账户 (ID: {$targetId})";
-                    }
-                    return $targetId;
+                    // 使用统一的消耗类型描述器获取目标名称
+                    $targetName = \App\Module\Game\Services\ConsumeTypeDescriptor::getTargetName($consumeItem->consume_type, $targetId);
+                    return "{$targetName} (ID: {$targetId})";
                 });
                 $grid->column('quantity', '数量');
 

+ 5 - 13
app/Module/Game/AdminControllers/GameConsumeItemController.php

@@ -6,7 +6,7 @@ use App\Module\Fund\Models\FundConfigModel;
 use App\Module\Fund\Models\FundCurrencyModel;
 use App\Module\Game\AdminControllers\Actions\DuplicateConsumeItemAction;
 use App\Module\Game\Enums\CONSUME_TYPE;
-use App\Module\Game\Enums\REWARD_TYPE;
+
 use App\Module\Game\Models\GameConsumeGroup;
 use App\Module\Game\Models\GameConsumeItem;
 use App\Module\Game\Repositorys\GameConsumeItemRepository;
@@ -172,7 +172,7 @@ class GameConsumeItemController extends AdminController
                 } elseif ($consumeType == CONSUME_TYPE::CURRENCY->value) {
                     $currency = FundCurrencyModel::find($targetId);
                     return $currency ? "{$currency->name} ({$targetId})" : $targetId;
-                } elseif ($consumeType == CONSUME_TYPE::FUND->value) {
+                } elseif ($consumeType == CONSUME_TYPE::FUND_CONFIG->value) {
                     $fund = FundConfigModel::find($targetId);
                     return $fund ? "{$fund->name} ({$targetId})" : $targetId;
                 }
@@ -208,17 +208,9 @@ class GameConsumeItemController extends AdminController
                 ->default(request()->input('consume_type'));
             $form->select('target_id', '目标ID')
                 ->options(function () {
-                    $conditionType = request()->input('consume_type',$this->consume_type);
-                    // 根据条件类型返回不同的选项
-                    if  ($conditionType == REWARD_TYPE::ITEM->value) {
-                        return Item::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONSUME_TYPE::CURRENCY->value) {
-                        return FundCurrencyModel::pluck('name', 'id')->toArray();
-                    } elseif ($conditionType == CONSUME_TYPE::FUND_CONFIG->value) {
-                        return FundConfigModel::pluck('name', 'id')->toArray();
-                    }
-
-                    return [];
+                    $consumeType = request()->input('consume_type', 0);
+                    // 使用统一的消耗类型描述器获取目标选项
+                    return \App\Module\Game\Services\ConsumeTypeDescriptor::getTargetOptions($consumeType);
                 });
 
 

+ 69 - 0
app/Module/Game/Enums/CONDITION_TYPE.php

@@ -80,4 +80,73 @@ enum CONDITION_TYPE: int
     {
         return isset(self::getAll()[$type]);
     }
+
+    /**
+     * 获取条件类型的详细信息
+     *
+     * @param int $type
+     * @return array
+     */
+    public static function getTypeInfo(int $type): array
+    {
+        $descriptions = [
+            self::LAND_LEVEL->value => [
+                'name' => '土地等级',
+                'description' => '检查用户指定类型土地的等级',
+                'target_desc' => '土地类型ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'value_desc' => '要求的等级值',
+            ],
+            self::HOUSE_LEVEL->value => [
+                'name' => '房屋等级',
+                'description' => '检查用户房屋的等级',
+                'target_desc' => '房屋ID(可填0)',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'value_desc' => '要求的等级值',
+            ],
+            self::PET_LEVEL->value => [
+                'name' => '宠物等级',
+                'description' => '检查用户指定宠物的等级',
+                'target_desc' => '宠物配置ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'value_desc' => '要求的等级值',
+            ],
+            self::ITEM_COUNT->value => [
+                'name' => '物品持有数',
+                'description' => '检查用户背包中指定物品的数量',
+                'target_desc' => '物品ID',
+                'param1_desc' => '品质要求',
+                'param2_desc' => '绑定状态要求',
+                'value_desc' => '要求的数量',
+            ],
+            self::CURRENCY_COUNT->value => [
+                'name' => '代币(币种)持有数',
+                'description' => '检查用户指定币种的持有数量',
+                'target_desc' => '币种ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'value_desc' => '要求的数量',
+            ],
+            self::FUND_COUNT->value => [
+                'name' => '代币(账户)持有数',
+                'description' => '检查用户指定账户种类的持有数量',
+                'target_desc' => '账户种类ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'value_desc' => '要求的数量',
+            ],
+        ];
+
+        return $descriptions[$type] ?? [
+            'name' => '未知',
+            'description' => '未知条件类型',
+            'target_desc' => '未知目标',
+            'param1_desc' => '未知参数1',
+            'param2_desc' => '未知参数2',
+            'value_desc' => '未知值',
+        ];
+    }
 }

+ 53 - 0
app/Module/Game/Enums/CONSUME_TYPE.php

@@ -83,4 +83,57 @@ enum CONSUME_TYPE: int
         return isset(self::getAll()[$type]);
     }
 
+    /**
+     * 获取消耗类型的详细信息
+     *
+     * @param int $type
+     * @return array
+     */
+    public static function getTypeInfo(int $type): array
+    {
+        $descriptions = [
+            self::ITEM->value => [
+                'name' => '物品',
+                'description' => '消耗用户背包中的物品',
+                'target_desc' => '物品ID',
+                'param1_desc' => '品质要求',
+                'param2_desc' => '绑定状态要求',
+                'quantity_desc' => '消耗数量',
+            ],
+            self::CURRENCY->value => [
+                'name' => '币种(CURRENCY)',
+                'description' => '消耗用户特定币种的资金',
+                'target_desc' => '币种ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'quantity_desc' => '消耗金额',
+            ],
+            self::FUND_CONFIG->value => [
+                'name' => '账户种类',
+                'description' => '消耗用户特定账户种类的资金',
+                'target_desc' => '账户种类ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'quantity_desc' => '消耗金额',
+            ],
+            self::FUND_CONFIGS->value => [
+                'name' => '多账户种类',
+                'description' => '消耗用户多个账户种类的资金,按顺序依次消耗',
+                'target_desc' => '主账户种类ID',
+                'param1_desc' => '保留参数',
+                'param2_desc' => '保留参数',
+                'quantity_desc' => '消耗金额',
+                'extra_data_desc' => '多个账户种类ID的JSON数组',
+            ],
+        ];
+
+        return $descriptions[$type] ?? [
+            'name' => '未知',
+            'description' => '未知消耗类型',
+            'target_desc' => '未知目标',
+            'param1_desc' => '未知参数1',
+            'param2_desc' => '未知参数2',
+            'quantity_desc' => '未知数量',
+        ];
+    }
 }

+ 1 - 27
app/Module/Game/Models/GameConditionItem.php

@@ -123,32 +123,6 @@ class GameConditionItem extends ModelCore
      */
     public function getTargetName(): string
     {
-        switch ($this->condition_type) {
-            case CONDITION_TYPE::LAND_LEVEL->value:
-                $landType = \App\Module\Farm\Models\FarmLandType::find($this->target_id);
-                return $landType ? $landType->name : "土地类型 {$this->target_id}";
-
-            case CONDITION_TYPE::HOUSE_LEVEL->value:
-                return "房屋等级";
-
-            case CONDITION_TYPE::PET_LEVEL->value:
-                $pet = \App\Module\Pet\Models\PetConfig::find($this->target_id);
-                return $pet ? $pet->name : "宠物 {$this->target_id}";
-
-            case CONDITION_TYPE::ITEM_COUNT->value:
-                $item = \App\Module\GameItems\Models\Item::find($this->target_id);
-                return $item ? $item->name : "物品 {$this->target_id}";
-
-            case CONDITION_TYPE::CURRENCY_COUNT->value:
-                $currency = \App\Module\Fund\Models\FundCurrencyModel::find($this->target_id);
-                return $currency ? $currency->name : "代币(币种) {$this->target_id}";
-
-            case CONDITION_TYPE::FUND_COUNT->value:
-                $fund = \App\Module\Fund\Models\FundConfigModel::find($this->target_id);
-                return $fund ? $fund->name : "代币(账户) {$this->target_id}";
-
-            default:
-                return "未知目标 {$this->target_id}";
-        }
+        return \App\Module\Game\Services\ConditionTypeDescriptor::getTargetNameFromModel($this);
     }
 }

+ 3 - 30
app/Module/Game/Services/ConditionGroupService.php

@@ -2,14 +2,9 @@
 
 namespace App\Module\Game\Services;
 
-use App\Module\Farm\Models\FarmLandType;
-use App\Module\Fund\Models\FundConfigModel;
-use App\Module\Fund\Models\FundCurrencyModel;
 use App\Module\Game\Enums\CONDITION_OPERATOR;
 use App\Module\Game\Enums\CONDITION_TYPE;
 use App\Module\Game\Models\GameConditionGroup;
-use App\Module\GameItems\Models\Item;
-use App\Module\Pet\Models\PetConfig;
 use Illuminate\Support\Facades\Log;
 
 /**
@@ -76,31 +71,9 @@ class ConditionGroupService
                     'operator_name' => CONDITION_OPERATOR::getName($item->operator)
                 ];
                 
-                // 根据条件类型获取目标名称
-                if ($item->condition_type == CONDITION_TYPE::LAND_LEVEL->value) {
-                    $landType = FarmLandType::find($item->target_id);
-                    $conditionItem['target_name'] = $landType ? $landType->name : "土地类型 {$item->target_id}";
-                    $conditionItem['condition_name'] = "土地等级";
-                } elseif ($item->condition_type == CONDITION_TYPE::HOUSE_LEVEL->value) {
-                    $conditionItem['target_name'] = "房屋";
-                    $conditionItem['condition_name'] = "房屋等级";
-                } elseif ($item->condition_type == CONDITION_TYPE::PET_LEVEL->value) {
-                    $pet = PetConfig::find($item->target_id);
-                    $conditionItem['target_name'] = $pet ? $pet->name : "宠物 {$item->target_id}";
-                    $conditionItem['condition_name'] = "宠物等级";
-                } elseif ($item->condition_type == CONDITION_TYPE::ITEM_COUNT->value) {
-                    $itemInfo = Item::find($item->target_id);
-                    $conditionItem['target_name'] = $itemInfo ? $itemInfo->name : "物品 {$item->target_id}";
-                    $conditionItem['condition_name'] = "物品持有数";
-                } elseif ($item->condition_type == CONDITION_TYPE::CURRENCY_COUNT->value) {
-                    $currency = FundCurrencyModel::find($item->target_id);
-                    $conditionItem['target_name'] = $currency ? $currency->name : "货币 {$item->target_id}";
-                    $conditionItem['condition_name'] = "货币持有数";
-                } elseif ($item->condition_type == CONDITION_TYPE::FUND_COUNT->value) {
-                    $fund = FundConfigModel::find($item->target_id);
-                    $conditionItem['target_name'] = $fund ? $fund->name : "代币账户 {$item->target_id}";
-                    $conditionItem['condition_name'] = "代币持有数";
-                }
+                // 使用统一的条件类型描述器获取目标名称和条件名称
+                $conditionItem['target_name'] = \App\Module\Game\Services\ConditionTypeDescriptor::getTargetNameFromModel($item);
+                $conditionItem['condition_name'] = CONDITION_TYPE::getName($item->condition_type);
                 
                 $conditions[] = $conditionItem;
             }

+ 235 - 0
app/Module/Game/Services/ConditionTypeDescriptor.php

@@ -0,0 +1,235 @@
+<?php
+
+namespace App\Module\Game\Services;
+
+use App\Module\Game\Enums\CONDITION_TYPE;
+use App\Module\Game\Models\GameConditionItem;
+use App\Module\Farm\Models\FarmLandType;
+use App\Module\Pet\Models\PetConfig;
+use App\Module\GameItems\Models\Item;
+use App\Module\Fund\Models\FundCurrencyModel;
+use App\Module\Fund\Models\FundConfigModel;
+use Exception;
+
+/**
+ * 条件类型描述器
+ * 
+ * 统一处理所有条件类型的描述、名称获取等逻辑
+ * 避免在各个类中重复实现相同的逻辑
+ */
+class ConditionTypeDescriptor
+{
+    /**
+     * 获取条件目标的名称
+     *
+     * @param int $conditionType 条件类型
+     * @param int $targetId 目标ID
+     * @param int $param1 参数1
+     * @param int $param2 参数2
+     * @return string 目标名称
+     */
+    public static function getTargetName(int $conditionType, int $targetId, int $param1 = 0, int $param2 = 0): string
+    {
+        switch ($conditionType) {
+            case CONDITION_TYPE::LAND_LEVEL->value:
+                return self::getLandTypeName($targetId);
+
+            case CONDITION_TYPE::HOUSE_LEVEL->value:
+                return self::getHouseName($targetId);
+
+            case CONDITION_TYPE::PET_LEVEL->value:
+                return self::getPetName($targetId);
+
+            case CONDITION_TYPE::ITEM_COUNT->value:
+                return self::getItemName($targetId);
+
+            case CONDITION_TYPE::CURRENCY_COUNT->value:
+                return self::getCurrencyName($targetId);
+
+            case CONDITION_TYPE::FUND_COUNT->value:
+                return self::getFundConfigName($targetId);
+
+            default:
+                return "未知条件类型 (ID: {$targetId})";
+        }
+    }
+
+    /**
+     * 从GameConditionItem模型获取目标名称
+     *
+     * @param GameConditionItem $item 条件项模型
+     * @return string 目标名称
+     */
+    public static function getTargetNameFromModel(GameConditionItem $item): string
+    {
+        return self::getTargetName($item->condition_type, $item->target_id, $item->param1, $item->param2);
+    }
+
+    /**
+     * 格式化条件项显示
+     *
+     * @param int $conditionType 条件类型
+     * @param int $targetId 目标ID
+     * @param int $operator 比较运算符
+     * @param int $value 比较值
+     * @param int $param1 参数1
+     * @param int $param2 参数2
+     * @param bool $withBadge 是否包含徽章样式
+     * @return string 格式化后的显示文本
+     */
+    public static function formatConditionDisplay(int $conditionType, int $targetId, int $operator, int $value, int $param1 = 0, int $param2 = 0, bool $withBadge = true): string
+    {
+        $conditionTypeName = CONDITION_TYPE::getName($conditionType);
+        $targetName = self::getTargetName($conditionType, $targetId, $param1, $param2);
+        $operatorSymbol = \App\Module\Game\Enums\CONDITION_OPERATOR::getSymbol($operator);
+
+        if ($withBadge) {
+            return "<span class=\"badge badge-warning\">{$conditionTypeName}</span> {$targetName} {$operatorSymbol} {$value}";
+        } else {
+            return "• {$conditionTypeName}: {$targetName} {$operatorSymbol} {$value}";
+        }
+    }
+
+    /**
+     * 从GameConditionItem模型格式化显示
+     *
+     * @param GameConditionItem $item 条件项模型
+     * @param bool $withBadge 是否包含徽章样式
+     * @return string 格式化后的显示文本
+     */
+    public static function formatConditionDisplayFromModel(GameConditionItem $item, bool $withBadge = true): string
+    {
+        return self::formatConditionDisplay(
+            $item->condition_type,
+            $item->target_id,
+            $item->operator,
+            $item->value,
+            $item->param1,
+            $item->param2,
+            $withBadge
+        );
+    }
+
+    /**
+     * 获取条件类型的目标选项(用于表单)
+     *
+     * @param int $conditionType 条件类型
+     * @return array 目标选项数组
+     */
+    public static function getTargetOptions(int $conditionType): array
+    {
+        switch ($conditionType) {
+            case CONDITION_TYPE::LAND_LEVEL->value:
+                return FarmLandType::pluck('name', 'id')->toArray();
+
+            case CONDITION_TYPE::HOUSE_LEVEL->value:
+                return [0 => '房屋等级']; // 房屋等级条件可填0
+
+            case CONDITION_TYPE::PET_LEVEL->value:
+                return PetConfig::pluck('name', 'id')->toArray();
+
+            case CONDITION_TYPE::ITEM_COUNT->value:
+                return Item::pluck('name', 'id')->toArray();
+
+            case CONDITION_TYPE::CURRENCY_COUNT->value:
+                return FundCurrencyModel::pluck('name', 'id')->toArray();
+
+            case CONDITION_TYPE::FUND_COUNT->value:
+                return FundConfigModel::pluck('name', 'id')->toArray();
+
+            default:
+                return [];
+        }
+    }
+
+    /**
+     * 获取土地类型名称
+     *
+     * @param int $landTypeId 土地类型ID
+     * @return string 土地类型名称
+     */
+    private static function getLandTypeName(int $landTypeId): string
+    {
+        try {
+            $landType = FarmLandType::find($landTypeId);
+            return $landType ? $landType->name : "土地类型 (ID: {$landTypeId})";
+        } catch (Exception $e) {
+            return "土地类型 (ID: {$landTypeId})";
+        }
+    }
+
+    /**
+     * 获取房屋名称
+     *
+     * @param int $houseId 房屋ID
+     * @return string 房屋名称
+     */
+    private static function getHouseName(int $houseId): string
+    {
+        return "房屋等级";
+    }
+
+    /**
+     * 获取宠物名称
+     *
+     * @param int $petId 宠物ID
+     * @return string 宠物名称
+     */
+    private static function getPetName(int $petId): string
+    {
+        try {
+            $pet = PetConfig::find($petId);
+            return $pet ? $pet->name : "宠物 (ID: {$petId})";
+        } catch (Exception $e) {
+            return "宠物 (ID: {$petId})";
+        }
+    }
+
+    /**
+     * 获取物品名称
+     *
+     * @param int $itemId 物品ID
+     * @return string 物品名称
+     */
+    private static function getItemName(int $itemId): string
+    {
+        try {
+            $item = Item::find($itemId);
+            return $item ? $item->name : "物品 (ID: {$itemId})";
+        } catch (Exception $e) {
+            return "物品 (ID: {$itemId})";
+        }
+    }
+
+    /**
+     * 获取货币名称
+     *
+     * @param int $currencyId 货币ID
+     * @return string 货币名称
+     */
+    private static function getCurrencyName(int $currencyId): string
+    {
+        try {
+            $currency = FundCurrencyModel::find($currencyId);
+            return $currency ? $currency->name : "货币 (ID: {$currencyId})";
+        } catch (Exception $e) {
+            return "货币 (ID: {$currencyId})";
+        }
+    }
+
+    /**
+     * 获取账户种类名称
+     *
+     * @param int $fundConfigId 账户种类ID
+     * @return string 账户种类名称
+     */
+    private static function getFundConfigName(int $fundConfigId): string
+    {
+        try {
+            $fund = FundConfigModel::find($fundConfigId);
+            return $fund ? $fund->name : "代币账户 (ID: {$fundConfigId})";
+        } catch (Exception $e) {
+            return "代币账户 (ID: {$fundConfigId})";
+        }
+    }
+}

+ 2 - 33
app/Module/Game/Services/ConsumeGroupService.php

@@ -2,12 +2,7 @@
 
 namespace App\Module\Game\Services;
 
-use App\Module\Fund\Models\FundConfigModel;
-use App\Module\Fund\Models\FundCurrencyModel;
-use App\Module\Game\Enums\CONSUME_TYPE;
 use App\Module\Game\Models\GameConsumeGroup;
-use App\Module\Game\Models\GameConsumeItem;
-use App\Module\GameItems\Models\Item;
 use Illuminate\Support\Facades\Log;
 
 /**
@@ -109,34 +104,8 @@ class ConsumeGroupService
 
         // 处理每个消耗项
         foreach ($consumeItems as $item) {
-            if ($item->consume_type == CONSUME_TYPE::ITEM->value) {
-                // 获取物品信息
-                $itemInfo = Item::find($item->target_id);
-                $materials[] = [
-                    'type' => $item->consume_type,
-                    'item_id' => $item->target_id,
-                    'item_name' => $itemInfo ? $itemInfo->name : "物品 {$item->target_id}",
-                    'amount' => $item->quantity
-                ];
-            } elseif ($item->consume_type == CONSUME_TYPE::CURRENCY->value) {
-                // 获取货币信息
-                $currencyInfo = FundCurrencyModel::find($item->target_id);
-                $materials[] = [
-                    'type' => $item->consume_type,
-                    'currency_id' => $item->target_id,
-                    'currency_name' => $currencyInfo ? $currencyInfo->name : "货币 {$item->target_id}",
-                    'amount' => $item->quantity
-                ];
-            } elseif ($item->consume_type == CONSUME_TYPE::FUND_CONFIG->value) {
-                // 获取代币账户信息
-                $fundInfo = FundConfigModel::find($item->target_id);
-                $materials[] = [
-                    'type' => $item->consume_type,
-                    'fund_id' => $item->target_id,
-                    'fund_name' => $fundInfo ? $fundInfo->name : "代币账户 {$item->target_id}",
-                    'amount' => $item->quantity
-                ];
-            }
+            // 使用统一的消耗类型描述器转换为数组
+            $materials[] = \App\Module\Game\Services\ConsumeTypeDescriptor::convertToArray($item);
         }
 
         return $materials;

+ 241 - 0
app/Module/Game/Services/ConsumeTypeDescriptor.php

@@ -0,0 +1,241 @@
+<?php
+
+namespace App\Module\Game\Services;
+
+use App\Module\Game\Enums\CONSUME_TYPE;
+use App\Module\Game\Models\GameConsumeItem;
+use App\Module\GameItems\Models\Item;
+use App\Module\Fund\Models\FundCurrencyModel;
+use App\Module\Fund\Models\FundConfigModel;
+use Exception;
+
+/**
+ * 消耗类型描述器
+ * 
+ * 统一处理所有消耗类型的描述、名称获取等逻辑
+ * 避免在各个类中重复实现相同的逻辑
+ */
+class ConsumeTypeDescriptor
+{
+    /**
+     * 获取消耗目标的名称
+     *
+     * @param int $consumeType 消耗类型
+     * @param int $targetId 目标ID
+     * @param int $param1 参数1
+     * @param int $param2 参数2
+     * @return string 目标名称
+     */
+    public static function getTargetName(int $consumeType, int $targetId, int $param1 = 0, int $param2 = 0): string
+    {
+        switch ($consumeType) {
+            case CONSUME_TYPE::ITEM->value:
+                return self::getItemName($targetId);
+
+            case CONSUME_TYPE::CURRENCY->value:
+                return self::getCurrencyName($targetId);
+
+            case CONSUME_TYPE::FUND_CONFIG->value:
+                return self::getFundConfigName($targetId);
+
+            case CONSUME_TYPE::FUND_CONFIGS->value:
+                return self::getFundConfigsName($targetId);
+
+            default:
+                return "未知消耗类型 (ID: {$targetId})";
+        }
+    }
+
+    /**
+     * 从GameConsumeItem模型获取目标名称
+     *
+     * @param GameConsumeItem $item 消耗项模型
+     * @return string 目标名称
+     */
+    public static function getTargetNameFromModel(GameConsumeItem $item): string
+    {
+        return self::getTargetName($item->consume_type, $item->target_id, $item->param1, $item->param2);
+    }
+
+    /**
+     * 格式化消耗项显示
+     *
+     * @param int $consumeType 消耗类型
+     * @param int $targetId 目标ID
+     * @param int $quantity 数量
+     * @param int $param1 参数1
+     * @param int $param2 参数2
+     * @param bool $withBadge 是否包含徽章样式
+     * @return string 格式化后的显示文本
+     */
+    public static function formatConsumeDisplay(int $consumeType, int $targetId, int $quantity, int $param1 = 0, int $param2 = 0, bool $withBadge = true): string
+    {
+        $consumeTypeName = CONSUME_TYPE::getName($consumeType);
+        $targetName = self::getTargetName($consumeType, $targetId, $param1, $param2);
+
+        if ($withBadge) {
+            return "<span class=\"badge badge-danger\">{$consumeTypeName}</span> {$targetName} × {$quantity}";
+        } else {
+            return "• {$consumeTypeName}: {$targetName} × {$quantity}";
+        }
+    }
+
+    /**
+     * 从GameConsumeItem模型格式化显示
+     *
+     * @param GameConsumeItem $item 消耗项模型
+     * @param bool $withBadge 是否包含徽章样式
+     * @return string 格式化后的显示文本
+     */
+    public static function formatConsumeDisplayFromModel(GameConsumeItem $item, bool $withBadge = true): string
+    {
+        return self::formatConsumeDisplay(
+            $item->consume_type,
+            $item->target_id,
+            $item->quantity,
+            $item->param1,
+            $item->param2,
+            $withBadge
+        );
+    }
+
+    /**
+     * 获取消耗类型的目标选项(用于表单)
+     *
+     * @param int $consumeType 消耗类型
+     * @return array 目标选项数组
+     */
+    public static function getTargetOptions(int $consumeType): array
+    {
+        switch ($consumeType) {
+            case CONSUME_TYPE::ITEM->value:
+                return Item::pluck('name', 'id')->toArray();
+
+            case CONSUME_TYPE::CURRENCY->value:
+                return FundCurrencyModel::pluck('name', 'id')->toArray();
+
+            case CONSUME_TYPE::FUND_CONFIG->value:
+            case CONSUME_TYPE::FUND_CONFIGS->value:
+                return FundConfigModel::pluck('name', 'id')->toArray();
+
+            default:
+                return [];
+        }
+    }
+
+    /**
+     * 转换消耗项为数组格式(用于API返回)
+     *
+     * @param GameConsumeItem $item 消耗项模型
+     * @return array 消耗项数组
+     */
+    public static function convertToArray(GameConsumeItem $item): array
+    {
+        $baseArray = [
+            'type' => $item->consume_type,
+            'amount' => $item->quantity
+        ];
+
+        switch ($item->consume_type) {
+            case CONSUME_TYPE::ITEM->value:
+                $itemInfo = Item::find($item->target_id);
+                return array_merge($baseArray, [
+                    'item_id' => $item->target_id,
+                    'item_name' => $itemInfo ? $itemInfo->name : "物品 {$item->target_id}",
+                ]);
+
+            case CONSUME_TYPE::CURRENCY->value:
+                $currencyInfo = FundCurrencyModel::find($item->target_id);
+                return array_merge($baseArray, [
+                    'currency_id' => $item->target_id,
+                    'currency_name' => $currencyInfo ? $currencyInfo->name : "货币 {$item->target_id}",
+                ]);
+
+            case CONSUME_TYPE::FUND_CONFIG->value:
+                $fundInfo = FundConfigModel::find($item->target_id);
+                return array_merge($baseArray, [
+                    'fund_id' => $item->target_id,
+                    'fund_name' => $fundInfo ? $fundInfo->name : "代币账户 {$item->target_id}",
+                ]);
+
+            case CONSUME_TYPE::FUND_CONFIGS->value:
+                $fundInfo = FundConfigModel::find($item->target_id);
+                return array_merge($baseArray, [
+                    'fund_id' => $item->target_id,
+                    'fund_name' => $fundInfo ? $fundInfo->name : "代币账户 {$item->target_id}",
+                    'fund_configs' => $item->extra_data ? json_decode($item->extra_data, true) : [],
+                ]);
+
+            default:
+                return array_merge($baseArray, [
+                    'target_id' => $item->target_id,
+                    'target_name' => "未知类型 {$item->target_id}",
+                ]);
+        }
+    }
+
+    /**
+     * 获取物品名称
+     *
+     * @param int $itemId 物品ID
+     * @return string 物品名称
+     */
+    private static function getItemName(int $itemId): string
+    {
+        try {
+            $item = Item::find($itemId);
+            return $item ? $item->name : "物品 (ID: {$itemId})";
+        } catch (Exception $e) {
+            return "物品 (ID: {$itemId})";
+        }
+    }
+
+    /**
+     * 获取货币名称
+     *
+     * @param int $currencyId 货币ID
+     * @return string 货币名称
+     */
+    private static function getCurrencyName(int $currencyId): string
+    {
+        try {
+            $currency = FundCurrencyModel::find($currencyId);
+            return $currency ? $currency->name : "货币 (ID: {$currencyId})";
+        } catch (Exception $e) {
+            return "货币 (ID: {$currencyId})";
+        }
+    }
+
+    /**
+     * 获取账户种类名称
+     *
+     * @param int $fundConfigId 账户种类ID
+     * @return string 账户种类名称
+     */
+    private static function getFundConfigName(int $fundConfigId): string
+    {
+        try {
+            $fund = FundConfigModel::find($fundConfigId);
+            return $fund ? $fund->name : "代币账户 (ID: {$fundConfigId})";
+        } catch (Exception $e) {
+            return "代币账户 (ID: {$fundConfigId})";
+        }
+    }
+
+    /**
+     * 获取多账户种类名称
+     *
+     * @param int $fundConfigId 主账户种类ID
+     * @return string 多账户种类名称
+     */
+    private static function getFundConfigsName(int $fundConfigId): string
+    {
+        try {
+            $fund = FundConfigModel::find($fundConfigId);
+            $baseName = $fund ? $fund->name : "代币账户 {$fundConfigId}";
+            return "多账户种类 ({$baseName})";
+        } catch (Exception $e) {
+            return "多账户种类 (ID: {$fundConfigId})";
+        }
+    }
+}