GameConsumeGroupController.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. namespace App\Module\Game\AdminControllers;
  3. use App\Module\Game\AdminControllers\Actions\DuplicateConsumeGroupAction;
  4. use App\Module\Game\Enums\CONSUME_TYPE;
  5. use App\Module\Game\Models\GameConsumeItem;
  6. use App\Module\Game\Repositorys\GameConsumeGroupRepository;
  7. use App\Module\Game\Repositorys\GameConsumeItemRepository;
  8. use Dcat\Admin\Form;
  9. use Dcat\Admin\Grid;
  10. use Dcat\Admin\Show;
  11. use Dcat\Admin\Http\Controllers\AdminController;
  12. use Spatie\RouteAttributes\Attributes\Resource;
  13. /**
  14. * 消耗组管理控制器
  15. */
  16. #[Resource('game-consume-groups', names: 'dcat.admin.game-consume-groups')]
  17. class GameConsumeGroupController extends AdminController
  18. {
  19. /**
  20. * 标题
  21. *
  22. * @return string
  23. */
  24. protected function title()
  25. {
  26. return '消耗组管理';
  27. }
  28. /**
  29. * 创建表格
  30. *
  31. * @return Grid
  32. */
  33. protected function grid()
  34. {
  35. return Grid::make(new GameConsumeGroupRepository(), function (Grid $grid) {
  36. // 预加载消耗项和标签关联数据
  37. $grid->model()->with(['consumeItems', 'tags']);
  38. $grid->column('id', 'ID')->sortable();
  39. $grid->column('name', '名称');
  40. $grid->column('code', '编码');
  41. $grid->column('description', '描述')->limit(30);
  42. // 标签列
  43. $grid->column('tags', '标签')->display(function () {
  44. return $this->formatTags();
  45. })->width(200);
  46. // 消耗详情列
  47. $grid->column('consume_details', '消耗详情')->display(function () {
  48. return $this->formatConsumeDetails();
  49. })->width(300);
  50. $grid->column('created_at', '创建时间');
  51. $grid->column('updated_at', '更新时间');
  52. // 添加消耗项数量统计和链接
  53. $grid->column('items_count', '消耗项数量')->display(function () {
  54. $count = GameConsumeItem::where('group_id', $this->getAttribute('id'))->count();
  55. return "<a href='game-consume-items?group_id={$this->getAttribute('id')}' target=\"_blank\" class='btn btn-sm btn-primary'>{$count} <i class='fa fa-arrow-right'></i></a>";
  56. });
  57. // 添加行操作
  58. $grid->actions(function (Grid\Displayers\Actions $actions) {
  59. // 添加复制操作
  60. $actions->append(new DuplicateConsumeGroupAction());
  61. // 添加管理消耗项操作
  62. $actions->append('<a href="game-consume-items?group_id='.$actions->getKey().'" target="_blank" class="btn btn-sm btn-primary">
  63. <i class="fa fa-list"></i> 管理消耗项
  64. </a>');
  65. });
  66. $grid->filter(function (Grid\Filter $filter) {
  67. $filter->equal('id', 'ID');
  68. $filter->like('name', '名称');
  69. $filter->like('code', '编码');
  70. // 标签筛选
  71. $tagRepository = new \App\Module\Game\Repositorys\GameTagRepository();
  72. $filter->whereHas('tags', '标签', function ($query) {
  73. $query->where('id', request('tags'));
  74. })->select($tagRepository->getActiveTagOptions());
  75. });
  76. });
  77. }
  78. /**
  79. * 创建详情页
  80. *
  81. * @param mixed $id
  82. * @return Show
  83. */
  84. protected function detail($id)
  85. {
  86. return Show::make($id, new GameConsumeGroupRepository(['tags']), function (Show $show) {
  87. $show->field('id', 'ID');
  88. $show->field('name', '名称');
  89. $show->field('code', '编码');
  90. $show->field('description', '描述');
  91. // 标签显示
  92. $show->field('tags', '标签')->as(function ($tags) {
  93. if (empty($tags)) {
  94. return '<span class="text-muted">无标签</span>';
  95. }
  96. $tagHtml = [];
  97. foreach ($tags as $tag) {
  98. // 使用静态方法计算对比色
  99. $contrastColor = \App\Module\Game\AdminControllers\GameConsumeGroupController::calculateContrastColor($tag['color']);
  100. $tagHtml[] = sprintf(
  101. '<span class="badge" style="background-color: %s; color: %s;">%s</span>',
  102. $tag['color'],
  103. $contrastColor,
  104. $tag['name']
  105. );
  106. }
  107. return implode(' ', $tagHtml);
  108. });
  109. $show->field('created_at', '创建时间');
  110. $show->field('updated_at', '更新时间');
  111. // 显示消耗项列表
  112. $show->relation('consumeItems', '消耗项列表', function ($model) {
  113. $grid = new Grid(new GameConsumeItemRepository());
  114. $grid->model()->where('group_id', $model->id);
  115. $grid->column('id', 'ID');
  116. $grid->column('consume_type', '消耗类型')->display(function ($type) {
  117. return CONSUME_TYPE::getName($type);
  118. });
  119. $grid->column('target_id', '目标')->display(function ($targetId) {
  120. // 获取完整的消耗项对象
  121. $consumeItem = GameConsumeItem::find($this->getAttribute('id'));
  122. if (!$consumeItem) {
  123. return $targetId;
  124. }
  125. // 使用统一的消耗类型描述器获取目标名称
  126. $targetName = \App\Module\Game\Services\ConsumeTypeDescriptor::getTargetName($consumeItem->consume_type, $targetId);
  127. return "{$targetName} (ID: {$targetId})";
  128. });
  129. $grid->column('quantity', '数量');
  130. // 添加操作按钮
  131. $grid->disableCreateButton();
  132. $grid->actions(function (Grid\Displayers\Actions $actions) {
  133. $actions->disableDelete();
  134. $actions->disableEdit();
  135. $actions->disableView();
  136. // 添加编辑链接
  137. $actions->append('<a href="game-consume-items/'.$actions->getKey().'/edit" class="btn btn-sm btn-primary">
  138. <i class="fa fa-edit"></i> 编辑
  139. </a>');
  140. });
  141. $grid->disableBatchDelete();
  142. $grid->disableRowSelector();
  143. // 添加创建按钮
  144. $grid->tools(function (Grid\Tools $tools) use ($model) {
  145. $tools->append('<a href="game-consume-items/create?group_id='.$model->id.'" class="btn btn-sm btn-success">
  146. <i class="fa fa-plus"></i> 添加消耗项
  147. </a>');
  148. });
  149. return $grid;
  150. });
  151. // 添加返回按钮
  152. $show->tools(function (Show\Tools $tools) {
  153. $tools->append('<a href="game-consume-groups" class="btn btn-sm btn-default">
  154. <i class="fa fa-arrow-left"></i> 返回列表
  155. </a>');
  156. });
  157. });
  158. }
  159. /**
  160. * 创建表单
  161. *
  162. * @return Form
  163. */
  164. protected function form()
  165. {
  166. return Form::make(new GameConsumeGroupRepository(['tags']), function (Form $form) {
  167. $form->display('id', 'ID');
  168. $form->text('name', '名称')->required();
  169. $form->text('code', '编码')
  170. ->required()
  171. ->creationRules(['required', 'unique:game_consume_groups,code'])
  172. ->updateRules(['required', 'unique:game_consume_groups,code,{{id}}']);
  173. $form->textarea('description', '描述');
  174. // 标签选择
  175. $tagRepository = new \App\Module\Game\Repositorys\GameTagRepository();
  176. $form->multipleSelect('tags', '标签')
  177. ->options($tagRepository->getActiveTagOptions())
  178. ->help('可以选择多个标签来分类管理消耗组');
  179. $form->display('created_at', '创建时间');
  180. $form->display('updated_at', '更新时间');
  181. // 添加提示信息,告知用户如何管理消耗项
  182. if ($form->isEditing()) {
  183. $id = $form->getKey();
  184. $form->html('<div class="alert alert-info">
  185. <p><i class="fa fa-info-circle"></i> 消耗项管理已移至单独页面,请保存当前表单后使用以下链接管理消耗项:</p>
  186. <a href="'.admin_url('game-consume-items?group_id='.$id).'" class="btn btn-primary" target="_blank">
  187. <i class="fa fa-list"></i> 管理消耗项
  188. </a>
  189. </div>');
  190. } else {
  191. $form->html('<div class="alert alert-info">
  192. <p><i class="fa fa-info-circle"></i> 消耗项管理已移至单独页面,请先保存当前表单,然后才能添加消耗项。</p>
  193. </div>');
  194. }
  195. });
  196. }
  197. /**
  198. * 根据背景色获取对比色
  199. *
  200. * @param string $hexColor
  201. * @return string
  202. */
  203. public static function calculateContrastColor(string $hexColor): string
  204. {
  205. $hexColor = ltrim($hexColor, '#');
  206. $r = hexdec(substr($hexColor, 0, 2));
  207. $g = hexdec(substr($hexColor, 2, 2));
  208. $b = hexdec(substr($hexColor, 4, 2));
  209. $brightness = ($r * 299 + $g * 587 + $b * 114) / 1000;
  210. return $brightness > 128 ? '#000000' : '#ffffff';
  211. }
  212. }