| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- <?php
- namespace App\Module\GameItems\Console\Commands;
- use App\Module\Game\Models\GameConsumeGroup;
- use App\Module\Game\Models\GameConsumeItem;
- use App\Module\Game\Models\GameRewardGroup;
- use App\Module\Game\Models\GameRewardItem;
- use App\Module\GameItems\Enums\ITEM_TYPE;
- use App\Module\GameItems\Models\Item;
- use App\Module\GameItems\Models\ItemChestContent;
- use App\Module\GameItems\Models\ItemChestOpenCost;
- use App\Module\GameItems\Models\ItemChestConfig;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 宝箱系统迁移命令
- *
- * 将现有的宝箱内容配置和开启消耗配置迁移到新的消耗组/奖励组系统
- */
- class MigrateChestToGroupSystemCommand extends Command
- {
- /**
- * 命令签名
- *
- * @var string
- */
- protected $signature = 'gameitems:migrate-chest-to-groups {--dry-run : 仅预览迁移结果,不实际执行}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '将现有宝箱配置迁移到消耗组/奖励组系统';
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle()
- {
- $isDryRun = $this->option('dry-run');
-
- $this->info('开始宝箱系统迁移...');
- $this->info($isDryRun ? '预览模式(不会实际修改数据)' : '实际执行模式');
-
- // 获取所有宝箱类型物品
- $chests = Item::where('type', ITEM_TYPE::CHEST)->get();
-
- if ($chests->isEmpty()) {
- $this->info('没有找到宝箱类型物品,迁移完成。');
- return 0;
- }
-
- $this->info("找到 {$chests->count()} 个宝箱物品");
-
- $migratedCount = 0;
- $skippedCount = 0;
-
- foreach ($chests as $chest) {
- $this->info("处理宝箱: {$chest->name} (ID: {$chest->id})");
-
- try {
- if ($this->migrateChest($chest, $isDryRun)) {
- $migratedCount++;
- } else {
- $skippedCount++;
- }
- } catch (\Exception $e) {
- $this->error("迁移宝箱 {$chest->id} 失败: " . $e->getMessage());
- Log::error('宝箱迁移失败', [
- 'chest_id' => $chest->id,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- }
- }
-
- $this->info("迁移完成!");
- $this->info("成功迁移: {$migratedCount} 个宝箱");
- $this->info("跳过: {$skippedCount} 个宝箱");
-
- return 0;
- }
- /**
- * 迁移单个宝箱
- *
- * @param Item $chest
- * @param bool $isDryRun
- * @return bool
- */
- private function migrateChest(Item $chest, bool $isDryRun): bool
- {
- // 检查是否已经配置了新系统
- $existingConfig = ItemChestConfig::where('item_id', $chest->id)->first();
- if ($existingConfig) {
- $this->warn(" 宝箱 {$chest->id} 已配置新系统,跳过");
- return false;
- }
-
- if ($isDryRun) {
- $this->previewChestMigration($chest);
- return true;
- }
-
- DB::beginTransaction();
- try {
- // 迁移消耗配置
- $consumeGroupId = $this->migrateChestCosts($chest);
-
- // 迁移奖励配置
- $rewardGroupId = $this->migrateChestContents($chest);
- // 创建新配置
- ItemChestConfig::create([
- 'item_id' => $chest->id,
- 'consume_group_id' => $consumeGroupId,
- 'reward_group_id' => $rewardGroupId,
- 'condition_group_id' => null, // 暂不支持条件组迁移
- 'is_active' => true,
- ]);
-
- DB::commit();
- $this->info(" ✓ 宝箱 {$chest->id} 迁移成功");
- return true;
-
- } catch (\Exception $e) {
- DB::rollBack();
- throw $e;
- }
- }
- /**
- * 预览宝箱迁移
- *
- * @param Item $chest
- */
- private function previewChestMigration(Item $chest)
- {
- $this->info(" 预览宝箱 {$chest->id} 迁移:");
-
- // 预览消耗配置
- $costs = ItemChestOpenCost::where('chest_id', $chest->id)->where('is_active', true)->get();
- if ($costs->isNotEmpty()) {
- $this->info(" 将创建消耗组: {$chest->name}_消耗组");
- foreach ($costs as $cost) {
- $this->info(" - 消耗类型: {$cost->cost_type}, ID: {$cost->cost_id}, 数量: {$cost->cost_quantity}");
- }
- } else {
- $this->info(" 无消耗配置,不创建消耗组");
- }
-
- // 预览奖励配置
- $contents = ItemChestContent::where('chest_id', $chest->id)->get();
- if ($contents->isNotEmpty()) {
- $this->info(" 将创建奖励组: {$chest->name}_奖励组");
- foreach ($contents as $content) {
- $type = $content->item_id ? "物品ID: {$content->item_id}" : "物品组ID: {$content->group_id}";
- $this->info(" - {$type}, 数量: {$content->min_quantity}-{$content->max_quantity}, 权重: {$content->weight}");
- }
- } else {
- $this->warn(" 无奖励配置,将创建空奖励组");
- }
- }
- /**
- * 迁移宝箱消耗配置
- *
- * @param Item $chest
- * @return int|null
- */
- private function migrateChestCosts(Item $chest): ?int
- {
- $costs = ItemChestOpenCost::where('chest_id', $chest->id)->where('is_active', true)->get();
-
- if ($costs->isEmpty()) {
- return null;
- }
-
- // 创建消耗组
- $consumeGroup = GameConsumeGroup::create([
- 'name' => $chest->name . '_消耗组',
- 'code' => 'chest_' . $chest->id . '_consume_' . time(),
- 'description' => "宝箱 {$chest->name} 的开启消耗配置(从旧系统迁移)",
- ]);
-
- // 创建消耗项
- foreach ($costs as $cost) {
- GameConsumeItem::create([
- 'group_id' => $consumeGroup->id,
- 'consume_type' => $cost->cost_type,
- 'target_id' => $cost->cost_id,
- 'quantity' => $cost->cost_quantity,
- ]);
- }
-
- return $consumeGroup->id;
- }
- /**
- * 迁移宝箱内容配置
- *
- * @param Item $chest
- * @return int
- */
- private function migrateChestContents(Item $chest): int
- {
- $contents = ItemChestContent::where('chest_id', $chest->id)->get();
-
- // 创建奖励组
- $rewardGroup = GameRewardGroup::create([
- 'name' => $chest->name . '_奖励组',
- 'code' => 'chest_' . $chest->id . '_reward_' . time(),
- 'description' => "宝箱 {$chest->name} 的奖励配置(从旧系统迁移)",
- 'is_random' => true,
- 'random_count' => ($chest->numeric_attributes && $chest->numeric_attributes->max_drop_count > 0) ? $chest->numeric_attributes->max_drop_count : 1,
- 'reward_mode' => 1, // 权重选择模式
- ]);
-
- // 创建奖励项
- foreach ($contents as $content) {
- if ($content->item_id) {
- // 直接物品奖励
- GameRewardItem::create([
- 'group_id' => $rewardGroup->id,
- 'reward_type' => 1, // 物品类型
- 'target_id' => $content->item_id,
- 'quantity' => $content->max_quantity, // 使用最大数量
- 'weight' => $content->weight,
- 'is_guaranteed' => false,
- ]);
- } elseif ($content->group_id) {
- // 物品组奖励 - 需要展开为具体物品
- $this->expandGroupToRewardItems($rewardGroup->id, $content);
- }
- }
-
- return $rewardGroup->id;
- }
- /**
- * 展开物品组为具体奖励项
- *
- * @param int $rewardGroupId
- * @param ItemChestContent $content
- */
- private function expandGroupToRewardItems(int $rewardGroupId, ItemChestContent $content)
- {
- $groupItems = \App\Module\GameItems\Models\ItemGroupItem::where('group_id', $content->group_id)->get();
-
- foreach ($groupItems as $groupItem) {
- GameRewardItem::create([
- 'group_id' => $rewardGroupId,
- 'reward_type' => 1, // 物品类型
- 'target_id' => $groupItem->item_id,
- 'quantity' => $content->max_quantity,
- 'weight' => $content->weight * $groupItem->weight, // 组合权重
- 'is_guaranteed' => false,
- ]);
- }
- }
- }
|