Your Name 8 tháng trước cách đây
mục cha
commit
aa8c1599af

+ 80 - 86
app/Module/GameItems/AdminControllers/CategoryController.php

@@ -53,28 +53,26 @@ class CategoryController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemCategory());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('name', '名称');
-        $grid->column('code', '编码');
-        $grid->column('icon', '图标')->image('', 50, 50);
-        $grid->column('sort', '排序')->sortable();
-        $grid->column('parent.name', '父分类');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->like('name', '名称');
-            $filter->like('code', '编码');
-            $filter->equal('parent_id', '父分类')->select(
-                ItemCategory::pluck('name', 'id')
-            );
+        return Grid::make(new ItemCategory(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('name', '名称');
+            $grid->column('code', '编码');
+            $grid->column('icon', '图标')->image('', 50, 50);
+            $grid->column('sort', '排序')->sortable();
+            $grid->column('parent.name', '父分类');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->like('name', '名称');
+                $filter->like('code', '编码');
+                $filter->equal('parent_id', '父分类')->select(
+                    ItemCategory::pluck('name', 'id')
+                );
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -85,38 +83,36 @@ class CategoryController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemCategory::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('name', '名称');
-        $show->field('code', '编码');
-        $show->field('icon', '图标')->image();
-        $show->field('sort', '排序');
-        $show->field('parent.name', '父分类');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        // 显示子分类
-        $show->children('子分类', function ($children) {
-            $children->resource('/admin/game-items-categories');
-            $children->id('ID');
-            $children->name('名称');
-            $children->code('编码');
-            $children->icon('图标')->image('', 50, 50);
-            $children->sort('排序');
-        });
+        return Show::make(ItemCategory::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('name', '名称');
+            $show->field('code', '编码');
+            $show->field('icon', '图标')->image();
+            $show->field('sort', '排序');
+            $show->field('parent.name', '父分类');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+
+            // 显示子分类
+            $show->children('子分类', function ($children) {
+                $children->resource('/admin/game-items-categories');
+                $children->id('ID');
+                $children->name('名称');
+                $children->code('编码');
+                $children->icon('图标')->image('', 50, 50);
+                $children->sort('排序');
+            });
 
-        // 显示分类下的物品
-        $show->items('物品', function ($items) {
-            $items->resource('/admin/game-items');
-            $items->id('ID');
-            $items->name('名称');
-            $items->icon('图标')->image('', 50, 50);
-            $items->type('类型');
-            $items->rarity('稀有度');
+            // 显示分类下的物品
+            $show->items('物品', function ($items) {
+                $items->resource('/admin/game-items');
+                $items->id('ID');
+                $items->name('名称');
+                $items->icon('图标')->image('', 50, 50);
+                $items->type('类型');
+                $items->rarity('稀有度');
+            });
         });
-
-        return $show;
     }
 
     /**
@@ -126,45 +122,43 @@ class CategoryController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemCategory());
-
-        $form->text('name', '名称')->required();
-        $form->text('code', '编码')->required()->help('用于系统识别的唯一编码');
-        $form->image('icon', '图标')
-            ->uniqueName()
-            ->autoUpload();
-        $form->number('sort', '排序')
-            ->default(0)
-            ->help('数字越小越靠前');
-
-        // 父分类选择,排除自己及其子分类
-        $form->select('parent_id', '父分类')
-            ->options(function () use ($form) {
-                $categories = ItemCategory::all();
-                $options = [0 => '无'];
-
-                // 如果是编辑状态,需要排除自己及其子分类
-                if ($form->isEditing()) {
-                    $id = $form->getKey();
-                    $childrenIds = $this->getChildrenIds($id);
-                    $childrenIds[] = $id;
-
-                    foreach ($categories as $category) {
-                        if (!in_array($category->id, $childrenIds)) {
+        return Form::make(new ItemCategory(), function (Form $form) {
+            $form->text('name', '名称')->required();
+            $form->text('code', '编码')->required()->help('用于系统识别的唯一编码');
+            $form->image('icon', '图标')
+                ->uniqueName()
+                ->autoUpload();
+            $form->number('sort', '排序')
+                ->default(0)
+                ->help('数字越小越靠前');
+
+            // 父分类选择,排除自己及其子分类
+            $form->select('parent_id', '父分类')
+                ->options(function () use ($form) {
+                    $categories = ItemCategory::all();
+                    $options = [0 => '无'];
+
+                    // 如果是编辑状态,需要排除自己及其子分类
+                    if ($form->isEditing()) {
+                        $id = $form->getKey();
+                        $childrenIds = $this->getChildrenIds($id);
+                        $childrenIds[] = $id;
+
+                        foreach ($categories as $category) {
+                            if (!in_array($category->id, $childrenIds)) {
+                                $options[$category->id] = $category->name;
+                            }
+                        }
+                    } else {
+                        foreach ($categories as $category) {
                             $options[$category->id] = $category->name;
                         }
                     }
-                } else {
-                    foreach ($categories as $category) {
-                        $options[$category->id] = $category->name;
-                    }
-                }
 
-                return $options;
-            })
-            ->default(0);
-
-        return $form;
+                    return $options;
+                })
+                ->default(0);
+        });
     }
 
     /**

+ 98 - 103
app/Module/GameItems/AdminControllers/ChestContentController.php

@@ -5,6 +5,7 @@ namespace App\Module\GameItems\AdminControllers;
 use App\Module\GameItems\Enums\ITEM_TYPE;
 use App\Module\GameItems\Models\ItemChestContent;
 use App\Module\GameItems\Models\ItemGroup;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
@@ -28,36 +29,34 @@ class ChestContentController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemChestContent());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('chest.name', '宝箱名称');
-        $grid->column('item.name', '物品名称');
-        $grid->column('group.name', '物品组名称');
-        $grid->column('min_quantity', '最小数量');
-        $grid->column('max_quantity', '最大数量');
-        $grid->column('weight', '权重');
-        $grid->column('allow_duplicate', '允许重复')->bool();
-        $grid->column('pity_count', '保底次数');
-        $grid->column('pity_weight_factor', '保底权重因子');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('chest_id', '宝箱')->select(
-                ItemItem::where('type', ITEM_TYPE::OPENABLE)->pluck('name', 'id')
-            );
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('group_id', '物品组')->select(
-                ItemGroup::pluck('name', 'id')
-            );
+        return Grid::make(new ItemChestContent(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('chest.name', '宝箱名称');
+            $grid->column('item.name', '物品名称');
+            $grid->column('group.name', '物品组名称');
+            $grid->column('min_quantity', '最小数量');
+            $grid->column('max_quantity', '最大数量');
+            $grid->column('weight', '权重');
+            $grid->column('allow_duplicate', '允许重复')->bool();
+            $grid->column('pity_count', '保底次数');
+            $grid->column('pity_weight_factor', '保底权重因子');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('chest_id', '宝箱')->select(
+                    ItemItem::where('type', ITEM_TYPE::OPENABLE)->pluck('name', 'id')
+                );
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('group_id', '物品组')->select(
+                    ItemGroup::pluck('name', 'id')
+                );
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -68,24 +67,22 @@ class ChestContentController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemChestContent::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('chest.name', '宝箱名称');
-        $show->field('item.name', '物品名称');
-        $show->field('group.name', '物品组名称');
-        $show->field('min_quantity', '最小数量');
-        $show->field('max_quantity', '最大数量');
-        $show->field('weight', '权重');
-        $show->field('allow_duplicate', '允许重复')->as(function ($allowDuplicate) {
-            return $allowDuplicate ? '是' : '否';
+        return Show::make(ItemChestContent::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('chest.name', '宝箱名称');
+            $show->field('item.name', '物品名称');
+            $show->field('group.name', '物品组名称');
+            $show->field('min_quantity', '最小数量');
+            $show->field('max_quantity', '最大数量');
+            $show->field('weight', '权重');
+            $show->field('allow_duplicate', '允许重复')->as(function ($allowDuplicate) {
+                return $allowDuplicate ? '是' : '否';
+            });
+            $show->field('pity_count', '保底次数');
+            $show->field('pity_weight_factor', '保底权重因子');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
         });
-        $show->field('pity_count', '保底次数');
-        $show->field('pity_weight_factor', '保底权重因子');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
     }
 
     /**
@@ -95,64 +92,62 @@ class ChestContentController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemChestContent());
-
-        $form->select('chest_id', '宝箱')
-            ->options(ItemItem::where('type', ITEM_TYPE::OPENABLE)->pluck('name', 'id'))
-            ->required();
-
-        // 物品和物品组二选一
-        $form->radio('content_type', '内容类型')
-            ->options(['item' => '物品', 'group' => '物品组'])
-            ->default('item')
-            ->when('item', function (Form $form) {
-                $form->select('item_id', '物品')
-                    ->options(ItemItem::pluck('name', 'id'))
-                    ->required();
-            })
-            ->when('group', function (Form $form) {
-                $form->select('group_id', '物品组')
-                    ->options(ItemGroup::pluck('name', 'id'))
-                    ->required();
+        return Form::make(new ItemChestContent(), function (Form $form) {
+            $form->select('chest_id', '宝箱')
+                ->options(ItemItem::where('type', ITEM_TYPE::OPENABLE)->pluck('name', 'id'))
+                ->required();
+
+            // 物品和物品组二选一
+            $form->radio('content_type', '内容类型')
+                ->options(['item' => '物品', 'group' => '物品组'])
+                ->default('item')
+                ->when('item', function (Form $form) {
+                    $form->select('item_id', '物品')
+                        ->options(ItemItem::pluck('name', 'id'))
+                        ->required();
+                })
+                ->when('group', function (Form $form) {
+                    $form->select('group_id', '物品组')
+                        ->options(ItemGroup::pluck('name', 'id'))
+                        ->required();
+                });
+
+            $form->number('min_quantity', '最小数量')
+                ->default(1)
+                ->min(1)
+                ->required();
+            $form->number('max_quantity', '最大数量')
+                ->default(1)
+                ->min(1)
+                ->required();
+            $form->number('weight', '权重')
+                ->default(1.0)
+                ->min(0.001)
+                ->step(0.001)
+                ->required()
+                ->help('权重越高,掉落概率越大,所有内容权重总和为100');
+            $form->switch('allow_duplicate', '允许重复')
+                ->default(false)
+                ->help('是否允许在一次开箱中重复获得该内容');
+            $form->number('pity_count', '保底次数')
+                ->default(0)
+                ->min(0)
+                ->help('连续未获得该内容的次数达到此值时,必定获得该内容,0表示不启用保底机制');
+            $form->number('pity_weight_factor', '保底权重因子')
+                ->default(1.0)
+                ->min(0)
+                ->step(0.1)
+                ->help('每次未获得该内容时,权重增加的倍数,默认为1.0');
+
+            // 保存前回调
+            $form->saving(function (Form $form) {
+                // 根据内容类型设置对应的字段
+                if ($form->content_type == 'item') {
+                    $form->group_id = null;
+                } else {
+                    $form->item_id = null;
+                }
             });
-
-        $form->number('min_quantity', '最小数量')
-            ->default(1)
-            ->min(1)
-            ->required();
-        $form->number('max_quantity', '最大数量')
-            ->default(1)
-            ->min(1)
-            ->required();
-        $form->number('weight', '权重')
-            ->default(1.0)
-            ->min(0.001)
-            ->step(0.001)
-            ->required()
-            ->help('权重越高,掉落概率越大,所有内容权重总和为100');
-        $form->switch('allow_duplicate', '允许重复')
-            ->default(false)
-            ->help('是否允许在一次开箱中重复获得该内容');
-        $form->number('pity_count', '保底次数')
-            ->default(0)
-            ->min(0)
-            ->help('连续未获得该内容的次数达到此值时,必定获得该内容,0表示不启用保底机制');
-        $form->number('pity_weight_factor', '保底权重因子')
-            ->default(1.0)
-            ->min(0)
-            ->step(0.1)
-            ->help('每次未获得该内容时,权重增加的倍数,默认为1.0');
-
-        // 保存前回调
-        $form->saving(function (Form $form) {
-            // 根据内容类型设置对应的字段
-            if ($form->content_type == 'item') {
-                $form->group_id = null;
-            } else {
-                $form->item_id = null;
-            }
         });
-
-        return $form;
     }
 }

+ 91 - 95
app/Module/GameItems/AdminControllers/ChestOpenLogController.php

@@ -34,47 +34,45 @@ class ChestOpenLogController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemChestOpenLog());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemChestOpenLog(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('chest.name', '宝箱名称');
+            $grid->column('quantity', '开启数量');
+            $grid->column('pity_triggered', '触发保底')->switch();
+            $grid->column('pity_content_id', '保底内容ID');
+            $grid->column('open_time', '开启时间')->sortable();
+            $grid->column('ip_address', 'IP地址');
+            $grid->column('created_at', '创建时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('chest_id', '宝箱')->select(
+                    ItemItem::where('type', 5)->pluck('name', 'id')
+                );
+                $filter->equal('pity_triggered', '触发保底')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+                $filter->between('open_time', '开启时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('chest.name', '宝箱名称');
-        $grid->column('quantity', '开启数量');
-        $grid->column('pity_triggered', '触发保底')->switch();
-        $grid->column('pity_content_id', '保底内容ID');
-        $grid->column('open_time', '开启时间')->sortable();
-        $grid->column('ip_address', 'IP地址');
-        $grid->column('created_at', '创建时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('chest_id', '宝箱')->select(
-                ItemItem::where('type', 5)->pluck('name', 'id')
-            );
-            $filter->equal('pity_triggered', '触发保底')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-            $filter->between('open_time', '开启时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -100,67 +98,65 @@ class ChestOpenLogController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemChestOpenLog::findOrFail($id));
+        return Show::make(ItemChestOpenLog::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('chest.name', '宝箱名称');
+            $show->field('quantity', '开启数量');
+            $show->field('pity_triggered', '触发保底')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('pity_content_id', '保底内容ID');
+
+            // 显示开箱结果
+            $show->field('results', '开箱结果')->as(function ($results) {
+                if (empty($results)) {
+                    return '无';
+                }
 
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
+                if (is_string($results)) {
+                    $results = json_decode($results, true);
+                }
 
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('chest.name', '宝箱名称');
-        $show->field('quantity', '开启数量');
-        $show->field('pity_triggered', '触发保底')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
-        $show->field('pity_content_id', '保底内容ID');
-
-        // 显示开箱结果
-        $show->field('results', '开箱结果')->as(function ($results) {
-            if (empty($results)) {
-                return '无';
-            }
-
-            if (is_string($results)) {
-                $results = json_decode($results, true);
-            }
-
-            if (is_array($results)) {
-                $html = '';
-
-                foreach ($results as $index => $chestResult) {
-                    $html .= '<h4>第' . ($index + 1) . '次开箱</h4>';
-                    $html .= '<table class="table table-bordered">';
-                    $html .= '<thead><tr><th>物品ID</th><th>数量</th><th>是否保底</th></tr></thead>';
-                    $html .= '<tbody>';
-
-                    foreach ($chestResult as $item) {
-                        $itemInfo = ItemItem::find($item['item_id']);
-                        $itemName = $itemInfo ? $itemInfo->name : '未知物品';
-
-                        $html .= '<tr>';
-                        $html .= '<td>' . $item['item_id'] . ' (' . $itemName . ')</td>';
-                        $html .= '<td>' . $item['quantity'] . '</td>';
-                        $html .= '<td>' . (isset($item['is_pity']) && $item['is_pity'] ? '是' : '否') . '</td>';
-                        $html .= '</tr>';
-                    }
+                if (is_array($results)) {
+                    $html = '';
 
-                    $html .= '</tbody></table>';
-                }
+                    foreach ($results as $index => $chestResult) {
+                        $html .= '<h4>第' . ($index + 1) . '次开箱</h4>';
+                        $html .= '<table class="table table-bordered">';
+                        $html .= '<thead><tr><th>物品ID</th><th>数量</th><th>是否保底</th></tr></thead>';
+                        $html .= '<tbody>';
 
-                return $html;
-            }
+                        foreach ($chestResult as $item) {
+                            $itemInfo = ItemItem::find($item['item_id']);
+                            $itemName = $itemInfo ? $itemInfo->name : '未知物品';
 
-            return $results;
-        })->unescape();
+                            $html .= '<tr>';
+                            $html .= '<td>' . $item['item_id'] . ' (' . $itemName . ')</td>';
+                            $html .= '<td>' . $item['quantity'] . '</td>';
+                            $html .= '<td>' . (isset($item['is_pity']) && $item['is_pity'] ? '是' : '否') . '</td>';
+                            $html .= '</tr>';
+                        }
 
-        $show->field('open_time', '开启时间');
-        $show->field('ip_address', 'IP地址');
-        $show->field('device_info', '设备信息');
-        $show->field('created_at', '创建时间');
+                        $html .= '</tbody></table>';
+                    }
 
-        return $show;
+                    return $html;
+                }
+
+                return $results;
+            })->unescape();
+
+            $show->field('open_time', '开启时间');
+            $show->field('ip_address', 'IP地址');
+            $show->field('device_info', '设备信息');
+            $show->field('created_at', '创建时间');
+        });
     }
 }

+ 91 - 94
app/Module/GameItems/AdminControllers/CraftLogController.php

@@ -4,6 +4,7 @@ namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Models\ItemCraftLog;
 use App\Module\GameItems\Models\ItemRecipe;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
 use UCore\DcatAdmin\AdminController;
@@ -34,51 +35,49 @@ class CraftLogController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemCraftLog());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemCraftLog(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('recipe.name', '配方名称');
+            $grid->column('is_success', '是否成功')->switch();
+            $grid->column('resultItem.name', '产出物品');
+            $grid->column('result_instance_id', '产出实例ID');
+            $grid->column('result_quantity', '产出数量');
+            $grid->column('craft_time', '合成时间')->sortable();
+            $grid->column('ip_address', 'IP地址');
+            $grid->column('created_at', '创建时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('recipe_id', '配方')->select(
+                    ItemRecipe::pluck('name', 'id')
+                );
+                $filter->equal('is_success', '是否成功')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+                $filter->equal('result_item_id', '产出物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->between('craft_time', '合成时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('recipe.name', '配方名称');
-        $grid->column('is_success', '是否成功')->switch();
-        $grid->column('resultItem.name', '产出物品');
-        $grid->column('result_instance_id', '产出实例ID');
-        $grid->column('result_quantity', '产出数量');
-        $grid->column('craft_time', '合成时间')->sortable();
-        $grid->column('ip_address', 'IP地址');
-        $grid->column('created_at', '创建时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('recipe_id', '配方')->select(
-                ItemRecipe::pluck('name', 'id')
-            );
-            $filter->equal('is_success', '是否成功')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-            $filter->equal('result_item_id', '产出物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->between('craft_time', '合成时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -104,63 +103,61 @@ class CraftLogController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemCraftLog::findOrFail($id));
+        return Show::make(ItemCraftLog::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('recipe.name', '配方名称');
+            $show->field('is_success', '是否成功')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+
+            // 显示使用的材料
+            $show->field('materials_used', '使用的材料')->as(function ($materials) {
+                if (empty($materials)) {
+                    return '无';
+                }
 
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
+                if (is_string($materials)) {
+                    $materials = json_decode($materials, true);
+                }
 
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('recipe.name', '配方名称');
-        $show->field('is_success', '是否成功')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
+                if (is_array($materials)) {
+                    $html = '<table class="table table-bordered">';
+                    $html .= '<thead><tr><th>物品ID</th><th>物品名称</th><th>数量</th></tr></thead>';
+                    $html .= '<tbody>';
 
-        // 显示使用的材料
-        $show->field('materials_used', '使用的材料')->as(function ($materials) {
-            if (empty($materials)) {
-                return '无';
-            }
-
-            if (is_string($materials)) {
-                $materials = json_decode($materials, true);
-            }
-
-            if (is_array($materials)) {
-                $html = '<table class="table table-bordered">';
-                $html .= '<thead><tr><th>物品ID</th><th>物品名称</th><th>数量</th></tr></thead>';
-                $html .= '<tbody>';
-
-                foreach ($materials as $material) {
-                    $itemInfo = ItemItem::find($material['item_id']);
-                    $itemName = $itemInfo ? $itemInfo->name : '未知物品';
-
-                    $html .= '<tr>';
-                    $html .= '<td>' . $material['item_id'] . '</td>';
-                    $html .= '<td>' . $itemName . '</td>';
-                    $html .= '<td>' . $material['quantity'] . '</td>';
-                    $html .= '</tr>';
-                }
+                    foreach ($materials as $material) {
+                        $itemInfo = ItemItem::find($material['item_id']);
+                        $itemName = $itemInfo ? $itemInfo->name : '未知物品';
 
-                $html .= '</tbody></table>';
+                        $html .= '<tr>';
+                        $html .= '<td>' . $material['item_id'] . '</td>';
+                        $html .= '<td>' . $itemName . '</td>';
+                        $html .= '<td>' . $material['quantity'] . '</td>';
+                        $html .= '</tr>';
+                    }
 
-                return $html;
-            }
+                    $html .= '</tbody></table>';
 
-            return $materials;
-        })->unescape();
+                    return $html;
+                }
 
-        $show->field('resultItem.name', '产出物品');
-        $show->field('result_instance_id', '产出实例ID');
-        $show->field('result_quantity', '产出数量');
-        $show->field('craft_time', '合成时间');
-        $show->field('ip_address', 'IP地址');
-        $show->field('device_info', '设备信息');
-        $show->field('created_at', '创建时间');
+                return $materials;
+            })->unescape();
 
-        return $show;
+            $show->field('resultItem.name', '产出物品');
+            $show->field('result_instance_id', '产出实例ID');
+            $show->field('result_quantity', '产出数量');
+            $show->field('craft_time', '合成时间');
+            $show->field('ip_address', 'IP地址');
+            $show->field('device_info', '设备信息');
+            $show->field('created_at', '创建时间');
+        });
     }
 }

+ 86 - 90
app/Module/GameItems/AdminControllers/DismantleLogController.php

@@ -35,48 +35,46 @@ class DismantleLogController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemDismantleLog());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemDismantleLog(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('item.name', '物品名称');
+            $grid->column('instance_id', '实例ID');
+            $grid->column('quantity', '数量');
+            $grid->column('rule_id', '规则ID');
+            $grid->column('coin_returned', '返还金币');
+            $grid->column('dismantle_time', '分解时间')->sortable();
+            $grid->column('ip_address', 'IP地址');
+            $grid->column('created_at', '创建时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('instance_id', '实例ID');
+                $filter->equal('rule_id', '规则ID')->select(
+                    ItemDismantleRule::pluck('id', 'id')
+                );
+                $filter->between('dismantle_time', '分解时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('item.name', '物品名称');
-        $grid->column('instance_id', '实例ID');
-        $grid->column('quantity', '数量');
-        $grid->column('rule_id', '规则ID');
-        $grid->column('coin_returned', '返还金币');
-        $grid->column('dismantle_time', '分解时间')->sortable();
-        $grid->column('ip_address', 'IP地址');
-        $grid->column('created_at', '创建时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('instance_id', '实例ID');
-            $filter->equal('rule_id', '规则ID')->select(
-                ItemDismantleRule::pluck('id', 'id')
-            );
-            $filter->between('dismantle_time', '分解时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -102,61 +100,59 @@ class DismantleLogController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemDismantleLog::findOrFail($id));
-
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
+        return Show::make(ItemDismantleLog::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('item.name', '物品名称');
+            $show->field('instance_id', '实例ID');
+            $show->field('quantity', '数量');
+            $show->field('rule_id', '规则ID');
+
+            // 显示分解结果
+            $show->field('results', '分解结果')->as(function ($results) {
+                if (empty($results)) {
+                    return '无';
+                }
 
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('item.name', '物品名称');
-        $show->field('instance_id', '实例ID');
-        $show->field('quantity', '数量');
-        $show->field('rule_id', '规则ID');
-
-        // 显示分解结果
-        $show->field('results', '分解结果')->as(function ($results) {
-            if (empty($results)) {
-                return '无';
-            }
-
-            if (is_string($results)) {
-                $results = json_decode($results, true);
-            }
-
-            if (is_array($results)) {
-                $html = '<table class="table table-bordered">';
-                $html .= '<thead><tr><th>物品ID</th><th>物品名称</th><th>数量</th></tr></thead>';
-                $html .= '<tbody>';
-
-                foreach ($results as $result) {
-                    $itemInfo = ItemItem::find($result['item_id']);
-                    $itemName = $itemInfo ? $itemInfo->name : '未知物品';
-
-                    $html .= '<tr>';
-                    $html .= '<td>' . $result['item_id'] . '</td>';
-                    $html .= '<td>' . $itemName . '</td>';
-                    $html .= '<td>' . $result['quantity'] . '</td>';
-                    $html .= '</tr>';
+                if (is_string($results)) {
+                    $results = json_decode($results, true);
                 }
 
-                $html .= '</tbody></table>';
+                if (is_array($results)) {
+                    $html = '<table class="table table-bordered">';
+                    $html .= '<thead><tr><th>物品ID</th><th>物品名称</th><th>数量</th></tr></thead>';
+                    $html .= '<tbody>';
+
+                    foreach ($results as $result) {
+                        $itemInfo = ItemItem::find($result['item_id']);
+                        $itemName = $itemInfo ? $itemInfo->name : '未知物品';
 
-                return $html;
-            }
+                        $html .= '<tr>';
+                        $html .= '<td>' . $result['item_id'] . '</td>';
+                        $html .= '<td>' . $itemName . '</td>';
+                        $html .= '<td>' . $result['quantity'] . '</td>';
+                        $html .= '</tr>';
+                    }
 
-            return $results;
-        })->unescape();
+                    $html .= '</tbody></table>';
 
-        $show->field('coin_returned', '返还金币');
-        $show->field('dismantle_time', '分解时间');
-        $show->field('ip_address', 'IP地址');
-        $show->field('device_info', '设备信息');
-        $show->field('created_at', '创建时间');
+                    return $html;
+                }
 
-        return $show;
+                return $results;
+            })->unescape();
+
+            $show->field('coin_returned', '返还金币');
+            $show->field('dismantle_time', '分解时间');
+            $show->field('ip_address', 'IP地址');
+            $show->field('device_info', '设备信息');
+            $show->field('created_at', '创建时间');
+        });
     }
 }

+ 147 - 150
app/Module/GameItems/AdminControllers/DismantleRuleController.php

@@ -4,6 +4,7 @@ namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Models\ItemDismantleRule;
 use App\Module\GameItems\Models\ItemCategory;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
@@ -28,57 +29,55 @@ class DismantleRuleController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemDismantleRule());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('rule_type', '规则类型')->display(function () {
-            if (!empty($this->item_id)) {
-                return '物品规则';
-            } elseif (!empty($this->category_id)) {
-                return '分类规则';
-            } else {
-                return '未知';
-            }
-        });
-        $grid->column('item.name', '物品名称');
-        $grid->column('category.name', '分类名称');
-        $grid->column('priority', '优先级')->sortable();
-        $grid->column('coin_return_rate', '金币返还率')->display(function ($value) {
-            return $value * 100 . '%';
-        });
-        $grid->column('results', '结果数量')->display(function ($results) {
-            return count($results);
-        });
-        $grid->column('is_active', '是否启用')->switch();
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('category_id', '分类')->select(
-                ItemCategory::pluck('name', 'id')
-            );
-            $filter->where('rule_type', function ($query) {
-                if ($this->input == 'item') {
-                    $query->whereNotNull('item_id')->whereNull('category_id');
-                } elseif ($this->input == 'category') {
-                    $query->whereNotNull('category_id')->whereNull('item_id');
+        return Grid::make(new ItemDismantleRule(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('rule_type', '规则类型')->display(function () {
+                if (!empty($this->item_id)) {
+                    return '物品规则';
+                } elseif (!empty($this->category_id)) {
+                    return '分类规则';
+                } else {
+                    return '未知';
                 }
-            }, '规则类型')->select([
-                'item' => '物品规则',
-                'category' => '分类规则',
-            ]);
-            $filter->equal('is_active', '是否启用')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
+            });
+            $grid->column('item.name', '物品名称');
+            $grid->column('category.name', '分类名称');
+            $grid->column('priority', '优先级')->sortable();
+            $grid->column('coin_return_rate', '金币返还率')->display(function ($value) {
+                return $value * 100 . '%';
+            });
+            $grid->column('results', '结果数量')->display(function ($results) {
+                return count($results);
+            });
+            $grid->column('is_active', '是否启用')->switch();
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('category_id', '分类')->select(
+                    ItemCategory::pluck('name', 'id')
+                );
+                $filter->where('rule_type', function ($query) {
+                    if ($this->input == 'item') {
+                        $query->whereNotNull('item_id')->whereNull('category_id');
+                    } elseif ($this->input == 'category') {
+                        $query->whereNotNull('category_id')->whereNull('item_id');
+                    }
+                }, '规则类型')->select([
+                    'item' => '物品规则',
+                    'category' => '分类规则',
+                ]);
+                $filter->equal('is_active', '是否启用')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -104,61 +103,61 @@ class DismantleRuleController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemDismantleRule::findOrFail($id));
-
-        $show->field('id', 'ID');
-
-        // 规则类型
-        $show->field('rule_type', '规则类型')->as(function () {
-            if (!empty($this->item_id)) {
-                return '物品规则';
-            } elseif (!empty($this->category_id)) {
-                return '分类规则';
-            } else {
-                return '未知';
-            }
-        });
-
-        // 根据规则类型显示不同字段
-        if ($show->getModel()->item_id) {
-            $show->field('item.name', '物品名称');
-        } elseif ($show->getModel()->category_id) {
-            $show->field('category.name', '分类名称');
-        }
-
-        $show->field('priority', '优先级');
-        $show->field('coin_return_rate', '金币返还率')->as(function ($value) {
-            return $value * 100 . '%';
-        });
-        $show->field('is_active', '是否启用')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        // 显示分解结果
-        $show->divider('分解结果');
-
-        $show->field('results', '结果列表')->as(function ($results) {
-            $html = '<table class="table table-bordered">';
-            $html .= '<thead><tr><th>物品名称</th><th>最小数量</th><th>最大数量</th><th>概率</th></tr></thead>';
-            $html .= '<tbody>';
+        $model = ItemDismantleRule::findOrFail($id);
+
+        return Show::make($model, function (Show $show) {
+            $show->field('id', 'ID');
+
+            // 规则类型
+            $show->field('rule_type', '规则类型')->as(function () {
+                if (!empty($this->item_id)) {
+                    return '物品规则';
+                } elseif (!empty($this->category_id)) {
+                    return '分类规则';
+                } else {
+                    return '未知';
+                }
+            });
 
-            foreach ($results as $result) {
-                $html .= '<tr>';
-                $html .= '<td>' . $result->resultItem->name . '</td>';
-                $html .= '<td>' . $result->min_quantity . '</td>';
-                $html .= '<td>' . $result->max_quantity . '</td>';
-                $html .= '<td>' . ($result->chance * 100) . '%</td>';
-                $html .= '</tr>';
+            // 根据规则类型显示不同字段
+            if ($show->getModel()->item_id) {
+                $show->field('item.name', '物品名称');
+            } elseif ($show->getModel()->category_id) {
+                $show->field('category.name', '分类名称');
             }
 
-            $html .= '</tbody></table>';
+            $show->field('priority', '优先级');
+            $show->field('coin_return_rate', '金币返还率')->as(function ($value) {
+                return $value * 100 . '%';
+            });
+            $show->field('is_active', '是否启用')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+
+            // 显示分解结果
+            $show->divider('分解结果');
+
+            $show->field('results', '结果列表')->as(function ($results) {
+                $html = '<table class="table table-bordered">';
+                $html .= '<thead><tr><th>物品名称</th><th>最小数量</th><th>最大数量</th><th>概率</th></tr></thead>';
+                $html .= '<tbody>';
+
+                foreach ($results as $result) {
+                    $html .= '<tr>';
+                    $html .= '<td>' . $result->resultItem->name . '</td>';
+                    $html .= '<td>' . $result->min_quantity . '</td>';
+                    $html .= '<td>' . $result->max_quantity . '</td>';
+                    $html .= '<td>' . ($result->chance * 100) . '%</td>';
+                    $html .= '</tr>';
+                }
 
-            return $html;
-        })->unescape();
+                $html .= '</tbody></table>';
 
-        return $show;
+                return $html;
+            })->unescape();
+        });
     }
 
     /**
@@ -197,62 +196,60 @@ class DismantleRuleController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemDismantleRule());
-
-        // 规则类型
-        $form->radio('rule_type', '规则类型')
-            ->options(['item' => '物品规则', 'category' => '分类规则'])
-            ->default('item')
-            ->when('item', function (Form $form) {
-                $form->select('item_id', '物品')
+        return Form::make(new ItemDismantleRule(), function (Form $form) {
+            // 规则类型
+            $form->radio('rule_type', '规则类型')
+                ->options(['item' => '物品规则', 'category' => '分类规则'])
+                ->default('item')
+                ->when('item', function (Form $form) {
+                    $form->select('item_id', '物品')
+                        ->options(ItemItem::pluck('name', 'id'))
+                        ->required();
+                })
+                ->when('category', function (Form $form) {
+                    $form->select('category_id', '分类')
+                        ->options(ItemCategory::pluck('name', 'id'))
+                        ->required();
+                });
+
+            $form->number('priority', '优先级')
+                ->default(0)
+                ->help('数字越大优先级越高,当物品同时匹配多个规则时,使用优先级最高的规则');
+
+            $form->rate('coin_return_rate', '金币返还率')
+                ->default(0.5)
+                ->help('分解时返还的金币比例,基于物品的sell_price计算');
+
+            $form->switch('is_active', '是否启用')
+                ->default(true);
+
+            // 分解结果
+            $form->hasMany('results', '分解结果', function (Form\NestedForm $form) {
+                $form->select('result_item_id', '物品')
                     ->options(ItemItem::pluck('name', 'id'))
                     ->required();
-            })
-            ->when('category', function (Form $form) {
-                $form->select('category_id', '分类')
-                    ->options(ItemCategory::pluck('name', 'id'))
+                $form->number('min_quantity', '最小数量')
+                    ->default(1)
+                    ->min(0)
+                    ->required();
+                $form->number('max_quantity', '最大数量')
+                    ->default(1)
+                    ->min(0)
                     ->required();
+                $form->rate('chance', '概率')
+                    ->default(1)
+                    ->help('获得该物品的概率,1表示100%');
             });
 
-        $form->number('priority', '优先级')
-            ->default(0)
-            ->help('数字越大优先级越高,当物品同时匹配多个规则时,使用优先级最高的规则');
-
-        $form->rate('coin_return_rate', '金币返还率')
-            ->default(0.5)
-            ->help('分解时返还的金币比例,基于物品的sell_price计算');
-
-        $form->switch('is_active', '是否启用')
-            ->default(true);
-
-        // 分解结果
-        $form->hasMany('results', '分解结果', function (Form\NestedForm $form) {
-            $form->select('result_item_id', '物品')
-                ->options(ItemItem::pluck('name', 'id'))
-                ->required();
-            $form->number('min_quantity', '最小数量')
-                ->default(1)
-                ->min(0)
-                ->required();
-            $form->number('max_quantity', '最大数量')
-                ->default(1)
-                ->min(0)
-                ->required();
-            $form->rate('chance', '概率')
-                ->default(1)
-                ->help('获得该物品的概率,1表示100%');
-        });
-
-        // 保存前回调
-        $form->saving(function (Form $form) {
-            // 根据规则类型设置对应的字段
-            if ($form->rule_type == 'item') {
-                $form->category_id = null;
-            } else {
-                $form->item_id = null;
-            }
+            // 保存前回调
+            $form->saving(function (Form $form) {
+                // 根据规则类型设置对应的字段
+                if ($form->rule_type == 'item') {
+                    $form->category_id = null;
+                } else {
+                    $form->item_id = null;
+                }
+            });
         });
-
-        return $form;
     }
 }

+ 44 - 49
app/Module/GameItems/AdminControllers/GroupController.php

@@ -3,6 +3,7 @@
 namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Models\ItemGroup;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
@@ -26,23 +27,21 @@ class GroupController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemGroup());
+        return Grid::make(new ItemGroup(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('name', '名称');
+            $grid->column('code', '编码');
+            $grid->column('description', '描述')->limit(30);
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
 
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('name', '名称');
-        $grid->column('code', '编码');
-        $grid->column('description', '描述')->limit(30);
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->like('name', '名称');
-            $filter->like('code', '编码');
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->like('name', '名称');
+                $filter->like('code', '编码');
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -53,24 +52,22 @@ class GroupController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemGroup::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('name', '名称');
-        $show->field('code', '编码');
-        $show->field('description', '描述');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
+        return Show::make(ItemGroup::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('name', '名称');
+            $show->field('code', '编码');
+            $show->field('description', '描述');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
 
-        // 显示物品组中的物品
-        $show->groupItems('物品组内容', function ($groupItems) {
-            $groupItems->resource('/admin/game-items-group-items');
-            $groupItems->id('ID');
-            $groupItems->item()->name('物品名称');
-            $groupItems->weight('权重');
+            // 显示物品组中的物品
+            $show->groupItems('物品组内容', function ($groupItems) {
+                $groupItems->resource('/admin/game-items-group-items');
+                $groupItems->id('ID');
+                $groupItems->item()->name('物品名称');
+                $groupItems->weight('权重');
+            });
         });
-
-        return $show;
     }
 
     /**
@@ -80,25 +77,23 @@ class GroupController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemGroup());
-
-        $form->text('name', '名称')->required();
-        $form->text('code', '编码')->required()->help('用于系统识别的唯一编码');
-        $form->textarea('description', '描述');
+        return Form::make(new ItemGroup(), function (Form $form) {
+            $form->text('name', '名称')->required();
+            $form->text('code', '编码')->required()->help('用于系统识别的唯一编码');
+            $form->textarea('description', '描述');
 
-        // 物品组内容
-        $form->hasMany('groupItems', '物品组内容', function (Form\NestedForm $form) {
-            $form->select('item_id', '物品')
-                ->options(ItemItem::pluck('name', 'id'))
-                ->required();
-            $form->number('weight', '权重')
-                ->default(1.0)
-                ->min(0.001)
-                ->step(0.001)
-                ->required()
-                ->help('权重越高,随机选择时概率越大');
+            // 物品组内容
+            $form->hasMany('groupItems', '物品组内容', function (Form\NestedForm $form) {
+                $form->select('item_id', '物品')
+                    ->options(ItemItem::pluck('name', 'id'))
+                    ->required();
+                $form->number('weight', '权重')
+                    ->default(1.0)
+                    ->min(0.001)
+                    ->step(0.001)
+                    ->required()
+                    ->help('权重越高,随机选择时概率越大');
+            });
         });
-
-        return $form;
     }
 }

+ 39 - 45
app/Module/GameItems/AdminControllers/GroupItemController.php

@@ -28,27 +28,25 @@ class GroupItemController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemGroupItem());
+        return Grid::make(new ItemGroupItem(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('group.name', '物品组');
+            $grid->column('item.name', '物品');
+            $grid->column('weight', '权重');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
 
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('group.name', '物品组');
-        $grid->column('item.name', '物品');
-        $grid->column('weight', '权重');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('group_id', '物品组')->select(
-                ItemGroup::pluck('name', 'id')
-            );
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('group_id', '物品组')->select(
+                    ItemGroup::pluck('name', 'id')
+                );
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -59,16 +57,14 @@ class GroupItemController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemGroupItem::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('group.name', '物品组');
-        $show->field('item.name', '物品');
-        $show->field('weight', '权重');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
+        return Show::make(ItemGroupItem::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('group.name', '物品组');
+            $show->field('item.name', '物品');
+            $show->field('weight', '权重');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+        });
     }
 
     /**
@@ -78,21 +74,19 @@ class GroupItemController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemGroupItem());
-
-        $form->select('group_id', '物品组')
-            ->options(ItemGroup::pluck('name', 'id'))
-            ->required();
-        $form->select('item_id', '物品')
-            ->options(ItemItem::pluck('name', 'id'))
-            ->required();
-        $form->number('weight', '权重')
-            ->default(1.0)
-            ->min(0.001)
-            ->step(0.001)
-            ->required()
-            ->help('权重越高,随机选择时概率越大');
-
-        return $form;
+        return Form::make(new ItemGroupItem(), function (Form $form) {
+            $form->select('group_id', '物品组')
+                ->options(ItemGroup::pluck('name', 'id'))
+                ->required();
+            $form->select('item_id', '物品')
+                ->options(ItemItem::pluck('name', 'id'))
+                ->required();
+            $form->number('weight', '权重')
+                ->default(1.0)
+                ->min(0.001)
+                ->step(0.001)
+                ->required()
+                ->help('权重越高,随机选择时概率越大');
+        });
     }
 }

+ 145 - 150
app/Module/GameItems/AdminControllers/InstanceController.php

@@ -3,6 +3,7 @@
 namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Models\ItemInstance;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
@@ -27,40 +28,38 @@ class InstanceController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemInstance());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('item.name', '基础物品');
-        $grid->column('name', '实例名称');
-        $grid->column('tradable', '可交易')->switch();
-        $grid->column('is_bound', '绑定')->switch();
-        $grid->column('bound_to', '绑定用户ID');
-        $grid->column('bind_exp_time', '绑定过期时间');
-        $grid->column('expire_at', '过期时间');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('item_id', '基础物品')->select(
-                ItemItem::where('is_unique', 1)->pluck('name', 'id')
-            );
-            $filter->like('name', '实例名称');
-            $filter->equal('tradable', '可交易')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-            $filter->equal('is_bound', '已绑定')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-            $filter->equal('bound_to', '绑定用户ID');
-            $filter->between('bind_exp_time', '绑定过期时间')->datetime();
-            $filter->between('expire_at', '过期时间')->datetime();
+        return Grid::make(new ItemInstance(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('item.name', '基础物品');
+            $grid->column('name', '实例名称');
+            $grid->column('tradable', '可交易')->switch();
+            $grid->column('is_bound', '已绑定')->switch();
+            $grid->column('bound_to', '绑定用户ID');
+            $grid->column('bind_exp_time', '绑定过期时间');
+            $grid->column('expire_at', '过期时间');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('item_id', '基础物品')->select(
+                    ItemItem::where('is_unique', 1)->pluck('name', 'id')
+                );
+                $filter->like('name', '实例名称');
+                $filter->equal('tradable', '可交易')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+                $filter->equal('is_bound', '已绑定')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+                $filter->equal('bound_to', '绑定用户ID');
+                $filter->between('bind_exp_time', '绑定过期时间')->datetime();
+                $filter->between('expire_at', '过期时间')->datetime();
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -86,95 +85,93 @@ class InstanceController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemInstance::findOrFail($id));
+        return Show::make(ItemInstance::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('item.name', '基础物品');
+            $show->field('name', '实例名称');
+
+            // 显示显示属性
+            $show->field('display_attributes', '显示属性')->as(function ($attributes) {
+                if (empty($attributes)) {
+                    return '无';
+                }
 
-        $show->field('id', 'ID');
-        $show->field('item.name', '基础物品');
-        $show->field('name', '实例名称');
+                if (is_string($attributes)) {
+                    $attributes = json_decode($attributes, true);
+                }
 
-        // 显示显示属性
-        $show->field('display_attributes', '显示属性')->as(function ($attributes) {
-            if (empty($attributes)) {
-                return '无';
-            }
+                if (is_array($attributes)) {
+                    $html = '<table class="table table-bordered">';
+                    $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
+                    $html .= '<tbody>';
 
-            if (is_string($attributes)) {
-                $attributes = json_decode($attributes, true);
-            }
+                    foreach ($attributes as $key => $value) {
+                        $html .= '<tr>';
+                        $html .= '<td>' . $key . '</td>';
+                        $html .= '<td>' . $value . '</td>';
+                        $html .= '</tr>';
+                    }
 
-            if (is_array($attributes)) {
-                $html = '<table class="table table-bordered">';
-                $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
-                $html .= '<tbody>';
+                    $html .= '</tbody></table>';
 
-                foreach ($attributes as $key => $value) {
-                    $html .= '<tr>';
-                    $html .= '<td>' . $key . '</td>';
-                    $html .= '<td>' . $value . '</td>';
-                    $html .= '</tr>';
+                    return $html;
                 }
 
-                $html .= '</tbody></table>';
+                return $attributes;
+            })->unescape();
 
-                return $html;
-            }
+            // 显示数值属性
+            $show->field('numeric_attributes', '数值属性')->as(function ($attributes) {
+                if (empty($attributes)) {
+                    return '无';
+                }
 
-            return $attributes;
-        })->unescape();
+                if (is_string($attributes)) {
+                    $attributes = json_decode($attributes, true);
+                }
 
-        // 显示数值属性
-        $show->field('numeric_attributes', '数值属性')->as(function ($attributes) {
-            if (empty($attributes)) {
-                return '无';
-            }
+                if (is_array($attributes)) {
+                    $html = '<table class="table table-bordered">';
+                    $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
+                    $html .= '<tbody>';
 
-            if (is_string($attributes)) {
-                $attributes = json_decode($attributes, true);
-            }
+                    foreach ($attributes as $key => $value) {
+                        $html .= '<tr>';
+                        $html .= '<td>' . $key . '</td>';
+                        $html .= '<td>' . $value . '</td>';
+                        $html .= '</tr>';
+                    }
 
-            if (is_array($attributes)) {
-                $html = '<table class="table table-bordered">';
-                $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
-                $html .= '<tbody>';
+                    $html .= '</tbody></table>';
 
-                foreach ($attributes as $key => $value) {
-                    $html .= '<tr>';
-                    $html .= '<td>' . $key . '</td>';
-                    $html .= '<td>' . $value . '</td>';
-                    $html .= '</tr>';
+                    return $html;
                 }
 
-                $html .= '</tbody></table>';
-
-                return $html;
-            }
-
-            return $attributes;
-        })->unescape();
-
-        $show->field('tradable', '可交易')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
-        $show->field('is_bound', '已绑定')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
-        $show->field('bound_to', '绑定用户ID');
-        $show->field('bind_exp_time', '绑定过期时间');
-        $show->field('expire_at', '过期时间');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
+                return $attributes;
+            })->unescape();
 
-        // 显示拥有该物品实例的用户
-        $show->users('拥有用户', function ($users) {
-            $users->resource('/admin/game-items-user-items');
-            $users->id('ID');
-            $users->user_id('用户ID');
-            $users->quantity('数量');
-            $users->expire_at('过期时间');
-            $users->created_at('获得时间');
+            $show->field('tradable', '可交易')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('is_bound', '已绑定')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('bound_to', '绑定用户ID');
+            $show->field('bind_exp_time', '绑定过期时间');
+            $show->field('expire_at', '过期时间');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+
+            // 显示拥有该物品实例的用户
+            $show->users('拥有用户', function ($users) {
+                $users->resource('/admin/game-items-user-items');
+                $users->id('ID');
+                $users->user_id('用户ID');
+                $users->quantity('数量');
+                $users->expire_at('过期时间');
+                $users->created_at('获得时间');
+            });
         });
-
-        return $show;
     }
 
     /**
@@ -213,53 +210,51 @@ class InstanceController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemInstance());
-
-        $form->select('item_id', '基础物品')
-            ->options(ItemItem::where('is_unique', 1)->pluck('name', 'id'))
-            ->required();
-        $form->text('name', '实例名称')
-            ->help('留空则使用基础物品名称');
-
-        // 显示属性
-        $form->keyValue('display_attributes', '显示属性')
-            ->help('用于显示的属性,如:攻击力、防御力等');
-
-        // 数值属性
-        $form->keyValue('numeric_attributes', '数值属性')
-            ->help('用于计算的属性,如:攻击加成、防御加成等');
-
-        $form->switch('tradable', '可交易')
-            ->default(true);
-        $form->switch('is_bound', '已绑定')
-            ->default(false)
-            ->when(true, function (Form $form) {
-                $form->text('bound_to', '绑定用户ID')
-                    ->required()
-                    ->help('物品绑定的用户ID');
-                $form->datetime('bind_exp_time', '绑定过期时间')
-                    ->help('绑定过期时间,为空表示永久绑定');
-            });
-        $form->datetime('expire_at', '过期时间')
-            ->help('物品过期时间,为空表示永不过期');
-
-        // 保存前回调
-        $form->saving(function (Form $form) {
-            // 如果名称为空,使用基础物品名称
-            if (empty($form->name)) {
-                $item = ItemItem::find($form->item_id);
-                if ($item) {
-                    $form->name = $item->name;
+        return Form::make(new ItemInstance(), function (Form $form) {
+            $form->select('item_id', '基础物品')
+                ->options(ItemItem::where('is_unique', 1)->pluck('name', 'id'))
+                ->required();
+            $form->text('name', '实例名称')
+                ->help('留空则使用基础物品名称');
+
+            // 显示属性
+            $form->keyValue('display_attributes', '显示属性')
+                ->help('用于显示的属性,如:攻击力、防御力等');
+
+            // 数值属性
+            $form->keyValue('numeric_attributes', '数值属性')
+                ->help('用于计算的属性,如:攻击加成、防御加成等');
+
+            $form->switch('tradable', '可交易')
+                ->default(true);
+            $form->switch('is_bound', '已绑定')
+                ->default(false)
+                ->when(true, function (Form $form) {
+                    $form->text('bound_to', '绑定用户ID')
+                        ->required()
+                        ->help('物品绑定的用户ID');
+                    $form->datetime('bind_exp_time', '绑定过期时间')
+                        ->help('绑定过期时间,为空表示永久绑定');
+                });
+            $form->datetime('expire_at', '过期时间')
+                ->help('物品过期时间,为空表示永不过期');
+
+            // 保存前回调
+            $form->saving(function (Form $form) {
+                // 如果名称为空,使用基础物品名称
+                if (empty($form->name)) {
+                    $item = ItemItem::find($form->item_id);
+                    if ($item) {
+                        $form->name = $item->name;
+                    }
                 }
-            }
 
-            // 如果未绑定,清空绑定相关字段
-            if (!$form->is_bound) {
-                $form->bound_to = null;
-                $form->bind_exp_time = null;
-            }
+                // 如果未绑定,清空绑定相关字段
+                if (!$form->is_bound) {
+                    $form->bound_to = null;
+                    $form->bind_exp_time = null;
+                }
+            });
         });
-
-        return $form;
     }
 }

+ 133 - 140
app/Module/GameItems/AdminControllers/OutputLimitController.php

@@ -3,7 +3,6 @@
 namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Models\ItemOutputLimit;
-use App\Module\GameItems\Models\ItemItem;
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
@@ -28,62 +27,60 @@ class OutputLimitController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemOutputLimit());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('item.name', '物品名称');
-        $grid->column('limit_type', '限制类型')->display(function ($value) {
-            $types = [
-                ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
-                ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
-                ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
-                ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
-                ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
-            ];
-            return $types[$value] ?? '未知';
-        });
-        $grid->column('max_quantity', '最大数量');
-        $grid->column('period_type', '周期类型')->display(function ($value) {
-            $types = [
-                1 => '永久',
-                2 => '每日',
-                3 => '每周',
-                4 => '每月',
-                5 => '自定义',
-            ];
-            return $types[$value] ?? '未知';
-        });
-        $grid->column('period_value', '周期值')->display(function ($value) {
-            if ($this->period_type == 5) {
-                return $value . ' 小时';
-            }
-            return '-';
-        });
-        $grid->column('reset_time', '重置时间');
-        $grid->column('is_active', '是否启用')->switch();
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('limit_type', '限制类型')->select([
-                ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
-                ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
-                ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
-                ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
-                ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
-            ]);
-            $filter->equal('is_active', '是否启用')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
+        return Grid::make(new ItemOutputLimit(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('item.name', '物品名称');
+            $grid->column('limit_type', '限制类型')->display(function ($value) {
+                $types = [
+                    ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
+                    ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
+                    ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
+                    ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
+                    ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
+                ];
+                return $types[$value] ?? '未知';
+            });
+            $grid->column('max_quantity', '最大数量');
+            $grid->column('period_type', '周期类型')->display(function ($value) {
+                $types = [
+                    1 => '永久',
+                    2 => '每日',
+                    3 => '每周',
+                    4 => '每月',
+                    5 => '自定义',
+                ];
+                return $types[$value] ?? '未知';
+            });
+            $grid->column('period_value', '周期值')->display(function ($value) {
+                if ($this->period_type == 5) {
+                    return $value . ' 小时';
+                }
+                return '-';
+            });
+            $grid->column('reset_time', '重置时间');
+            $grid->column('is_active', '是否启用')->switch();
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('limit_type', '限制类型')->select([
+                    ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
+                    ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
+                    ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
+                    ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
+                    ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
+                ]);
+                $filter->equal('is_active', '是否启用')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -109,45 +106,43 @@ class OutputLimitController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemOutputLimit::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('item.name', '物品名称');
-        $show->field('limit_type', '限制类型')->as(function ($value) {
-            $types = [
-                ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
-                ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
-                ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
-                ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
-                ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
-            ];
-            return $types[$value] ?? '未知';
-        });
-        $show->field('max_quantity', '最大数量');
-        $show->field('period_type', '周期类型')->as(function ($value) {
-            $types = [
-                1 => '永久',
-                2 => '每日',
-                3 => '每周',
-                4 => '每月',
-                5 => '自定义',
-            ];
-            return $types[$value] ?? '未知';
-        });
-        $show->field('period_value', '周期值')->as(function ($value) {
-            if ($this->period_type == 5) {
-                return $value . ' 小时';
-            }
-            return '-';
-        });
-        $show->field('reset_time', '重置时间');
-        $show->field('is_active', '是否启用')->as(function ($value) {
-            return $value ? '是' : '否';
+        return Show::make(ItemOutputLimit::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('item.name', '物品名称');
+            $show->field('limit_type', '限制类型')->as(function ($value) {
+                $types = [
+                    ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
+                    ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
+                    ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
+                    ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
+                    ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
+                ];
+                return $types[$value] ?? '未知';
+            });
+            $show->field('max_quantity', '最大数量');
+            $show->field('period_type', '周期类型')->as(function ($value) {
+                $types = [
+                    1 => '永久',
+                    2 => '每日',
+                    3 => '每周',
+                    4 => '每月',
+                    5 => '自定义',
+                ];
+                return $types[$value] ?? '未知';
+            });
+            $show->field('period_value', '周期值')->as(function ($value) {
+                if ($this->period_type == 5) {
+                    return $value . ' 小时';
+                }
+                return '-';
+            });
+            $show->field('reset_time', '重置时间');
+            $show->field('is_active', '是否启用')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
         });
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
     }
 
     /**
@@ -186,51 +181,49 @@ class OutputLimitController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemOutputLimit());
-
-        $form->select('item_id', '物品')
-            ->options(ItemItem::pluck('name', 'id'))
-            ->required();
-
-        $form->select('limit_type', '限制类型')
-            ->options([
-                ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
-                ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
-                ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
-                ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
-                ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
-            ])
-            ->required()
-            ->help('全局限制:所有用户共享限制;用户限制:每个用户单独限制;每日/周/月限制:每个用户在周期内的限制');
-
-        $form->number('max_quantity', '最大数量')
-            ->min(1)
-            ->required()
-            ->help('最大产出数量');
-
-        $form->select('period_type', '周期类型')
-            ->options([
-                1 => '永久',
-                2 => '每日',
-                3 => '每周',
-                4 => '每月',
-                5 => '自定义',
-            ])
-            ->default(1)
-            ->required()
-            ->when(5, function (Form $form) {
-                $form->number('period_value', '周期值(小时)')
-                    ->min(1)
-                    ->required()
-                    ->help('自定义周期的小时数');
-            });
-
-        $form->datetime('reset_time', '重置时间')
-            ->help('下一次重置时间,为空表示不重置');
-
-        $form->switch('is_active', '是否启用')
-            ->default(true);
-
-        return $form;
+        return Form::make(new ItemOutputLimit(), function (Form $form) {
+            $form->select('item_id', '物品')
+                ->options(ItemItem::pluck('name', 'id'))
+                ->required();
+
+            $form->select('limit_type', '限制类型')
+                ->options([
+                    ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
+                    ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
+                    ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
+                    ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
+                    ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
+                ])
+                ->required()
+                ->help('全局限制:所有用户共享限制;用户限制:每个用户单独限制;每日/周/月限制:每个用户在周期内的限制');
+
+            $form->number('max_quantity', '最大数量')
+                ->min(1)
+                ->required()
+                ->help('最大产出数量');
+
+            $form->select('period_type', '周期类型')
+                ->options([
+                    1 => '永久',
+                    2 => '每日',
+                    3 => '每周',
+                    4 => '每月',
+                    5 => '自定义',
+                ])
+                ->default(1)
+                ->required()
+                ->when(5, function (Form $form) {
+                    $form->number('period_value', '周期值(小时)')
+                        ->min(1)
+                        ->required()
+                        ->help('自定义周期的小时数');
+                });
+
+            $form->datetime('reset_time', '重置时间')
+                ->help('下一次重置时间,为空表示不重置');
+
+            $form->switch('is_active', '是否启用')
+                ->default(true);
+        });
     }
 }

+ 65 - 69
app/Module/GameItems/AdminControllers/PityTimeController.php

@@ -35,42 +35,40 @@ class PityTimeController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemPityTime());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemPityTime(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('chest.name', '宝箱名称');
+            $grid->column('chest_content_id', '宝箱内容ID');
+            $grid->column('current_count', '当前计数');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('chest_id', '宝箱')->select(
+                    ItemItem::where('type', 5)->pluck('name', 'id')
+                );
+                $filter->equal('chest_content_id', '宝箱内容ID');
+                $filter->between('current_count', '当前计数');
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('chest.name', '宝箱名称');
-        $grid->column('chest_content_id', '宝箱内容ID');
-        $grid->column('current_count', '当前计数');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('chest_id', '宝箱')->select(
-                ItemItem::where('type', 5)->pluck('name', 'id')
-            );
-            $filter->equal('chest_content_id', '宝箱内容ID');
-            $filter->between('current_count', '当前计数');
-        });
-
-        return $grid;
     }
 
     /**
@@ -96,40 +94,38 @@ class PityTimeController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemPityTime::findOrFail($id));
-
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
-
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('chest.name', '宝箱名称');
-
-        // 显示宝箱内容信息
-        $show->field('chest_content_id', '宝箱内容ID');
-        $show->field('chestContent.item.name', '内容物品名称');
-        $show->field('chestContent.group.name', '内容物品组名称');
-        $show->field('chestContent.pity_count', '保底次数');
-        $show->field('chestContent.pity_weight_factor', '保底权重因子');
-
-        $show->field('current_count', '当前计数');
-
-        // 计算距离保底还需次数
-        $show->field('remaining_count', '距离保底还需次数')->as(function () {
-            if (!$this->chestContent || !$this->chestContent->pity_count) {
-                return '无保底机制';
-            }
-
-            $remaining = max(0, $this->chestContent->pity_count - $this->current_count);
-            return $remaining;
+        return Show::make(ItemPityTime::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('chest.name', '宝箱名称');
+
+            // 显示宝箱内容信息
+            $show->field('chest_content_id', '宝箱内容ID');
+            $show->field('chestContent.item.name', '内容物品名称');
+            $show->field('chestContent.group.name', '内容物品组名称');
+            $show->field('chestContent.pity_count', '保底次数');
+            $show->field('chestContent.pity_weight_factor', '保底权重因子');
+
+            $show->field('current_count', '当前计数');
+
+            // 计算距离保底还需次数
+            $show->field('remaining_count', '距离保底还需次数')->as(function () {
+                if (!$this->chestContent || !$this->chestContent->pity_count) {
+                    return '无保底机制';
+                }
+
+                $remaining = max(0, $this->chestContent->pity_count - $this->current_count);
+                return $remaining;
+            });
+
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
         });
-
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
     }
 }

+ 146 - 152
app/Module/GameItems/AdminControllers/RecipeController.php

@@ -28,56 +28,54 @@ class RecipeController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemRecipe());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('name', '配方名称');
-        $grid->column('resultItem.name', '产出物品');
-        $grid->column('result_quantity', '产出数量');
-        $grid->column('success_rate', '成功率')->display(function ($value) {
-            return $value * 100 . '%';
-        });
-        $grid->column('materials', '材料数量')->display(function ($materials) {
-            return count($materials);
-        });
-        $grid->column('coin_cost', '金币消耗')->display(function ($value) {
-            if (empty($value)) {
-                return '0';
-            }
-
-            if (is_string($value)) {
-                $value = json_decode($value, true);
-            }
-
-            if (is_array($value)) {
-                $result = [];
-                foreach ($value as $currency => $amount) {
-                    $result[] = $currency . ': ' . $amount;
+        return Grid::make(new ItemRecipe(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('name', '配方名称');
+            $grid->column('resultItem.name', '产出物品');
+            $grid->column('result_quantity', '产出数量');
+            $grid->column('success_rate', '成功率')->display(function ($value) {
+                return $value * 100 . '%';
+            });
+            $grid->column('materials', '材料数量')->display(function ($materials) {
+                return count($materials);
+            });
+            $grid->column('coin_cost', '金币消耗')->display(function ($value) {
+                if (empty($value)) {
+                    return '0';
                 }
-                return implode(', ', $result);
-            }
 
-            return $value;
-        });
-        $grid->column('cooldown_seconds', '冷却时间(秒)');
-        $grid->column('is_visible', '是否可见')->switch();
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->like('name', '配方名称');
-            $filter->equal('result_item_id', '产出物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('is_visible', '是否可见')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-        });
+                if (is_string($value)) {
+                    $value = json_decode($value, true);
+                }
+
+                if (is_array($value)) {
+                    $result = [];
+                    foreach ($value as $currency => $amount) {
+                        $result[] = $currency . ': ' . $amount;
+                    }
+                    return implode(', ', $result);
+                }
 
-        return $grid;
+                return $value;
+            });
+            $grid->column('cooldown_seconds', '冷却时间(秒)');
+            $grid->column('is_visible', '是否可见')->switch();
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->like('name', '配方名称');
+                $filter->equal('result_item_id', '产出物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('is_visible', '是否可见')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+            });
+        });
     }
 
     /**
@@ -103,88 +101,86 @@ class RecipeController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemRecipe::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('name', '配方名称');
-        $show->field('resultItem.name', '产出物品');
-        $show->field('result_quantity', '产出数量');
-        $show->field('success_rate', '成功率')->as(function ($value) {
-            return $value * 100 . '%';
-        });
-
-        // 显示金币消耗
-        $show->field('coin_cost', '金币消耗')->as(function ($value) {
-            if (empty($value)) {
-                return '0';
-            }
-
-            if (is_string($value)) {
-                $value = json_decode($value, true);
-            }
+        return Show::make(ItemRecipe::findOrFail($id), function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('name', '配方名称');
+            $show->field('resultItem.name', '产出物品');
+            $show->field('result_quantity', '产出数量');
+            $show->field('success_rate', '成功率')->as(function ($value) {
+                return $value * 100 . '%';
+            });
+
+            // 显示金币消耗
+            $show->field('coin_cost', '金币消耗')->as(function ($value) {
+                if (empty($value)) {
+                    return '0';
+                }
 
-            if (is_array($value)) {
-                $result = [];
-                foreach ($value as $currency => $amount) {
-                    $result[] = $currency . ': ' . $amount;
+                if (is_string($value)) {
+                    $value = json_decode($value, true);
                 }
-                return implode('<br>', $result);
-            }
 
-            return $value;
-        })->unescape();
+                if (is_array($value)) {
+                    $result = [];
+                    foreach ($value as $currency => $amount) {
+                        $result[] = $currency . ': ' . $amount;
+                    }
+                    return implode('<br>', $result);
+                }
 
-        $show->field('cooldown_seconds', '冷却时间(秒)');
-        $show->field('is_visible', '是否可见')->as(function ($value) {
-            return $value ? '是' : '否';
-        });
+                return $value;
+            })->unescape();
 
-        // 显示解锁条件
-        $show->field('unlock_condition', '解锁条件')->as(function ($value) {
-            if (empty($value)) {
-                return '无';
-            }
+            $show->field('cooldown_seconds', '冷却时间(秒)');
+            $show->field('is_visible', '是否可见')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
 
-            if (is_string($value)) {
-                $value = json_decode($value, true);
-            }
+            // 显示解锁条件
+            $show->field('unlock_condition', '解锁条件')->as(function ($value) {
+                if (empty($value)) {
+                    return '无';
+                }
 
-            if (is_array($value)) {
-                $result = [];
-                foreach ($value as $condition => $requirement) {
-                    $result[] = $condition . ': ' . $requirement;
+                if (is_string($value)) {
+                    $value = json_decode($value, true);
                 }
-                return implode('<br>', $result);
-            }
 
-            return $value;
-        })->unescape();
+                if (is_array($value)) {
+                    $result = [];
+                    foreach ($value as $condition => $requirement) {
+                        $result[] = $condition . ': ' . $requirement;
+                    }
+                    return implode('<br>', $result);
+                }
 
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
+                return $value;
+            })->unescape();
 
-        // 显示配方材料
-        $show->divider('配方材料');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
 
-        $show->field('materials', '材料列表')->as(function ($materials) {
-            $html = '<table class="table table-bordered">';
-            $html .= '<thead><tr><th>物品名称</th><th>数量</th><th>是否消耗</th></tr></thead>';
-            $html .= '<tbody>';
+            // 显示配方材料
+            $show->divider('配方材料');
 
-            foreach ($materials as $material) {
-                $html .= '<tr>';
-                $html .= '<td>' . $material->item->name . '</td>';
-                $html .= '<td>' . $material->quantity . '</td>';
-                $html .= '<td>' . ($material->is_consumed ? '是' : '否') . '</td>';
-                $html .= '</tr>';
-            }
+            $show->field('materials', '材料列表')->as(function ($materials) {
+                $html = '<table class="table table-bordered">';
+                $html .= '<thead><tr><th>物品名称</th><th>数量</th><th>是否消耗</th></tr></thead>';
+                $html .= '<tbody>';
 
-            $html .= '</tbody></table>';
+                foreach ($materials as $material) {
+                    $html .= '<tr>';
+                    $html .= '<td>' . $material->item->name . '</td>';
+                    $html .= '<td>' . $material->quantity . '</td>';
+                    $html .= '<td>' . ($material->is_consumed ? '是' : '否') . '</td>';
+                    $html .= '</tr>';
+                }
 
-            return $html;
-        })->unescape();
+                $html .= '</tbody></table>';
 
-        return $show;
+                return $html;
+            })->unescape();
+        });
     }
 
     /**
@@ -223,51 +219,49 @@ class RecipeController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemRecipe());
-
-        $form->text('name', '配方名称')->required();
-        $form->select('result_item_id', '产出物品')
-            ->options(ItemItem::pluck('name', 'id'))
-            ->required();
-        $form->number('result_quantity', '产出数量')
-            ->default(1)
-            ->min(1)
-            ->required();
-        $form->rate('success_rate', '成功率')
-            ->default(1)
-            ->help('合成成功的概率,1表示100%');
-
-        // 金币消耗
-        $form->keyValue('coin_cost', '金币消耗')
-            ->help('可以设置多种货币类型的消耗,如:gold:100表示消耗100金币');
-
-        $form->number('cooldown_seconds', '冷却时间(秒)')
-            ->default(0)
-            ->min(0)
-            ->help('两次合成之间的冷却时间,0表示无冷却');
-
-        $form->switch('is_visible', '是否可见')
-            ->default(true)
-            ->help('是否在游戏中对玩家可见');
-
-        // 解锁条件
-        $form->keyValue('unlock_condition', '解锁条件')
-            ->help('设置解锁该配方的条件,如:level:10表示玩家等级达到10级');
-
-        // 配方材料
-        $form->hasMany('materials', '配方材料', function (Form\NestedForm $form) {
-            $form->select('item_id', '物品')
+        return Form::make(new ItemRecipe(), function (Form $form) {
+            $form->text('name', '配方名称')->required();
+            $form->select('result_item_id', '产出物品')
                 ->options(ItemItem::pluck('name', 'id'))
                 ->required();
-            $form->number('quantity', '数量')
+            $form->number('result_quantity', '产出数量')
                 ->default(1)
                 ->min(1)
                 ->required();
-            $form->switch('is_consumed', '是否消耗')
+            $form->rate('success_rate', '成功率')
+                ->default(1)
+                ->help('合成成功的概率,1表示100%');
+
+            // 金币消耗
+            $form->keyValue('coin_cost', '金币消耗')
+                ->help('可以设置多种货币类型的消耗,如:gold:100表示消耗100金币');
+
+            $form->number('cooldown_seconds', '冷却时间(秒)')
+                ->default(0)
+                ->min(0)
+                ->help('两次合成之间的冷却时间,0表示无冷却');
+
+            $form->switch('is_visible', '是否可见')
                 ->default(true)
-                ->help('合成时是否消耗该材料,否则只需要拥有但不会减少');
+                ->help('是否在游戏中对玩家可见');
+
+            // 解锁条件
+            $form->keyValue('unlock_condition', '解锁条件')
+                ->help('设置解锁该配方的条件,如:level:10表示玩家等级达到10级');
+
+            // 配方材料
+            $form->hasMany('materials', '配方材料', function (Form\NestedForm $form) {
+                $form->select('item_id', '物品')
+                    ->options(ItemItem::pluck('name', 'id'))
+                    ->required();
+                $form->number('quantity', '数量')
+                    ->default(1)
+                    ->min(1)
+                    ->required();
+                $form->switch('is_consumed', '是否消耗')
+                    ->default(true)
+                    ->help('合成时是否消耗该材料,否则只需要拥有但不会减少');
+            });
         });
-
-        return $form;
     }
 }

+ 0 - 15
app/Module/GameItems/AdminControllers/TestController.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Module\GameItems\AdminControllers;
-
-use UCore\DcatAdmin\AdminController;
-use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Log;
-use Spatie\RouteAttributes\Attributes\Get;
-use Spatie\RouteAttributes\Attributes\Prefix;
-
-#[Prefix('game-items-test')]
-class TestController extends AdminController
-{
-
-}

+ 91 - 94
app/Module/GameItems/AdminControllers/TransactionLogController.php

@@ -4,9 +4,10 @@ namespace App\Module\GameItems\AdminControllers;
 
 use App\Module\GameItems\Enums\TRANSACTION_TYPE;
 use App\Module\GameItems\Models\ItemTransactionLog;
+use App\Module\GameItems\Models\Item as ItemItem;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Show;
-use Dcat\Admin\Http\Controllers\AdminController;
+use UCore\DcatAdmin\AdminController;
 use Dcat\Admin\Layout\Content;
 use Spatie\RouteAttributes\Attributes\Resource;
 
@@ -34,51 +35,49 @@ class TransactionLogController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemTransactionLog());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemTransactionLog(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('item.name', '物品名称');
+            $grid->column('instance_id', '实例ID');
+            $grid->column('quantity', '数量');
+            $grid->column('transaction_type', '交易类型')->display(function ($value) {
+                return TRANSACTION_TYPE::getName($value);
+            });
+            $grid->column('source_type', '来源类型');
+            $grid->column('source_id', '来源ID');
+            $grid->column('expire_at', '过期时间');
+            $grid->column('ip_address', 'IP地址');
+            $grid->column('created_at', '创建时间')->sortable();
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('item_id', '物品')->select(
+                    ItemItem::pluck('name', 'id')
+                );
+                $filter->equal('instance_id', '实例ID');
+                $filter->equal('transaction_type', '交易类型')->select(TRANSACTION_TYPE::all());
+                $filter->like('source_type', '来源类型');
+                $filter->equal('source_id', '来源ID');
+                $filter->between('created_at', '创建时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('item.name', '物品名称');
-        $grid->column('instance_id', '实例ID');
-        $grid->column('quantity', '数量');
-        $grid->column('transaction_type', '交易类型')->display(function ($value) {
-            return TRANSACTION_TYPE::getName($value);
-        });
-        $grid->column('source_type', '来源类型');
-        $grid->column('source_id', '来源ID');
-        $grid->column('expire_at', '过期时间');
-        $grid->column('ip_address', 'IP地址');
-        $grid->column('created_at', '创建时间')->sortable();
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('item_id', '物品')->select(
-                ItemItem::pluck('name', 'id')
-            );
-            $filter->equal('instance_id', '实例ID');
-            $filter->equal('transaction_type', '交易类型')->select(TRANSACTION_TYPE::all());
-            $filter->like('source_type', '来源类型');
-            $filter->equal('source_id', '来源ID');
-            $filter->between('created_at', '创建时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -104,61 +103,59 @@ class TransactionLogController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemTransactionLog::findOrFail($id));
-
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
+        return Show::make(ItemTransactionLog::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('item.name', '物品名称');
+            $show->field('instance_id', '实例ID');
+            $show->field('quantity', '数量');
+            $show->field('transaction_type', '交易类型')->as(function ($value) {
+                return TRANSACTION_TYPE::getName($value);
+            });
+            $show->field('source_type', '来源类型');
+            $show->field('source_id', '来源ID');
+
+            // 显示详细信息
+            $show->field('details', '详细信息')->as(function ($details) {
+                if (empty($details)) {
+                    return '无';
+                }
 
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('item.name', '物品名称');
-        $show->field('instance_id', '实例ID');
-        $show->field('quantity', '数量');
-        $show->field('transaction_type', '交易类型')->as(function ($value) {
-            return TRANSACTION_TYPE::getName($value);
-        });
-        $show->field('source_type', '来源类型');
-        $show->field('source_id', '来源ID');
-
-        // 显示详细信息
-        $show->field('details', '详细信息')->as(function ($details) {
-            if (empty($details)) {
-                return '无';
-            }
-
-            if (is_string($details)) {
-                $details = json_decode($details, true);
-            }
-
-            if (is_array($details)) {
-                $html = '<table class="table table-bordered">';
-                $html .= '<thead><tr><th>键</th><th>值</th></tr></thead>';
-                $html .= '<tbody>';
-
-                foreach ($details as $key => $value) {
-                    $html .= '<tr>';
-                    $html .= '<td>' . $key . '</td>';
-                    $html .= '<td>' . (is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value) . '</td>';
-                    $html .= '</tr>';
+                if (is_string($details)) {
+                    $details = json_decode($details, true);
                 }
 
-                $html .= '</tbody></table>';
+                if (is_array($details)) {
+                    $html = '<table class="table table-bordered">';
+                    $html .= '<thead><tr><th>键</th><th>值</th></tr></thead>';
+                    $html .= '<tbody>';
 
-                return $html;
-            }
+                    foreach ($details as $key => $value) {
+                        $html .= '<tr>';
+                        $html .= '<td>' . $key . '</td>';
+                        $html .= '<td>' . (is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value) . '</td>';
+                        $html .= '</tr>';
+                    }
 
-            return $details;
-        })->unescape();
+                    $html .= '</tbody></table>';
 
-        $show->field('expire_at', '过期时间');
-        $show->field('ip_address', 'IP地址');
-        $show->field('device_info', '设备信息');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
+                    return $html;
+                }
 
-        return $show;
+                return $details;
+            })->unescape();
+
+            $show->field('expire_at', '过期时间');
+            $show->field('ip_address', 'IP地址');
+            $show->field('device_info', '设备信息');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+        });
     }
 }

+ 151 - 155
app/Module/GameItems/AdminControllers/UserItemController.php

@@ -29,30 +29,28 @@ class UserItemController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemUser());
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('item.name', '物品名称');
-        $grid->column('instance_id', '实例ID');
-        $grid->column('quantity', '数量');
-        $grid->column('expire_at', '过期时间');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('item_id', '物品')->select(
-                Item::pluck('name', 'id')
-            );
-            $filter->equal('instance_id', '实例ID');
-            $filter->between('quantity', '数量');
-            $filter->between('expire_at', '过期时间')->datetime();
+        return Grid::make(new ItemUser(), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('item.name', '物品名称');
+            $grid->column('instance_id', '实例ID');
+            $grid->column('quantity', '数量');
+            $grid->column('expire_at', '过期时间');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('item_id', '物品')->select(
+                    Item::pluck('name', 'id')
+                );
+                $filter->equal('instance_id', '实例ID');
+                $filter->between('quantity', '数量');
+                $filter->between('expire_at', '过期时间')->datetime();
+            });
         });
-
-        return $grid;
     }
 
     /**
@@ -78,111 +76,111 @@ class UserItemController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemUser::findOrFail($id));
-
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-        $show->field('item.name', '物品名称');
-        $show->field('item.description', '物品描述');
-        $show->field('item.type', '物品类型')->as(function ($type) {
-            $types = [
-                1 => '可使用',
-                2 => '可装备',
-                3 => '可合成',
-                4 => '可交任务',
-                5 => '可开启',
-            ];
-            return $types[$type] ?? '未知';
-        });
-
-        // 如果是单独属性物品,显示实例信息
-        if ($show->getModel()->instance_id) {
-            $show->field('instance_id', '实例ID');
-            $show->field('instance.name', '实例名称');
-
-            // 显示实例显示属性
-            $show->field('instance.display_attributes', '实例显示属性')->as(function ($attributes) {
-                if (empty($attributes)) {
-                    return '无';
-                }
+        $model = ItemUser::findOrFail($id);
+
+        return Show::make($model, function (Show $show) {
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+            $show->field('item.name', '物品名称');
+            $show->field('item.description', '物品描述');
+            $show->field('item.type', '物品类型')->as(function ($type) {
+                $types = [
+                    1 => '可使用',
+                    2 => '可装备',
+                    3 => '可合成',
+                    4 => '可交任务',
+                    5 => '可开启',
+                ];
+                return $types[$type] ?? '未知';
+            });
 
-                if (is_string($attributes)) {
-                    $attributes = json_decode($attributes, true);
-                }
+            // 如果是单独属性物品,显示实例信息
+            if ($show->getModel()->instance_id) {
+                $show->field('instance_id', '实例ID');
+                $show->field('instance.name', '实例名称');
 
-                if (is_array($attributes)) {
-                    $html = '<table class="table table-bordered">';
-                    $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
-                    $html .= '<tbody>';
+                // 显示实例显示属性
+                $show->field('instance.display_attributes', '实例显示属性')->as(function ($attributes) {
+                    if (empty($attributes)) {
+                        return '无';
+                    }
 
-                    foreach ($attributes as $key => $value) {
-                        $html .= '<tr>';
-                        $html .= '<td>' . $key . '</td>';
-                        $html .= '<td>' . $value . '</td>';
-                        $html .= '</tr>';
+                    if (is_string($attributes)) {
+                        $attributes = json_decode($attributes, true);
                     }
 
-                    $html .= '</tbody></table>';
+                    if (is_array($attributes)) {
+                        $html = '<table class="table table-bordered">';
+                        $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
+                        $html .= '<tbody>';
 
-                    return $html;
-                }
+                        foreach ($attributes as $key => $value) {
+                            $html .= '<tr>';
+                            $html .= '<td>' . $key . '</td>';
+                            $html .= '<td>' . $value . '</td>';
+                            $html .= '</tr>';
+                        }
 
-                return $attributes;
-            })->unescape();
+                        $html .= '</tbody></table>';
 
-            // 显示实例数值属性
-            $show->field('instance.numeric_attributes', '实例数值属性')->as(function ($attributes) {
-                if (empty($attributes)) {
-                    return '无';
-                }
+                        return $html;
+                    }
 
-                if (is_string($attributes)) {
-                    $attributes = json_decode($attributes, true);
-                }
+                    return $attributes;
+                })->unescape();
 
-                if (is_array($attributes)) {
-                    $html = '<table class="table table-bordered">';
-                    $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
-                    $html .= '<tbody>';
+                // 显示实例数值属性
+                $show->field('instance.numeric_attributes', '实例数值属性')->as(function ($attributes) {
+                    if (empty($attributes)) {
+                        return '无';
+                    }
 
-                    foreach ($attributes as $key => $value) {
-                        $html .= '<tr>';
-                        $html .= '<td>' . $key . '</td>';
-                        $html .= '<td>' . $value . '</td>';
-                        $html .= '</tr>';
+                    if (is_string($attributes)) {
+                        $attributes = json_decode($attributes, true);
                     }
 
-                    $html .= '</tbody></table>';
+                    if (is_array($attributes)) {
+                        $html = '<table class="table table-bordered">';
+                        $html .= '<thead><tr><th>属性名</th><th>属性值</th></tr></thead>';
+                        $html .= '<tbody>';
 
-                    return $html;
-                }
+                        foreach ($attributes as $key => $value) {
+                            $html .= '<tr>';
+                            $html .= '<td>' . $key . '</td>';
+                            $html .= '<td>' . $value . '</td>';
+                            $html .= '</tr>';
+                        }
 
-                return $attributes;
-            })->unescape();
+                        $html .= '</tbody></table>';
 
-            $show->field('instance.tradable', '实例可交易')->as(function ($value) {
-                return $value ? '是' : '否';
-            });
-            $show->field('instance.is_bound', '实例已绑定')->as(function ($value) {
-                return $value ? '是' : '否';
-            });
-            $show->field('instance.bound_to', '实例绑定用户ID');
-            $show->field('instance.bind_exp_time', '实例绑定过期时间');
-            $show->field('instance.expire_at', '实例过期时间');
-        }
+                        return $html;
+                    }
 
-        $show->field('quantity', '数量');
-        $show->field('expire_at', '过期时间');
+                    return $attributes;
+                })->unescape();
+
+                $show->field('instance.tradable', '实例可交易')->as(function ($value) {
+                    return $value ? '是' : '否';
+                });
+                $show->field('instance.is_bound', '实例已绑定')->as(function ($value) {
+                    return $value ? '是' : '否';
+                });
+                $show->field('instance.bound_to', '实例绑定用户ID');
+                $show->field('instance.bind_exp_time', '实例绑定过期时间');
+                $show->field('instance.expire_at', '实例过期时间');
+            }
 
-        // 检查是否过期
-        $show->field('is_expired', '是否过期')->as(function () {
-            return $this->isExpired() ? '是' : '否';
-        });
+            $show->field('quantity', '数量');
+            $show->field('expire_at', '过期时间');
 
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
+            // 检查是否过期
+            $show->field('is_expired', '是否过期')->as(function () {
+                return $this->isExpired() ? '是' : '否';
+            });
 
-        return $show;
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
+        });
     }
 
     /**
@@ -221,55 +219,53 @@ class UserItemController extends AdminController
      */
     protected function form()
     {
-        $form = new Form(new ItemUser());
-
-        $form->text('user_id', '用户ID')
-            ->required()
-            ->help('物品所属的用户ID');
-
-        // 物品类型选择
-        $form->radio('item_type', '物品类型')
-            ->options(['normal' => '普通物品', 'unique' => '单独属性物品'])
-            ->default('normal')
-            ->when('normal', function (Form $form) {
-                $form->select('item_id', '物品')
-                    ->options(Item::pluck('name', 'id'))
-                    ->required();
-                $form->number('quantity', '数量')
-                    ->default(1)
-                    ->min(1)
-                    ->required();
-            })
-            ->when('unique', function (Form $form) {
-                $form->select('item_id', '物品')
-                    ->options(Item::where('is_unique', 1)->pluck('name', 'id'))
-                    ->required();
-                $form->select('instance_id', '物品实例')
-                    ->options(function ($id) {
-                        if ($id) {
-                            $instance = ItemInstance::find($id);
-                            if ($instance) {
-                                return [$instance->id => $instance->name . ' (ID: ' . $instance->id . ')'];
+        return Form::make(new ItemUser(), function (Form $form) {
+            $form->text('user_id', '用户ID')
+                ->required()
+                ->help('物品所属的用户ID');
+
+            // 物品类型选择
+            $form->radio('item_type', '物品类型')
+                ->options(['normal' => '普通物品', 'unique' => '单独属性物品'])
+                ->default('normal')
+                ->when('normal', function (Form $form) {
+                    $form->select('item_id', '物品')
+                        ->options(Item::pluck('name', 'id'))
+                        ->required();
+                    $form->number('quantity', '数量')
+                        ->default(1)
+                        ->min(1)
+                        ->required();
+                })
+                ->when('unique', function (Form $form) {
+                    $form->select('item_id', '物品')
+                        ->options(Item::where('is_unique', 1)->pluck('name', 'id'))
+                        ->required();
+                    $form->select('instance_id', '物品实例')
+                        ->options(function ($id) {
+                            if ($id) {
+                                $instance = ItemInstance::find($id);
+                                if ($instance) {
+                                    return [$instance->id => $instance->name . ' (ID: ' . $instance->id . ')'];
+                                }
                             }
-                        }
-                        return [];
-                    })
-                    ->ajax('api/game-items/instances')
-                    ->required();
-                $form->hidden('quantity')->default(1);
+                            return [];
+                        })
+                        ->ajax('api/game-items/instances')
+                        ->required();
+                    $form->hidden('quantity')->default(1);
+                });
+
+            $form->datetime('expire_at', '过期时间')
+                ->help('物品过期时间,为空表示使用物品默认过期时间');
+
+            // 保存前回调
+            $form->saving(function (Form $form) {
+                // 如果是单独属性物品,数量固定为1
+                if ($form->item_type == 'unique') {
+                    $form->quantity = 1;
+                }
             });
-
-        $form->datetime('expire_at', '过期时间')
-            ->help('物品过期时间,为空表示使用物品默认过期时间');
-
-        // 保存前回调
-        $form->saving(function (Form $form) {
-            // 如果是单独属性物品,数量固定为1
-            if ($form->item_type == 'unique') {
-                $form->quantity = 1;
-            }
         });
-
-        return $form;
     }
 }

+ 73 - 77
app/Module/GameItems/AdminControllers/UserOutputCounterController.php

@@ -34,42 +34,40 @@ class UserOutputCounterController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemUserOutputCounter());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemUserOutputCounter(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('outputLimit.item.name', '物品名称');
+            $grid->column('current_count', '当前计数');
+            $grid->column('last_reset_time', '上次重置时间');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('limit_id', '限制ID')->select(
+                    ItemOutputLimit::with('item')->get()->pluck('item.name', 'id')
+                );
+                $filter->between('current_count', '当前计数');
+                $filter->between('last_reset_time', '上次重置时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('outputLimit.item.name', '物品名称');
-        $grid->column('current_count', '当前计数');
-        $grid->column('last_reset_time', '上次重置时间');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('limit_id', '限制ID')->select(
-                ItemOutputLimit::with('item')->get()->pluck('item.name', 'id')
-            );
-            $filter->between('current_count', '当前计数');
-            $filter->between('last_reset_time', '上次重置时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -95,48 +93,46 @@ class UserOutputCounterController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemUserOutputCounter::findOrFail($id));
-
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
-
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-
-        // 显示限制信息
-        $show->field('limit_id', '限制ID');
-        $show->field('outputLimit.item.name', '物品名称');
-        $show->field('outputLimit.limit_type', '限制类型')->as(function ($value) {
-            $types = [
-                ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
-                ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
-                ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
-                ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
-                ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
-            ];
-            return $types[$value] ?? '未知';
+        return Show::make(ItemUserOutputCounter::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+
+            // 显示限制信息
+            $show->field('limit_id', '限制ID');
+            $show->field('outputLimit.item.name', '物品名称');
+            $show->field('outputLimit.limit_type', '限制类型')->as(function ($value) {
+                $types = [
+                    ItemOutputLimit::LIMIT_TYPE_GLOBAL => '全局限制',
+                    ItemOutputLimit::LIMIT_TYPE_USER => '用户限制',
+                    ItemOutputLimit::LIMIT_TYPE_DAILY => '每日限制',
+                    ItemOutputLimit::LIMIT_TYPE_WEEKLY => '每周限制',
+                    ItemOutputLimit::LIMIT_TYPE_MONTHLY => '每月限制',
+                ];
+                return $types[$value] ?? '未知';
+            });
+            $show->field('outputLimit.max_quantity', '最大数量');
+
+            $show->field('current_count', '当前计数');
+
+            // 计算剩余可获取数量
+            $show->field('remaining_count', '剩余可获取数量')->as(function () {
+                if (!$this->outputLimit) {
+                    return '未知';
+                }
+
+                $remaining = max(0, $this->outputLimit->max_quantity - $this->current_count);
+                return $remaining;
+            });
+
+            $show->field('last_reset_time', '上次重置时间');
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
         });
-        $show->field('outputLimit.max_quantity', '最大数量');
-
-        $show->field('current_count', '当前计数');
-
-        // 计算剩余可获取数量
-        $show->field('remaining_count', '剩余可获取数量')->as(function () {
-            if (!$this->outputLimit) {
-                return '未知';
-            }
-
-            $remaining = max(0, $this->outputLimit->max_quantity - $this->current_count);
-            return $remaining;
-        });
-
-        $show->field('last_reset_time', '上次重置时间');
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
     }
 }

+ 87 - 91
app/Module/GameItems/AdminControllers/UserRecipeController.php

@@ -35,49 +35,47 @@ class UserRecipeController extends AdminController
      */
     protected function grid()
     {
-        $grid = new Grid(new ItemUserRecipe());
-
-        // 禁用创建、编辑和删除按钮
-        $grid->disableCreateButton();
-        $grid->disableActions();
-        $grid->disableBatchDelete();
-        $grid->disableDeleteButton();
-        $grid->disableEditButton();
-
-        // 只保留详情按钮
-        $grid->actions(function (Grid\Displayers\Actions $actions) {
-            $actions->disableDelete();
-            $actions->disableEdit();
-            $actions->disableQuickEdit();
+        return Grid::make(new ItemUserRecipe(), function (Grid $grid) {
+            // 禁用创建、编辑和删除按钮
+            $grid->disableCreateButton();
+            $grid->disableActions();
+            $grid->disableBatchDelete();
+            $grid->disableDeleteButton();
+            $grid->disableEditButton();
+
+            // 只保留详情按钮
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+            });
+
+            $grid->column('id', 'ID')->sortable();
+            $grid->column('user_id', '用户ID');
+            $grid->column('recipe.name', '配方名称');
+            $grid->column('is_unlocked', '是否解锁')->switch();
+            $grid->column('unlock_time', '解锁时间');
+            $grid->column('craft_count', '合成次数');
+            $grid->column('last_craft_time', '上次合成时间');
+            $grid->column('created_at', '创建时间');
+            $grid->column('updated_at', '更新时间');
+
+            // 筛选
+            $grid->filter(function ($filter) {
+                $filter->equal('id', 'ID');
+                $filter->equal('user_id', '用户ID');
+                $filter->equal('recipe_id', '配方')->select(
+                    ItemRecipe::pluck('name', 'id')
+                );
+                $filter->equal('is_unlocked', '是否解锁')->radio([
+                    1 => '是',
+                    0 => '否',
+                ]);
+                $filter->between('unlock_time', '解锁时间')->datetime();
+                $filter->between('craft_count', '合成次数');
+                $filter->between('last_craft_time', '上次合成时间')->datetime();
+            });
         });
-
-        $grid->column('id', 'ID')->sortable();
-        $grid->column('user_id', '用户ID');
-        $grid->column('recipe.name', '配方名称');
-        $grid->column('is_unlocked', '是否解锁')->switch();
-        $grid->column('unlock_time', '解锁时间');
-        $grid->column('craft_count', '合成次数');
-        $grid->column('last_craft_time', '上次合成时间');
-        $grid->column('created_at', '创建时间');
-        $grid->column('updated_at', '更新时间');
-
-        // 筛选
-        $grid->filter(function ($filter) {
-            $filter->equal('id', 'ID');
-            $filter->equal('user_id', '用户ID');
-            $filter->equal('recipe_id', '配方')->select(
-                ItemRecipe::pluck('name', 'id')
-            );
-            $filter->equal('is_unlocked', '是否解锁')->radio([
-                1 => '是',
-                0 => '否',
-            ]);
-            $filter->between('unlock_time', '解锁时间')->datetime();
-            $filter->between('craft_count', '合成次数');
-            $filter->between('last_craft_time', '上次合成时间')->datetime();
-        });
-
-        return $grid;
     }
 
     /**
@@ -103,55 +101,53 @@ class UserRecipeController extends AdminController
      */
     protected function detail($id)
     {
-        $show = new Show(ItemUserRecipe::findOrFail($id));
-
-        // 禁用编辑和删除按钮
-        $show->panel()->tools(function ($tools) {
-            $tools->disableEdit();
-            $tools->disableDelete();
-        });
-
-        $show->field('id', 'ID');
-        $show->field('user_id', '用户ID');
-
-        // 显示配方信息
-        $show->field('recipe.name', '配方名称');
-        $show->field('recipe.resultItem.name', '产出物品');
-        $show->field('recipe.result_quantity', '产出数量');
-        $show->field('recipe.success_rate', '成功率')->as(function ($value) {
-            return ($value * 100) . '%';
-        });
-        $show->field('recipe.cooldown_seconds', '冷却时间(秒)');
-
-        $show->field('is_unlocked', '是否解锁')->as(function ($value) {
-            return $value ? '是' : '否';
+        return Show::make(ItemUserRecipe::findOrFail($id), function (Show $show) {
+            // 禁用编辑和删除按钮
+            $show->panel()->tools(function ($tools) {
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+
+            $show->field('id', 'ID');
+            $show->field('user_id', '用户ID');
+
+            // 显示配方信息
+            $show->field('recipe.name', '配方名称');
+            $show->field('recipe.resultItem.name', '产出物品');
+            $show->field('recipe.result_quantity', '产出数量');
+            $show->field('recipe.success_rate', '成功率')->as(function ($value) {
+                return ($value * 100) . '%';
+            });
+            $show->field('recipe.cooldown_seconds', '冷却时间(秒)');
+
+            $show->field('is_unlocked', '是否解锁')->as(function ($value) {
+                return $value ? '是' : '否';
+            });
+            $show->field('unlock_time', '解锁时间');
+            $show->field('craft_count', '合成次数');
+            $show->field('last_craft_time', '上次合成时间');
+
+            // 计算冷却状态
+            $show->field('cooldown_status', '冷却状态')->as(function () {
+                if (!$this->recipe || $this->recipe->cooldown_seconds <= 0) {
+                    return '无冷却';
+                }
+
+                if (!$this->last_craft_time) {
+                    return '未合成过';
+                }
+
+                $cooldownEnd = $this->last_craft_time->addSeconds($this->recipe->cooldown_seconds);
+                if ($cooldownEnd->isPast()) {
+                    return '已冷却完成';
+                } else {
+                    $remainingSeconds = now()->diffInSeconds($cooldownEnd, false);
+                    return '冷却中,剩余 ' . $remainingSeconds . ' 秒';
+                }
+            });
+
+            $show->field('created_at', '创建时间');
+            $show->field('updated_at', '更新时间');
         });
-        $show->field('unlock_time', '解锁时间');
-        $show->field('craft_count', '合成次数');
-        $show->field('last_craft_time', '上次合成时间');
-
-        // 计算冷却状态
-        $show->field('cooldown_status', '冷却状态')->as(function () {
-            if (!$this->recipe || $this->recipe->cooldown_seconds <= 0) {
-                return '无冷却';
-            }
-
-            if (!$this->last_craft_time) {
-                return '未合成过';
-            }
-
-            $cooldownEnd = $this->last_craft_time->addSeconds($this->recipe->cooldown_seconds);
-            if ($cooldownEnd->isPast()) {
-                return '已冷却完成';
-            } else {
-                $remainingSeconds = now()->diffInSeconds($cooldownEnd, false);
-                return '冷却中,剩余 ' . $remainingSeconds . ' 秒';
-            }
-        });
-
-        $show->field('created_at', '创建时间');
-        $show->field('updated_at', '更新时间');
-
-        return $show;
     }
 }

+ 3 - 0
noai.md

@@ -34,3 +34,6 @@ netresearch/jsonmapper
 * field end`的类注释,并注释该类的中文名
 
 参考 app/Module/GameItems/AdminControllers/ItemController.php ,修复后台其他控制器,Grid/Show/Form 应使用 make进行实例化
+
+参考 app/Module/GameItems/AdminControllers/ItemController.php ,修复其他控制器,使用 ShowHelper/FormHelper/GridHelper/
+