Эх сурвалжийг харах

feat(farm): 添加种子配置表刷新和同步功能

- 新增 RefreshFarmSeedJsonTool 和 SyncFarm
notfff 7 сар өмнө
parent
commit
9f2e2d5e8e

+ 103 - 0
app/Module/Farm/AdminControllers/Tools/RefreshFarmSeedJsonTool.php

@@ -0,0 +1,103 @@
+<?php
+
+namespace App\Module\Farm\AdminControllers\Tools;
+
+use App\Module\Game\DCache\FarmSeedJsonConfig;
+use Dcat\Admin\Grid\Tools\AbstractTool;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 种子配置表刷新工具
+ *
+ * 用于在后台管理界面中刷新种子配置表数据
+ */
+class RefreshFarmSeedJsonTool extends AbstractTool
+{
+    /**
+     * 是否显示按钮
+     *
+     * @var bool
+     */
+    protected $shouldDisplay;
+
+    /**
+     * 按钮样式
+     *
+     * @var string
+     */
+    protected $style = 'btn btn-danger waves-effect';
+
+    /**
+     * 构造函数
+     *
+     * @param bool $shouldDisplay 是否显示按钮
+     */
+    public function __construct(bool $shouldDisplay = true)
+    {
+        $this->shouldDisplay = $shouldDisplay;
+    }
+
+    /**
+     * 按钮标题
+     *
+     * @return string
+     */
+    public function title()
+    {
+        return '立即刷新';
+    }
+
+    /**
+     * 确认提示
+     *
+     * @return string
+     */
+    public function confirm()
+    {
+        return '确定要立即刷新种子配置JSON数据吗?';
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     * @return mixed
+     */
+    public function handle(Request $request)
+    {
+        try {
+            // 强制刷新缓存
+            FarmSeedJsonConfig::getData([], true);
+
+            return $this->response()->success('刷新成功')->refresh();
+        } catch (\Exception $e) {
+            Log::error('Refresh farm seed JSON exception: '.$e->getMessage());
+            return $this->response()->error('刷新失败:'.$e->getMessage());
+        }
+    }
+
+    /**
+     * 渲染按钮
+     *
+     * @return string
+     */
+    public function render()
+    {
+        if (!$this->shouldDisplay) {
+            return '';
+        }
+
+        return parent::render();
+    }
+
+    /**
+     * 判断是否应该显示按钮
+     *
+     * @return bool
+     */
+    public static function shouldDisplay(): bool
+    {
+        return true;
+    }
+}

+ 122 - 0
app/Module/Farm/AdminControllers/Tools/SyncFarmSeedJsonTool.php

@@ -0,0 +1,122 @@
+<?php
+
+namespace App\Module\Farm\AdminControllers\Tools;
+
+use App\Module\Game\DCache\FarmSeedJsonConfig;
+use Dcat\Admin\Grid\Tools\AbstractTool;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 种子配置表同步工具
+ *
+ * 用于在后台管理界面中同步种子配置表数据到JSON文件
+ */
+class SyncFarmSeedJsonTool extends AbstractTool
+{
+    /**
+     * 是否显示按钮
+     *
+     * @var bool
+     */
+    protected $shouldDisplay;
+
+    /**
+     * 按钮样式
+     *
+     * @var string
+     */
+    protected $style = 'btn btn-primary waves-effect';
+
+    /**
+     * 构造函数
+     *
+     * @param bool $shouldDisplay 是否显示按钮
+     */
+    public function __construct(bool $shouldDisplay = true)
+    {
+        $this->shouldDisplay = $shouldDisplay;
+    }
+
+    /**
+     * 按钮标题
+     *
+     * @return string
+     */
+    public function title()
+    {
+        return '生成JSON';
+    }
+
+    /**
+     * 确认提示
+     *
+     * @return string
+     */
+    public function confirm()
+    {
+        return '确定要生成种子配置JSON数据吗?';
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     * @return mixed
+     */
+    public function handle(Request $request)
+    {
+        try {
+            // 直接调用缓存类刷新数据,这会同时生成JSON文件
+            FarmSeedJsonConfig::getData([], true);
+
+            return $this->response()->success('生成成功')->refresh();
+        } catch (\Exception $e) {
+            Log::error('Generate farm_seed.json exception: '.$e->getMessage());
+            return $this->response()->error('生成失败:'.$e->getMessage());
+        }
+    }
+
+    /**
+     * 渲染按钮
+     *
+     * @return string
+     */
+    public function render()
+    {
+        if (!$this->shouldDisplay) {
+            return '';
+        }
+
+        return parent::render();
+    }
+
+    /**
+     * 判断是否应该显示按钮
+     *
+     * @return bool
+     */
+    public static function shouldDisplay(): bool
+    {
+        // 获取缓存数据
+        $json = FarmSeedJsonConfig::getData();
+
+        // 如果没有生成时间戳,说明需要生成
+        if (!isset($json['generated_ts'])) {
+            return true;
+        }
+
+        // 获取生成时间和最后更新时间
+        $generatedAt = \Carbon\Carbon::createFromTimestamp($json['generated_ts']);
+
+        // 获取种子和种子产出的最后更新时间
+        $lastUpdatedSeed = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmSeed::max('updated_at') ?: '2000-01-01');
+        $lastUpdatedOutput = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmSeedOutput::max('updated_at') ?: '2000-01-01');
+
+        // 取最新的更新时间
+        $lastUpdated = $lastUpdatedSeed->gt($lastUpdatedOutput) ? $lastUpdatedSeed : $lastUpdatedOutput;
+
+        // 如果生成时间早于最后更新时间,说明需要重新生成
+        return $generatedAt->lt($lastUpdated);
+    }
+}

+ 124 - 0
app/Module/Farm/Commands/GenerateFarmSeedConfigJson.php

@@ -0,0 +1,124 @@
+<?php
+
+namespace App\Module\Farm\Commands;
+
+use App\Module\Farm\Models\FarmSeed;
+use Illuminate\Console\Command;
+
+/**
+ * 生成种子配置表JSON数据命令
+ *
+ * 该命令用于从数据库中的种子表和种子产出表生成JSON数据文件,供客户端使用。
+ * 生成的JSON文件包含种子的基本信息,如种子ID、名称、类型、生长时间、产量范围、灾害抵抗等,
+ * 以及种子的产出配置信息。该命令通常在种子配置数据更新后运行,以确保客户端获取最新的配置数据。
+ */
+class GenerateFarmSeedConfigJson extends Command
+{
+    /**
+     * 命令名称
+     *
+     * @var string
+     */
+    protected $signature = 'farm:generate-seed-json';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = '生成种子配置JSON文件';
+
+    /**
+     * 生成种子配置JSON数据
+     *
+     * @return array|bool 生成的数据或失败标志
+     */
+    public static function generateJson()
+    {
+        try {
+            // 获取所有种子配置,预加载产出关联
+            $seeds = FarmSeed::with('outputs')->orderBy('id')->get();
+
+            // 准备JSON数据
+            $jsonData = [
+                'generated_ts' => time(),
+                'seeds' => []
+            ];
+
+            // 处理种子基本数据和产出数据
+            foreach ($seeds as $seed) {
+                // 获取种子的所有产出物品ID
+                $seedOutputs = [];
+                foreach ($seed->outputs as $output) {
+                    $seedOutputs[] = $output->item_id;
+                }
+
+                $jsonData['seeds'][] = [
+                    'id' => $seed->id,
+                    'name' => $seed->name,
+                    'type' => $seed->type,
+                    'seed_time' => $seed->seed_time,
+                    'sprout_time' => $seed->sprout_time,
+                    'growth_time' => $seed->growth_time,
+                    'min_output' => $seed->min_output,
+                    'max_output' => $seed->max_output,
+                    'item_id' => $seed->item_id,
+                    'disaster_resistance' => $seed->disaster_resistance,
+                    'display_attributes' => $seed->display_attributes,
+                    'seed_outputs' => $seedOutputs, // 直接在种子属性中包含产出物品ID数组
+                ];
+            }
+
+            return $jsonData;
+        } catch (\Exception $e) {
+            if (php_sapi_name() === 'cli') {
+                echo "Error: Generate farm_seed.json failed: {$e->getMessage()}\n";
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * 执行命令
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $this->info('开始生成种子配置JSON文件...');
+
+        try {
+            // 通过缓存类生成JSON
+            $result = \App\Module\Game\DCache\FarmSeedJsonConfig::getData([], true);
+
+            if ($result !== false && is_array($result)) {
+                $this->info('种子配置JSON文件生成成功');
+                $this->info('共生成 ' . count($result['seeds'] ?? []) . ' 条种子数据');
+
+                // 统计总的产出物品数量
+                $totalOutputs = 0;
+                foreach ($result['seeds'] as $seed) {
+                    $totalOutputs += count($seed['seed_outputs'] ?? []);
+                }
+                $this->info('共包含 ' . $totalOutputs . ' 个种子产出物品');
+
+                // 显示一些示例数据
+                if (!empty($result['seeds'])) {
+                    $this->info('种子示例数据:');
+                    $firstSeed = $result['seeds'][0];
+                    $this->line('  ID: ' . $firstSeed['id'] . ', 名称: ' . $firstSeed['name']);
+                    $this->line('  产出物品: [' . implode(', ', $firstSeed['seed_outputs'] ?? []) . ']');
+                }
+
+                return Command::SUCCESS;
+            } else {
+                $this->error('生成种子配置JSON文件失败');
+                return Command::FAILURE;
+            }
+        } catch (\Exception $e) {
+            $this->error('生成种子配置JSON文件失败: ' . $e->getMessage());
+            return Command::FAILURE;
+        }
+    }
+}

+ 2 - 0
app/Module/Farm/Providers/FarmServiceProvider.php

@@ -57,6 +57,8 @@ class FarmServiceProvider extends ServiceProvider
             Commands\CleanExpiredLogsCommand::class,
             Commands\GenerateFarmHouseConfigJson::class,
             Commands\GenerateFarmShrineConfigJson::class,
+            Commands\GenerateFarmLandConfigJson::class,
+            Commands\GenerateFarmSeedConfigJson::class,
             Commands\MigrateLandUpgradeMaterialsToConsumeGroupsCommand::class,
             Commands\MigrateLandUpgradeConditionsToConditionGroupsCommand::class,
             Commands\InitializeUserLandsCommand::class

+ 41 - 0
app/Module/Game/AdminControllers/GameConfigController.php

@@ -6,6 +6,7 @@ use App\Module\Game\DCache\ChestJsonConfig;
 use App\Module\Game\DCache\DismantleJsonConfig;
 use App\Module\Game\DCache\FarmHouseJsonConfig;
 use App\Module\Game\DCache\FarmLandJsonConfig;
+use App\Module\Game\DCache\FarmSeedJsonConfig;
 use App\Module\Game\DCache\FarmShrineJsonConfig;
 use App\Module\Game\DCache\FundCurrencyJsonConfig;
 use App\Module\Game\DCache\ItemJsonConfig;
@@ -18,6 +19,7 @@ use App\Module\Pet\AdminControllers\Tools\SyncPetJsonTool;
 use App\Module\Pet\AdminControllers\Tools\RefreshPetJsonTool;
 use App\Module\Farm\AdminControllers\Tools\RefreshFarmHouseJsonTool;
 use App\Module\Farm\AdminControllers\Tools\RefreshFarmLandJsonTool;
+use App\Module\Farm\AdminControllers\Tools\RefreshFarmSeedJsonTool;
 use App\Module\Farm\AdminControllers\Tools\RefreshFarmShrineJsonTool;
 use App\Module\Farm\AdminControllers\Tools\SyncFarmHouseJsonTool;
 use App\Module\Farm\AdminControllers\Tools\SyncFarmLandJsonTool;
@@ -191,6 +193,16 @@ class GameConfigController extends AdminController
                     $this->getFarmLandConfigInfo()
                 ));
 
+                // 种子配置表卡片
+                $row->column(6, $this->createConfigCard(
+                    '种子配置表',
+                    'farm_seed.json',
+                    'farm:generate-seed-json',
+                    RefreshFarmSeedJsonTool::make(),
+                    $this->getFarmSeedConfigInfo()
+                ));
+            })
+            ->body(function (Row $row) {
                 // 神像配置表卡片
                 $row->column(6, $this->createConfigCard(
                     '神像配置表',
@@ -249,6 +261,8 @@ class GameConfigController extends AdminController
             $key = 'farm_house';
         } elseif ($firstFilename === 'farm_land.json') {
             $key = 'farm_land';
+        } elseif ($firstFilename === 'farm_seed.json') {
+            $key = 'farm_seed';
         } elseif ($firstFilename === 'farm_shrine.json') {
             $key = 'farm_shrine';
         } elseif ($firstFilename === 'currencies.json') {
@@ -437,6 +451,32 @@ class GameConfigController extends AdminController
         return $info;
     }
 
+    /**
+     * 获取种子配置表信息
+     *
+     * @return array
+     */
+    protected function getFarmSeedConfigInfo()
+    {
+        $data = FarmSeedJsonConfig::getData();
+
+        // 统计总的产出物品数量
+        $totalOutputs = 0;
+        if (isset($data['seeds'])) {
+            foreach ($data['seeds'] as $seed) {
+                $totalOutputs += count($seed['seed_outputs'] ?? []);
+            }
+        }
+
+        $info = [
+            '生成时间'  => isset($data['generated_ts']) ? Datetime::ts2string($data['generated_ts']) : '未生成',
+            '种子数量' => isset($data['seeds']) ? count($data['seeds']) : 0,
+            '产出物品总数' => $totalOutputs,
+        ];
+
+        return $info;
+    }
+
     /**
      * 获取货币配置表信息
      *
@@ -508,6 +548,7 @@ class GameConfigController extends AdminController
             'pets' => [PetJsonConfig::class, '宠物配置表(旧版)'],
             'farm_house' => [FarmHouseJsonConfig::class, '农场房屋配置表'],
             'farm_land' => [FarmLandJsonConfig::class, '土地配置表'],
+            'farm_seed' => [FarmSeedJsonConfig::class, '种子配置表'],
             'farm_shrine' => [FarmShrineJsonConfig::class, '神像配置表'],
             'currencies' => [FundCurrencyJsonConfig::class, '货币配置表'],
         ];

+ 62 - 0
app/Module/Game/DCache/FarmSeedJsonConfig.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Module\Game\DCache;
+
+use App\Module\Farm\Commands\GenerateFarmSeedConfigJson;
+use App\Module\LCache\DQueueJob;
+
+/**
+ * 农场种子配置表缓存
+ */
+class FarmSeedJsonConfig extends DQueueJob
+{
+    /**
+     * 获取新数据
+     *
+     * @param array $parameter 参数
+     * @return mixed
+     */
+    static public function getNewData(array $parameter = [])
+    {
+        try {
+            return GenerateFarmSeedConfigJson::generateJson();
+        } catch (\Exception $e) {
+            // 如果生成失败,返回空数组
+            return [
+                'generated_ts' => time(),
+                'seeds' => [],
+                'seed_outputs' => []
+            ];
+        }
+    }
+
+    /**
+     * 获取缓存时间(秒)
+     *
+     * @return int
+     */
+    static public function getTtl(): int
+    {
+        return 3600; // 1小时
+    }
+
+    /**
+     * 获取防重复执行时间(秒)
+     *
+     * @return int
+     */
+    static public function getPreventDuplication(): int
+    {
+        return 600; // 10分钟
+    }
+
+    /**
+     * 获取必需参数索引
+     *
+     * @return array
+     */
+    static public function getRequiredArgIndex(): array
+    {
+        return [];
+    }
+}