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

给房屋配置增加可用土地数量参数,实现房屋升级后自动创建土地功能

notfff пре 7 месеци
родитељ
комит
4312d449c8

+ 141 - 0
app/Module/Farm/Commands/InitializeUserLandsCommand.php

@@ -0,0 +1,141 @@
+<?php
+
+namespace App\Module\Farm\Commands;
+
+use App\Module\Farm\Logics\HouseLogic;
+use App\Module\Farm\Logics\LandLogic;
+use App\Module\Farm\Models\FarmLand;
+use App\Module\Farm\Models\FarmUser;
+use App\Module\Farm\Enums\LAND_TYPE;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+class InitializeUserLandsCommand extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'farm:initialize-user-lands {--user_id= : 指定用户ID,不指定则处理所有用户}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '根据用户房屋等级初始化用户的土地';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        $this->info('开始初始化用户土地...');
+
+        // 获取用户ID参数
+        $userId = $this->option('user_id');
+
+        // 创建逻辑类实例
+        $houseLogic = new HouseLogic();
+        $landLogic = new LandLogic();
+
+        try {
+            // 根据是否指定用户ID获取用户列表
+            if ($userId) {
+                $users = FarmUser::where('user_id', $userId)->get();
+                $this->info("处理指定用户 ID: {$userId}");
+            } else {
+                $users = FarmUser::all();
+                $this->info("处理所有用户,共 " . $users->count() . " 个用户");
+            }
+
+            $bar = $this->output->createProgressBar($users->count());
+            $bar->start();
+
+            $totalCreated = 0;
+            $totalUsers = 0;
+
+            foreach ($users as $user) {
+                $userId = $user->user_id;
+                $houseLevel = $user->house_level;
+
+                // 获取该等级房屋可用的土地数量
+                $availableLands = $houseLogic->getAvailableLandsCount($houseLevel);
+
+                // 获取用户当前的土地
+                $userLands = FarmLand::where('user_id', $userId)->get();
+                $currentLandsCount = $userLands->count();
+
+                // 如果当前土地数量小于可用土地数量,需要创建新土地
+                if ($currentLandsCount < $availableLands) {
+                    $landsToAdd = $availableLands - $currentLandsCount;
+
+                    // 获取已使用的位置
+                    $usedPositions = $userLands->pluck('position')->toArray();
+
+                    // 开始创建新土地
+                    DB::beginTransaction();
+
+                    try {
+                        // 从位置1开始,找到未使用的位置创建土地
+                        $position = 1;
+                        $createdCount = 0;
+
+                        while ($createdCount < $landsToAdd) {
+                            // 如果位置未被使用,创建新土地
+                            if (!in_array($position, $usedPositions)) {
+                                $land = $landLogic->createLand($userId, $position, LAND_TYPE::NORMAL->value);
+
+                                if ($land) {
+                                    $createdCount++;
+                                    $totalCreated++;
+                                }
+                            }
+
+                            $position++;
+
+                            // 防止无限循环
+                            if ($position > 100) {
+                                $this->warn("用户 {$userId} 创建土地时达到最大位置限制");
+                                break;
+                            }
+                        }
+
+                        DB::commit();
+
+                        if ($createdCount > 0) {
+                            $totalUsers++;
+                        }
+                    } catch (\Exception $e) {
+                        DB::rollBack();
+                        $this->error("用户 {$userId} 创建土地失败: " . $e->getMessage());
+                        Log::error('初始化用户土地失败', [
+                            'user_id' => $userId,
+                            'error' => $e->getMessage(),
+                            'trace' => $e->getTraceAsString()
+                        ]);
+                    }
+                }
+
+                $bar->advance();
+            }
+
+            $bar->finish();
+            $this->newLine(2);
+
+            $this->info("初始化完成!共为 {$totalUsers} 个用户创建了 {$totalCreated} 块土地。");
+
+        } catch (\Exception $e) {
+            $this->error('初始化用户土地失败: ' . $e->getMessage());
+            Log::error('初始化用户土地失败', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            return 1;
+        }
+
+        return 0;
+    }
+}

+ 152 - 0
app/Module/Farm/Listeners/AddLandAfterHouseUpgradeListener.php

@@ -0,0 +1,152 @@
+<?php
+
+namespace App\Module\Farm\Listeners;
+
+use App\Module\Farm\Events\HouseUpgradedEvent;
+use App\Module\Farm\Logics\HouseLogic;
+use App\Module\Farm\Logics\LandLogic;
+use App\Module\Farm\Models\FarmLand;
+use App\Module\Farm\Enums\LAND_TYPE;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+class AddLandAfterHouseUpgradeListener implements ShouldQueue
+{
+    use InteractsWithQueue;
+
+    /**
+     * 房屋逻辑类
+     *
+     * @var HouseLogic
+     */
+    protected $houseLogic;
+
+    /**
+     * 土地逻辑类
+     *
+     * @var LandLogic
+     */
+    protected $landLogic;
+
+    /**
+     * Create the event listener.
+     */
+    public function __construct()
+    {
+        $this->houseLogic = new HouseLogic();
+        $this->landLogic = new LandLogic();
+    }
+
+    /**
+     * Handle the event.
+     */
+    public function handle(HouseUpgradedEvent $event): void
+    {
+        try {
+            // 只处理升级事件,不处理降级事件
+            if ($event->newLevel <= $event->oldLevel) {
+                Log::info('房屋降级,不创建新土地', [
+                    'user_id' => $event->userId,
+                    'old_level' => $event->oldLevel,
+                    'new_level' => $event->newLevel
+                ]);
+                return;
+            }
+
+            // 获取新等级可用的土地数量
+            $newAvailableLands = $this->houseLogic->getAvailableLandsCount($event->newLevel);
+
+            // 获取旧等级可用的土地数量
+            $oldAvailableLands = $this->houseLogic->getAvailableLandsCount($event->oldLevel);
+
+            // 计算需要新增的土地数量
+            $landsToAdd = $newAvailableLands - $oldAvailableLands;
+
+            if ($landsToAdd <= 0) {
+                Log::info('房屋升级后无需增加土地', [
+                    'user_id' => $event->userId,
+                    'old_level' => $event->oldLevel,
+                    'new_level' => $event->newLevel,
+                    'old_available_lands' => $oldAvailableLands,
+                    'new_available_lands' => $newAvailableLands
+                ]);
+                return;
+            }
+
+            Log::info('房屋升级后需要增加土地', [
+                'user_id' => $event->userId,
+                'old_level' => $event->oldLevel,
+                'new_level' => $event->newLevel,
+                'lands_to_add' => $landsToAdd
+            ]);
+
+            // 获取用户当前的土地
+            $userLands = FarmLand::where('user_id', $event->userId)->get();
+
+            // 获取已使用的位置
+            $usedPositions = $userLands->pluck('position')->toArray();
+
+            // 开始创建新土地
+            DB::beginTransaction();
+
+            try {
+                // 从位置1开始,找到未使用的位置创建土地
+                $position = 1;
+                $createdCount = 0;
+
+                while ($createdCount < $landsToAdd) {
+                    // 如果位置未被使用,创建新土地
+                    if (!in_array($position, $usedPositions)) {
+                        $land = $this->landLogic->createLand($event->userId, $position, LAND_TYPE::NORMAL->value);
+
+                        if ($land) {
+                            $createdCount++;
+                            Log::info('创建新土地成功', [
+                                'user_id' => $event->userId,
+                                'land_id' => $land->id,
+                                'position' => $position
+                            ]);
+                        }
+                    }
+
+                    $position++;
+
+                    // 防止无限循环
+                    if ($position > 100) {
+                        Log::warning('创建土地时达到最大位置限制', [
+                            'user_id' => $event->userId,
+                            'max_position' => 100
+                        ]);
+                        break;
+                    }
+                }
+
+                DB::commit();
+
+                Log::info('房屋升级后创建土地完成', [
+                    'user_id' => $event->userId,
+                    'created_count' => $createdCount,
+                    'target_count' => $landsToAdd
+                ]);
+            } catch (\Exception $e) {
+                DB::rollBack();
+
+                Log::error('房屋升级后创建土地失败', [
+                    'user_id' => $event->userId,
+                    'error' => $e->getMessage(),
+                    'trace' => $e->getTraceAsString()
+                ]);
+
+                throw $e;
+            }
+        } catch (\Exception $e) {
+            Log::error('处理房屋升级事件失败', [
+                'user_id' => $event->userId,
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+        }
+    }
+}

+ 28 - 0
app/Module/Farm/Logics/HouseLogic.php

@@ -96,6 +96,7 @@ class HouseLogic
                     'special_land_limit' => $config->special_land_limit,
                     'upgrade_materials' => $config->upgrade_materials,
                     'downgrade_days' => $config->downgrade_days,
+                    'available_lands' => $config->available_lands,
                 ];
             }
 
@@ -223,6 +224,33 @@ class HouseLogic
         }
     }
 
+    /**
+     * 获取房屋等级可用的土地数量
+     *
+     * @param int $level 房屋等级
+     * @return int 可用土地数量
+     */
+    public function getAvailableLandsCount(int $level): int
+    {
+        try {
+            $config = $this->getHouseConfig($level);
+
+            if (!$config) {
+                return 0;
+            }
+
+            return $config->available_lands;
+        } catch (\Exception $e) {
+            Log::error('获取房屋等级可用土地数量失败', [
+                'level' => $level,
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+
+            return 0;
+        }
+    }
+
     /**
      * 清除房屋配置缓存
      *

+ 1 - 0
app/Module/Farm/Models/FarmHouseConfig.php

@@ -14,6 +14,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
  * @property  int  $special_land_limit  特殊土地上限
  * @property  int  $upgrade_materials  升级所需消耗组ID,关联game_consume_groups表
  * @property  int  $downgrade_days  降级天数,NULL表示不降级
+ * @property  int  $available_lands  该等级可用的土地数量
  * @property  \Carbon\Carbon  $created_at  创建时间
  * @property  \Carbon\Carbon  $updated_at  更新时间
  * field end

+ 7 - 1
app/Module/Farm/Providers/FarmServiceProvider.php

@@ -5,6 +5,8 @@ namespace App\Module\Farm\Providers;
 use App\Module\Farm\Commands;
 use App\Module\Farm\Events\CropGrowthStageChangedEvent;
 use App\Module\Farm\Events\CropHarvestedEvent;
+use App\Module\Farm\Events\HouseUpgradedEvent;
+use App\Module\Farm\Listeners\AddLandAfterHouseUpgradeListener;
 use App\Module\Farm\Listeners\CalculateHarvestOutputListener;
 use App\Module\Farm\Listeners\CheckHouseDowngradeListener;
 use App\Module\Farm\Listeners\DistributeTeamProfitListener;
@@ -33,6 +35,9 @@ class FarmServiceProvider extends ServiceProvider
             CalculateHarvestOutputListener::class,
             DistributeTeamProfitListener::class,
         ],
+        HouseUpgradedEvent::class => [
+            AddLandAfterHouseUpgradeListener::class,
+        ],
     ];
 
     /**
@@ -51,7 +56,8 @@ class FarmServiceProvider extends ServiceProvider
             Commands\GenerateFarmHouseConfigJson::class,
             Commands\GenerateFarmShrineConfigJson::class,
             Commands\MigrateLandUpgradeMaterialsToConsumeGroupsCommand::class,
-            Commands\MigrateLandUpgradeConditionsToConditionGroupsCommand::class
+            Commands\MigrateLandUpgradeConditionsToConditionGroupsCommand::class,
+            Commands\InitializeUserLandsCommand::class
         ]);
 
 

+ 28 - 0
database/migrations/2025_05_22_115720_add_available_lands_to_farm_house_configs_table.php

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('farm_house_configs', function (Blueprint $table) {
+            $table->unsignedInteger('available_lands')->default(0)->comment('该等级可用的土地数量');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('farm_house_configs', function (Blueprint $table) {
+            $table->dropColumn('available_lands');
+        });
+    }
+};

+ 34 - 0
database/sql/update_farm_house_configs_available_lands.sql

@@ -0,0 +1,34 @@
+-- 更新 farm_house_configs 表,添加 available_lands 字段的初始值
+-- 根据房屋等级设置可用土地数量
+
+-- 1级房屋:1块土地
+UPDATE farm_house_configs SET available_lands = 1 WHERE level = 1;
+
+-- 2级房屋:2块土地
+UPDATE farm_house_configs SET available_lands = 2 WHERE level = 2;
+
+-- 3级房屋:3块土地
+UPDATE farm_house_configs SET available_lands = 3 WHERE level = 3;
+
+-- 4级房屋:4块土地
+UPDATE farm_house_configs SET available_lands = 4 WHERE level = 4;
+
+-- 5级房屋:5块土地
+UPDATE farm_house_configs SET available_lands = 5 WHERE level = 5;
+
+-- 6级房屋:6块土地
+UPDATE farm_house_configs SET available_lands = 6 WHERE level = 6;
+
+-- 7级房屋:7块土地
+UPDATE farm_house_configs SET available_lands = 7 WHERE level = 7;
+
+-- 8级房屋:8块土地
+UPDATE farm_house_configs SET available_lands = 8 WHERE level = 8;
+
+-- 9级房屋:9块土地
+UPDATE farm_house_configs SET available_lands = 9 WHERE level = 9;
+
+-- 10级房屋:10块土地
+UPDATE farm_house_configs SET available_lands = 10 WHERE level = 10;
+
+-- 如果有更高等级的房屋,可以继续添加