Browse Source

feat(farm): 添加土地配置表生成和刷新功能

- 在 FarmLandTypeController 和 FarmLandUpgradeConfigController 中添加生成 JSON 配置表的功能
- 在 GameConfigController 中添加刷新土地配置表和货币配置表的功能
- 优化 JsonController,支持多种配置表的读取
- 更新 RefreshCheckTool,支持检查土地配置表的同步状态
Your Name 8 tháng trước cách đây
mục cha
commit
a30e356f34

+ 60 - 15
app/Module/AppGame/HttpControllers/JsonController.php

@@ -3,39 +3,84 @@
 namespace App\Module\AppGame\HttpControllers;
 
 use App\Http\Controllers\Controller;
-use App\Module\AppGame\Tools\Protobuf;
+use App\Module\Game\DCache\ChestJsonConfig;
+use App\Module\Game\DCache\FarmHouseJsonConfig;
+use App\Module\Game\DCache\FarmLandJsonConfig;
+use App\Module\Game\DCache\FundCurrencyJsonConfig;
 use App\Module\Game\DCache\ItemJsonConfig;
-use Illuminate\Http\Request as HttpRequest;
+use App\Module\Game\DCache\PetJsonConfig;
 use Illuminate\Support\Facades\Log;
-use Illuminate\Support\Str;
-use UCore\App;
 use UCore\Exception\HandleNotException;
-use UCore\Exception\ValidateException;
-use UCore\Helper\Logger;
 use Uraus\Kku\Common\RESPONSE_CODE;
-use Uraus\Kku\Request;
-use Uraus\Kku\Response;
 
 /**
- * Protobuf 控制器
  *
- * 负责处理来自客户端的 Protobuf 请求,并将其路由到相应的处理器
+ * 访问json配置表,输出配置表Json格式
+ * @package App\Module\AppGame\HttpControllers
+ *
+ *
  */
 class JsonController extends Controller
 {
 
     /**
-     * 配置表
-     * @param string $key
+     * 配置表读取
+     * @param string $key 配置表键名
      * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Foundation\Application|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response|object
      * @throws HandleNotException
      */
     public function config($key)
     {
-        $map =[
-            'items'=>ItemJsonConfig::class
+        // 配置表映射关系
+        $map = [
+            'items' => ItemJsonConfig::class,
+            'chest' => ChestJsonConfig::class,
+            'pets' => PetJsonConfig::class,
+            'farm_house' => FarmHouseJsonConfig::class,
+            'farm_land' => FarmLandJsonConfig::class,
+            'currencies' => FundCurrencyJsonConfig::class,
         ];
-        dump($key);
+
+        // 检查请求的配置表是否存在
+        if (!isset($map[$key])) {
+            return response()->json([
+                'code' => RESPONSE_CODE::REQUEST_ERROR,
+                'message' => '配置表不存在',
+                'data' => null
+            ], 400);
+        }
+
+        try {
+            // 获取配置表数据
+            $configClass = $map[$key];
+            $data = $configClass::getData();
+
+            // 如果数据为空,返回错误
+            if (empty($data)) {
+                return response()->json([
+                    'code' => RESPONSE_CODE::SERVER_ERROR,
+                    'message' => '配置表数据为空',
+                    'data' => null
+                ], 500);
+            }
+
+            // 返回配置表数据
+            return $data;
+        } catch (\Exception $e) {
+            // 记录错误日志
+            Log::error('获取配置表数据失败', [
+                'key' => $key,
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+
+            // 返回错误响应
+            return response()->json([
+                'code' => RESPONSE_CODE::SERVER_ERROR,
+                'message' => '获取配置表数据失败',
+                'data' => null
+            ], 500);
+        }
     }
 
 

+ 50 - 0
app/Module/Farm/AdminControllers/FarmLandTypeController.php

@@ -2,13 +2,19 @@
 
 namespace App\Module\Farm\AdminControllers;
 
+use App\Module\Farm\AdminControllers\Helper\FilterHelper;
+use App\Module\Farm\AdminControllers\Helper\FormHelper;
 use App\Module\Farm\AdminControllers\Helper\GridHelper;
+use App\Module\Farm\AdminControllers\Helper\ShowHelper;
+use App\Module\Farm\AdminControllers\Tools\RefreshCheckTool;
+use App\Module\Farm\AdminControllers\Tools\SyncFarmLandJsonTool;
 use App\Module\Farm\Repositories\FarmLandTypeRepository;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
 use UCore\DcatAdmin\AdminController;
 use Spatie\RouteAttributes\Attributes\Resource;
+use Spatie\RouteAttributes\Attributes\Get;
 
 /**
  * 土地类型配置管理控制器
@@ -16,6 +22,36 @@ use Spatie\RouteAttributes\Attributes\Resource;
 #[Resource('farm-land-types', names: 'dcat.admin.farm-land-types')]
 class FarmLandTypeController extends AdminController
 {
+    /**
+     * 生成土地配置JSON数据
+     */
+    #[Get('farm-land-types/generate-json')]
+    public function generateJson()
+    {
+        try {
+            // 直接调用命令生成JSON
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'farm:generate-land-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                return response()->json([
+                    'status'  => 'error',
+                    'message' => 'JSON生成失败: ' . $process->getErrorOutput()
+                ]);
+            }
+
+            return response()->json([
+                'status'  => 'success',
+                'message' => 'JSON生成成功'
+            ]);
+        } catch (\Exception $e) {
+            return response()->json([
+                'status'  => 'error',
+                'message' => 'JSON生成失败: ' . $e->getMessage()
+            ]);
+        }
+    }
     /**
      * 页面标题
      *
@@ -40,6 +76,20 @@ class FarmLandTypeController extends AdminController
         return Grid::make(new FarmLandTypeRepository(), function (Grid $grid) {
             $helper = new GridHelper($grid, $this);
 
+            // 检查配置表状态
+            $status = RefreshCheckTool::checkSyncStatus('land');
+
+            if ($status['is_synced']) {
+                admin_success('JSON配置表状态', $status['message']);
+            } else {
+                admin_warning('JSON配置表状态', $status['message']);
+            }
+
+            // 添加工具按钮
+            $grid->tools([
+                new SyncFarmLandJsonTool()
+            ]);
+
             $grid->column('id', 'ID')->sortable();
             $grid->column('name', '名称')->sortable();
             $grid->column('code', '编码')->sortable();

+ 16 - 0
app/Module/Farm/AdminControllers/FarmLandUpgradeConfigController.php

@@ -6,6 +6,8 @@ use App\Module\Farm\AdminControllers\Helper\FilterHelper;
 use App\Module\Farm\AdminControllers\Helper\FormHelper;
 use App\Module\Farm\AdminControllers\Helper\GridHelper;
 use App\Module\Farm\AdminControllers\Helper\ShowHelper;
+use App\Module\Farm\AdminControllers\Tools\RefreshCheckTool;
+use App\Module\Farm\AdminControllers\Tools\SyncFarmLandJsonTool;
 use App\Module\Farm\Repositories\FarmLandTypeRepository;
 use App\Module\Farm\Repositories\FarmLandUpgradeConfigRepository;
 use Dcat\Admin\Form;
@@ -44,6 +46,20 @@ class FarmLandUpgradeConfigController extends AdminController
         return Grid::make(new FarmLandUpgradeConfigRepository(), function (Grid $grid) {
             $helper = new GridHelper($grid, $this);
 
+            // 检查配置表状态
+            $status = RefreshCheckTool::checkSyncStatus('land');
+
+            if ($status['is_synced']) {
+                admin_success('JSON配置表状态', $status['message']);
+            } else {
+                admin_warning('JSON配置表状态', $status['message']);
+            }
+
+            // 添加工具按钮
+            $grid->tools([
+                new SyncFarmLandJsonTool()
+            ]);
+
             $helper->columnId();
             $grid->column('from_type_id', '起始土地类型ID')->sortable();
             $grid->column('to_type_id', '目标土地类型ID')->sortable();

+ 103 - 6
app/Module/Farm/AdminControllers/Tools/RefreshCheckTool.php

@@ -3,6 +3,7 @@
 namespace App\Module\Farm\AdminControllers\Tools;
 
 use App\Module\Game\DCache\FarmHouseJsonConfig;
+use App\Module\Game\DCache\FarmLandJsonConfig;
 use Dcat\Admin\Grid\Tools\AbstractTool;
 use Illuminate\Support\Facades\Log;
 
@@ -30,27 +31,71 @@ class RefreshCheckTool extends AbstractTool
         return parent::render();
     }
 
-    public static function checkSyncStatus(): array
+    /**
+     * 检查配置表同步状态
+     *
+     * @param string $type 配置表类型,可选值:house, land, all
+     * @return array
+     */
+    public static function checkSyncStatus(string $type = 'house'): array
     {
+        if ($type === 'house') {
+            return self::checkHouseConfigStatus();
+        } elseif ($type === 'land') {
+            return self::checkLandConfigStatus();
+        } else {
+            // 检查所有配置表
+            $houseStatus = self::checkHouseConfigStatus();
+            $landStatus = self::checkLandConfigStatus();
 
+            // 如果都已同步,返回成功状态
+            if ($houseStatus['is_synced'] && $landStatus['is_synced']) {
+                return [
+                    'is_synced' => true,
+                    'message' => '所有配置表已同步',
+                    'should_display' => false
+                ];
+            }
 
+            // 否则返回需要同步的状态
+            $message = '';
+            if (!$houseStatus['is_synced']) {
+                $message .= '房屋配置表需要同步; ';
+            }
+            if (!$landStatus['is_synced']) {
+                $message .= '土地配置表需要同步; ';
+            }
 
-        try {
-            $json = FarmHouseJsonConfig::getData([],true);
+            return [
+                'is_synced' => false,
+                'message' => $message,
+                'should_display' => true
+            ];
+        }
+    }
 
+    /**
+     * 检查房屋配置表状态
+     *
+     * @return array
+     */
+    private static function checkHouseConfigStatus(): array
+    {
+        try {
+            $json = FarmHouseJsonConfig::getData();
             $generatedAt = \Carbon\Carbon::createFromTimestamp($json['generated_ts']);
             $lastUpdated = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmHouseConfig::max('updated_at'));
 
             if ($generatedAt->lt($lastUpdated)) {
                 return [
                     'is_synced' => false,
-                    'message' => "配置文件需要更新(生成于 {$generatedAt->format('Y-m-d H:i:s')},最后修改于 {$lastUpdated->format('Y-m-d H:i:s')})",
+                    'message' => "房屋配置表需要更新(生成于 {$generatedAt->format('Y-m-d H:i:s')},最后修改于 {$lastUpdated->format('Y-m-d H:i:s')})",
                     'should_display' => true
                 ];
             } else {
                 return [
                     'is_synced' => true,
-                    'message' => "配置文件已是最新(生成于 {$generatedAt->format('Y-m-d H:i:s')})",
+                    'message' => "房屋配置表已是最新(生成于 {$generatedAt->format('Y-m-d H:i:s')})",
                     'should_display' => false
                 ];
             }
@@ -59,7 +104,59 @@ class RefreshCheckTool extends AbstractTool
 
             return [
                 'is_synced' => false,
-                'message' => '检查配置文件状态失败:'.$e->getMessage(),
+                'message' => '检查房屋配置表状态失败:'.$e->getMessage(),
+                'should_display' => true
+            ];
+        }
+    }
+
+    /**
+     * 检查土地配置表状态
+     *
+     * @return array
+     */
+    private static function checkLandConfigStatus(): array
+    {
+        try {
+            $json = FarmLandJsonConfig::getData();
+
+            // 如果没有生成时间戳,说明需要生成
+            if (!isset($json['generated_ts'])) {
+                return [
+                    'is_synced' => false,
+                    'message' => '土地配置表需要生成',
+                    'should_display' => true
+                ];
+            }
+
+            $generatedAt = \Carbon\Carbon::createFromTimestamp($json['generated_ts']);
+
+            // 获取土地类型和升级配置的最后更新时间
+            $lastUpdatedType = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmLandType::max('updated_at') ?: '2000-01-01');
+            $lastUpdatedUpgrade = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmLandUpgradeConfig::max('updated_at') ?: '2000-01-01');
+
+            // 取最新的更新时间
+            $lastUpdated = $lastUpdatedType->gt($lastUpdatedUpgrade) ? $lastUpdatedType : $lastUpdatedUpgrade;
+
+            if ($generatedAt->lt($lastUpdated)) {
+                return [
+                    'is_synced' => false,
+                    'message' => "土地配置表需要更新(生成于 {$generatedAt->format('Y-m-d H:i:s')},最后修改于 {$lastUpdated->format('Y-m-d H:i:s')})",
+                    'should_display' => true
+                ];
+            } else {
+                return [
+                    'is_synced' => true,
+                    'message' => "土地配置表已是最新(生成于 {$generatedAt->format('Y-m-d H:i:s')})",
+                    'should_display' => false
+                ];
+            }
+        } catch (\Exception $e) {
+            Log::error('Check farm land config sync status failed: '.$e->getMessage());
+
+            return [
+                'is_synced' => false,
+                'message' => '检查土地配置表状态失败:'.$e->getMessage(),
                 'should_display' => true
             ];
         }

+ 132 - 0
app/Module/Farm/AdminControllers/Tools/SyncFarmLandJsonTool.php

@@ -0,0 +1,132 @@
+<?php
+
+namespace App\Module\Farm\AdminControllers\Tools;
+
+use App\Module\Game\DCache\FarmLandJsonConfig;
+use Dcat\Admin\Grid\Tools\AbstractTool;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 土地配置表同步工具
+ * 
+ * 用于在后台管理界面中同步土地配置表数据到JSON文件
+ */
+class SyncFarmLandJsonTool 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
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'farm:generate-land-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                Log::error('Generate farm_land.json failed: ' . $process->getErrorOutput());
+                return $this->response()->error('生成失败:' . $process->getErrorOutput());
+            }
+
+            // 强制刷新缓存
+            FarmLandJsonConfig::getData([], true);
+
+            return $this->response()->success('生成成功')->refresh();
+        } catch (\Exception $e) {
+            Log::error('Generate farm_land.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 = FarmLandJsonConfig::getData();
+        
+        // 如果没有生成时间戳,说明需要生成
+        if (!isset($json['generated_ts'])) {
+            return true;
+        }
+        
+        // 获取生成时间和最后更新时间
+        $generatedAt = \Carbon\Carbon::createFromTimestamp($json['generated_ts']);
+        
+        // 获取土地类型和升级配置的最后更新时间
+        $lastUpdatedType = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmLandType::max('updated_at') ?: '2000-01-01');
+        $lastUpdatedUpgrade = \Carbon\Carbon::parse(\App\Module\Farm\Models\FarmLandUpgradeConfig::max('updated_at') ?: '2000-01-01');
+        
+        // 取最新的更新时间
+        $lastUpdated = $lastUpdatedType->gt($lastUpdatedUpgrade) ? $lastUpdatedType : $lastUpdatedUpgrade;
+
+        // 如果生成时间早于最后更新时间,说明需要重新生成
+        return $generatedAt->lt($lastUpdated);
+    }
+}

+ 116 - 0
app/Module/Farm/Commands/GenerateFarmLandConfigJson.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Module\Farm\Commands;
+
+use App\Module\Farm\Models\FarmLandType;
+use App\Module\Farm\Models\FarmLandUpgradeConfig;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 生成土地配置表JSON数据命令
+ *
+ * 该命令用于从数据库中的土地类型表和土地升级配置表生成JSON数据文件,供客户端使用。
+ * 生成的JSON文件包含土地类型的基本信息,如类型ID、名称、产量加成、灾害抵抗等,以及土地升级路径和所需材料。
+ * 该命令通常在土地配置数据更新后运行,以确保客户端获取最新的配置数据。
+ */
+class GenerateFarmLandConfigJson extends Command
+{
+    /**
+     * 命令名称
+     *
+     * @var string
+     */
+    protected $signature = 'farm:generate-land-json';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = '生成土地配置JSON文件';
+
+    /**
+     * 生成土地配置JSON数据
+     *
+     * @return array|bool 生成的数据或失败标志
+     */
+    public static function generateJson()
+    {
+        try {
+            // 获取所有土地类型
+            $landTypes = FarmLandType::orderBy('id')->get();
+            
+            // 获取所有土地升级配置
+            $upgradeConfigs = FarmLandUpgradeConfig::with(['fromType', 'toType'])->get();
+
+            // 准备JSON数据
+            $jsonData = [
+                'generated_ts' => time(),
+                'land_types' => [],
+                'upgrade_paths' => []
+            ];
+
+            // 处理土地类型数据
+            foreach ($landTypes as $type) {
+                $jsonData['land_types'][] = [
+                    'id' => $type->id,
+                    'name' => $type->name,
+                    'code' => $type->code,
+                    'output_bonus' => $type->output_bonus,
+                    'disaster_resistance' => $type->disaster_resistance,
+                    'unlock_house_level' => $type->unlock_house_level,
+                    'is_special' => $type->is_special,
+                    'icon' => $type->icon,
+                    'description' => $type->description,
+                ];
+            }
+
+            // 处理土地升级路径数据
+            foreach ($upgradeConfigs as $config) {
+                $jsonData['upgrade_paths'][] = [
+                    'from_type_id' => $config->from_type_id,
+                    'to_type_id' => $config->to_type_id,
+                    'materials' => $config->materials,
+                    'conditions' => $config->conditions,
+                ];
+            }
+
+            return $jsonData;
+        } catch (\Exception $e) {
+            if (php_sapi_name() === 'cli') {
+                echo "Error: Generate farm_land.json failed: {$e->getMessage()}\n";
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * 执行命令
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $this->info('开始生成土地配置JSON文件...');
+
+        try {
+            // 直接调用静态方法生成JSON,而不通过缓存类
+            $result = self::generateJson();
+
+            if ($result !== false) {
+                $this->info('土地配置JSON文件生成成功');
+                $this->info('共生成 ' . count($result['land_types']) . ' 条土地类型数据');
+                $this->info('共生成 ' . count($result['upgrade_paths']) . ' 条升级路径数据');
+                return Command::SUCCESS;
+            } else {
+                $this->error('生成土地配置JSON文件失败');
+                return Command::FAILURE;
+            }
+        } catch (\Exception $e) {
+            $this->error('生成土地配置JSON文件失败: ' . $e->getMessage());
+            return Command::FAILURE;
+        }
+    }
+}

+ 192 - 0
app/Module/Fund/AdminControllers/FundCurrencyController.php

@@ -0,0 +1,192 @@
+<?php
+
+namespace App\Module\Fund\AdminControllers;
+
+use App\Module\Fund\AdminControllers\Helper\FormHelper;
+use App\Module\Fund\AdminControllers\Helper\GridHelper;
+use App\Module\Fund\AdminControllers\Helper\ShowHelper;
+use App\Module\Fund\AdminControllers\Tools\SyncFundCurrencyJsonTool;
+use App\Module\Fund\Repositorys\FundCurrencyRepository;
+use Dcat\Admin\Form;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Show;
+use UCore\DcatAdmin\AdminController;
+use Spatie\RouteAttributes\Attributes\Resource;
+use Spatie\RouteAttributes\Attributes\Get;
+
+/**
+ * 货币配置控制器
+ */
+#[Resource('fund-currencies', names: 'dcat.admin.fund-currencies')]
+class FundCurrencyController extends AdminController
+{
+    /**
+     * 页面标题
+     *
+     * @var string
+     */
+    protected $title = '货币配置';
+
+    /**
+     * 生成货币配置JSON数据
+     */
+    #[Get('fund-currencies/generate-json')]
+    public function generateJson()
+    {
+        try {
+            // 直接调用命令生成JSON
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'fund:generate-currency-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                return response()->json([
+                    'status'  => 'error',
+                    'message' => 'JSON生成失败: ' . $process->getErrorOutput()
+                ]);
+            }
+
+            return response()->json([
+                'status'  => 'success',
+                'message' => 'JSON生成成功'
+            ]);
+        } catch (\Exception $e) {
+            return response()->json([
+                'status'  => 'error',
+                'message' => 'JSON生成失败: ' . $e->getMessage()
+            ]);
+        }
+    }
+
+    /**
+     * 列表页
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        return Grid::make(new FundCurrencyRepository(), function (Grid $grid) {
+            $helper = new GridHelper($grid, $this);
+            
+            // 检查配置表状态
+            $status = SyncFundCurrencyJsonTool::shouldDisplay();
+            
+            if ($status) {
+                admin_warning('JSON配置表状态', '货币配置表需要更新');
+            } else {
+                admin_success('JSON配置表状态', '货币配置表已是最新');
+            }
+            
+            // 添加工具按钮
+            $grid->tools([
+                new SyncFundCurrencyJsonTool()
+            ]);
+
+            $helper->columnId();
+            $grid->column('identification', '货币标识')->sortable();
+            $grid->column('name', '货币名称')->sortable();
+            $grid->column('icon', '图标')->image('', 40, 40);
+            $grid->column('data1', '额外数据')->display(function ($value) {
+                if (empty($value)) {
+                    return '-';
+                }
+                $data = json_decode($value, true);
+                return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+            });
+            $grid->column('create_time', '创建时间')->display(function ($value) {
+                return date('Y-m-d H:i:s', $value);
+            })->sortable();
+            $grid->column('update_time', '更新时间')->display(function ($value) {
+                return date('Y-m-d H:i:s', $value);
+            })->sortable();
+
+            // 筛选器
+            $grid->filter(function (Grid\Filter $filter) {
+                $filter->equal('id', 'ID');
+                $filter->like('identification', '货币标识');
+                $filter->like('name', '货币名称');
+            });
+        });
+    }
+
+    /**
+     * 详情页
+     *
+     * @param mixed $id
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        return Show::make($id, new FundCurrencyRepository(), function (Show $show) {
+            $helper = new ShowHelper($show, $this);
+            
+            $show->field('id', 'ID');
+            $show->field('identification', '货币标识');
+            $show->field('name', '货币名称');
+            $show->field('icon', '图标')->image();
+            $show->field('data1', '额外数据')->json();
+            $show->field('create_time', '创建时间')->as(function ($value) {
+                return date('Y-m-d H:i:s', $value);
+            });
+            $show->field('update_time', '更新时间')->as(function ($value) {
+                return date('Y-m-d H:i:s', $value);
+            });
+        });
+    }
+
+    /**
+     * 表单
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        return Form::make(new FundCurrencyRepository(), function (Form $form) {
+            $helper = new FormHelper($form, $this);
+            
+            $form->display('id', 'ID');
+            $form->text('identification', '货币标识')
+                ->required()
+                ->maxLength(10)
+                ->help('货币的唯一标识符,最多10个字符');
+                
+            $form->text('name', '货币名称')
+                ->required()
+                ->maxLength(30)
+                ->help('货币的显示名称,最多30个字符');
+                
+            $form->image('icon', '图标')
+                ->required()
+                ->autoUpload()
+                ->uniqueName()
+                ->help('货币的图标,建议尺寸64x64像素');
+                
+            $form->textarea('data1', '额外数据')
+                ->help('额外的货币属性,JSON格式');
+                
+            // 保存前处理
+            $form->saving(function (Form $form) {
+                // 设置时间戳
+                if ($form->isCreating()) {
+                    $form->create_time = time();
+                }
+                $form->update_time = time();
+                
+                // 验证额外数据是否为有效的JSON
+                if (!empty($form->data1)) {
+                    $data = json_decode($form->data1, true);
+                    if (json_last_error() !== JSON_ERROR_NONE) {
+                        return $form->response()->error('额外数据必须是有效的JSON格式');
+                    }
+                    $form->data1 = json_encode($data);
+                }
+            });
+            
+            // 保存后处理
+            $form->saved(function (Form $form) {
+                // 提示用户更新JSON配置
+                admin_toastr('货币配置已保存,请点击"生成JSON"按钮更新配置文件', 'info');
+            });
+        });
+    }
+}

+ 128 - 0
app/Module/Fund/AdminControllers/Tools/SyncFundCurrencyJsonTool.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace App\Module\Fund\AdminControllers\Tools;
+
+use App\Module\Game\DCache\FundCurrencyJsonConfig;
+use Dcat\Admin\Grid\Tools\AbstractTool;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 货币配置表同步工具
+ * 
+ * 用于在后台管理界面中同步货币配置表数据到JSON文件
+ */
+class SyncFundCurrencyJsonTool 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
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'fund:generate-currency-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                Log::error('Generate fund_currency.json failed: ' . $process->getErrorOutput());
+                return $this->response()->error('生成失败:' . $process->getErrorOutput());
+            }
+
+            // 强制刷新缓存
+            FundCurrencyJsonConfig::getData([], true);
+
+            return $this->response()->success('生成成功')->refresh();
+        } catch (\Exception $e) {
+            Log::error('Generate fund_currency.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 = FundCurrencyJsonConfig::getData();
+        
+        // 如果没有生成时间戳,说明需要生成
+        if (!isset($json['generated_ts'])) {
+            return true;
+        }
+        
+        // 获取生成时间和最后更新时间
+        $generatedAt = \Carbon\Carbon::createFromTimestamp($json['generated_ts']);
+        
+        // 获取货币配置的最后更新时间
+        $lastUpdated = \Carbon\Carbon::parse(\App\Module\Fund\Models\FundCurrencyModel::max('update_time') ?: '2000-01-01');
+        
+        // 如果生成时间早于最后更新时间,说明需要重新生成
+        return $generatedAt->lt($lastUpdated);
+    }
+}

+ 104 - 0
app/Module/Fund/Commands/GenerateFundCurrencyConfigJson.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace App\Module\Fund\Commands;
+
+use App\Module\Fund\Models\FundCurrencyModel;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 生成货币配置表JSON数据命令
+ *
+ * 该命令用于从数据库中的货币配置表生成JSON数据文件,供客户端使用。
+ * 生成的JSON文件包含货币的基本信息,如ID、名称、标识、图标等。
+ * 该命令通常在货币配置数据更新后运行,以确保客户端获取最新的配置数据。
+ */
+class GenerateFundCurrencyConfigJson extends Command
+{
+    /**
+     * 命令名称
+     *
+     * @var string
+     */
+    protected $signature = 'fund:generate-currency-json';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = '生成货币配置JSON文件';
+
+    /**
+     * 生成货币配置JSON数据
+     *
+     * @return array|bool 生成的数据或失败标志
+     */
+    public static function generateJson()
+    {
+        try {
+            // 获取所有货币配置
+            $currencies = FundCurrencyModel::orderBy('id')->get();
+
+            // 准备JSON数据
+            $jsonData = [
+                'generated_ts' => time(),
+                'currencies' => []
+            ];
+
+            foreach ($currencies as $currency) {
+                $currencyData = [
+                    'id' => $currency->id,
+                    'identification' => $currency->identification,
+                    'name' => $currency->name,
+                    'icon' => $currency->icon,
+                ];
+
+                // 如果有额外数据,解析并添加
+                if (!empty($currency->data1)) {
+                    $extraData = json_decode($currency->data1, true);
+                    if (is_array($extraData)) {
+                        $currencyData['extra_data'] = $extraData;
+                    }
+                }
+
+                $jsonData['currencies'][] = $currencyData;
+            }
+
+            return $jsonData;
+        } catch (\Exception $e) {
+            if (php_sapi_name() === 'cli') {
+                echo "Error: Generate fund_currency.json failed: {$e->getMessage()}\n";
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * 执行命令
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $this->info('开始生成货币配置JSON文件...');
+
+        try {
+            // 直接调用静态方法生成JSON,而不通过缓存类
+            $result = self::generateJson();
+
+            if ($result !== false) {
+                $this->info('货币配置JSON文件生成成功');
+                $this->info('共生成 ' . count($result['currencies']) . ' 条货币配置数据');
+                return Command::SUCCESS;
+            } else {
+                $this->error('生成货币配置JSON文件失败');
+                return Command::FAILURE;
+            }
+        } catch (\Exception $e) {
+            $this->error('生成货币配置JSON文件失败: ' . $e->getMessage());
+            return Command::FAILURE;
+        }
+    }
+}

+ 19 - 0
app/Module/Fund/Repositorys/FundCurrencyRepository.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Module\Fund\Repositorys;
+
+use App\Module\Fund\Models\FundCurrencyModel;
+use Dcat\Admin\Repositories\EloquentRepository;
+
+/**
+ * 货币配置仓库
+ */
+class FundCurrencyRepository extends EloquentRepository
+{
+    /**
+     * 关联的模型类
+     *
+     * @var string
+     */
+    protected $eloquentClass = FundCurrencyModel::class;
+}

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

@@ -4,6 +4,8 @@ namespace App\Module\Game\AdminControllers;
 
 use App\Module\Game\DCache\ChestJsonConfig;
 use App\Module\Game\DCache\FarmHouseJsonConfig;
+use App\Module\Game\DCache\FarmLandJsonConfig;
+use App\Module\Game\DCache\FundCurrencyJsonConfig;
 use App\Module\Game\DCache\ItemJsonConfig;
 use App\Module\Game\DCache\PetJsonConfig;
 use App\Module\GameItems\AdminControllers\Tools\RefreshCheckTool;
@@ -30,6 +32,76 @@ use UCore\Helper\Datetime;
 #[Resource('game-jsonconfigs', names: 'dcat.admin.game-jsonconfigs')]
 class GameConfigController extends AdminController
 {
+    /**
+     * 刷新货币配置表
+     *
+     * @return \Illuminate\Http\JsonResponse
+     */
+    #[Get('game-jsonconfigs/refresh-currencies')]
+    public function refreshCurrencies()
+    {
+        try {
+            // 调用命令生成JSON
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'fund:generate-currency-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                return response()->json([
+                    'status' => 'error',
+                    'message' => '刷新失败: ' . $process->getErrorOutput()
+                ]);
+            }
+
+            // 强制刷新缓存
+            FundCurrencyJsonConfig::getData([], true);
+
+            return response()->json([
+                'status' => 'success',
+                'message' => '刷新成功'
+            ]);
+        } catch (\Exception $e) {
+            return response()->json([
+                'status' => 'error',
+                'message' => '刷新失败: ' . $e->getMessage()
+            ]);
+        }
+    }
+    /**
+     * 刷新土地配置表
+     *
+     * @return \Illuminate\Http\JsonResponse
+     */
+    #[Get('game-jsonconfigs/refresh-farm-land')]
+    public function refreshFarmLand()
+    {
+        try {
+            // 调用命令生成JSON
+            $process = new \Symfony\Component\Process\Process(['php', 'artisan', 'farm:generate-land-json']);
+            $process->setWorkingDirectory(base_path());
+            $process->run();
+
+            if (!$process->isSuccessful()) {
+                return response()->json([
+                    'status' => 'error',
+                    'message' => '刷新失败: ' . $process->getErrorOutput()
+                ]);
+            }
+
+            // 强制刷新缓存
+            FarmLandJsonConfig::getData([], true);
+
+            return response()->json([
+                'status' => 'success',
+                'message' => '刷新成功'
+            ]);
+        } catch (\Exception $e) {
+            return response()->json([
+                'status' => 'error',
+                'message' => '刷新失败: ' . $e->getMessage()
+            ]);
+        }
+    }
 
     /**
      * 页面标题
@@ -94,6 +166,25 @@ class GameConfigController extends AdminController
                     'game-jsonconfigs/refresh-farm-house',
                     $this->getFarmHouseConfigInfo()
                 ));
+            })
+            ->body(function (Row $row) {
+                // 土地配置表卡片
+                $row->column(6, $this->createConfigCard(
+                    '土地配置表',
+                    'farm_land.json',
+                    'farm:generate-land-json',
+                    'game-jsonconfigs/refresh-farm-land',
+                    $this->getFarmLandConfigInfo()
+                ));
+
+                // 货币配置表卡片
+                $row->column(6, $this->createConfigCard(
+                    '货币配置表',
+                    'currencies.json',
+                    'fund:generate-currency-json',
+                    'game-jsonconfigs/refresh-currencies',
+                    $this->getFundCurrencyConfigInfo()
+                ));
             });
     }
 
@@ -196,5 +287,38 @@ class GameConfigController extends AdminController
         return $info;
     }
 
+    /**
+     * 获取土地配置表信息
+     *
+     * @return array
+     */
+    protected function getFarmLandConfigInfo()
+    {
+        $data = FarmLandJsonConfig::getData();
+        $info = [
+            '生成时间'  => Datetime::ts2string($data['generated_ts']),
+            '土地类型数量' => isset($data['land_types']) ? count($data['land_types']) : 0,
+            '升级路径数量' => isset($data['upgrade_paths']) ? count($data['upgrade_paths']) : 0,
+        ];
+
+        return $info;
+    }
+
+    /**
+     * 获取货币配置表信息
+     *
+     * @return array
+     */
+    protected function getFundCurrencyConfigInfo()
+    {
+        $data = FundCurrencyJsonConfig::getData();
+        $info = [
+            '生成时间'  => Datetime::ts2string($data['generated_ts']),
+            '货币数量' => isset($data['currencies']) ? count($data['currencies']) : 0,
+        ];
+
+        return $info;
+    }
+
 
 }

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

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Module\Game\DCache;
+
+use App\Module\Farm\Commands\GenerateFarmLandConfigJson;
+use App\Module\LCache\DQueueJob;
+
+/**
+ * 农场土地配置表缓存
+ */
+class FarmLandJsonConfig extends DQueueJob
+{
+    /**
+     * 获取新数据
+     *
+     * @param array $parameter 参数
+     * @return mixed
+     */
+    static public function getNewData(array $parameter = [])
+    {
+        try {
+            return GenerateFarmLandConfigJson::generateJson();
+        } catch (\Exception $e) {
+            // 如果生成失败,返回空数组
+            return [
+                'generated_ts' => time(),
+                'land_types' => [],
+                'upgrade_paths' => []
+            ];
+        }
+    }
+
+    /**
+     * 获取缓存时间(秒)
+     *
+     * @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 [];
+    }
+}

+ 61 - 0
app/Module/Game/DCache/FundCurrencyJsonConfig.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Module\Game\DCache;
+
+use App\Module\Fund\Commands\GenerateFundCurrencyConfigJson;
+use App\Module\LCache\DQueueJob;
+
+/**
+ * 货币配置表缓存
+ */
+class FundCurrencyJsonConfig extends DQueueJob
+{
+    /**
+     * 获取新数据
+     *
+     * @param array $parameter 参数
+     * @return mixed
+     */
+    static public function getNewData(array $parameter = [])
+    {
+        try {
+            return GenerateFundCurrencyConfigJson::generateJson();
+        } catch (\Exception $e) {
+            // 如果生成失败,返回空数组
+            return [
+                'generated_ts' => time(),
+                'currencies' => []
+            ];
+        }
+    }
+
+    /**
+     * 获取缓存时间(秒)
+     *
+     * @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 [];
+    }
+}