ActivityController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <?php
  2. namespace App\Module\Activity\AdminControllers;
  3. use App\Module\Activity\Enums\ACTIVITY_STATUS;
  4. use App\Module\Activity\Enums\ACTIVITY_TYPE;
  5. use App\Module\Activity\Models\ActivityConfig;
  6. use App\Module\Activity\Repositorys\ActivityConfigRepository;
  7. use App\Module\Game\Services\RewardService;
  8. use Dcat\Admin\Form;
  9. use Dcat\Admin\Grid;
  10. use Dcat\Admin\Show;
  11. use Dcat\Admin\Http\Controllers\AdminController;
  12. use Dcat\Admin\Layout\Content;
  13. use Dcat\Admin\Widgets\Card;
  14. use Dcat\Admin\Widgets\Table;
  15. /**
  16. * 活动管理控制器
  17. */
  18. class ActivityController extends AdminController
  19. {
  20. /**
  21. * 标题
  22. *
  23. * @return string
  24. */
  25. protected function title()
  26. {
  27. return '活动管理';
  28. }
  29. /**
  30. * 创建表格
  31. *
  32. * @return Grid
  33. */
  34. protected function grid()
  35. {
  36. return Grid::make(new ActivityConfigRepository(), function (Grid $grid) {
  37. $grid->column('id', 'ID')->sortable();
  38. $grid->column('name', '活动名称');
  39. $grid->column('type', '活动类型')->display(function ($type) {
  40. return ACTIVITY_TYPE::getName($type);
  41. });
  42. $grid->column('start_time', '开始时间')->sortable();
  43. $grid->column('end_time', '结束时间')->sortable();
  44. $grid->column('status', '状态')->display(function ($status) {
  45. return ACTIVITY_STATUS::getName($status);
  46. })->label([
  47. ACTIVITY_STATUS::NOT_STARTED => 'default',
  48. ACTIVITY_STATUS::IN_PROGRESS => 'success',
  49. ACTIVITY_STATUS::ENDED => 'warning',
  50. ACTIVITY_STATUS::CLOSED => 'danger',
  51. ]);
  52. $grid->column('display_order', '显示顺序')->sortable();
  53. $grid->column('reward_group_id', '奖励组ID');
  54. $grid->column('reward_group_code', '奖励组编码');
  55. $grid->column('created_at', '创建时间');
  56. $grid->column('updated_at', '更新时间');
  57. $grid->filter(function (Grid\Filter $filter) {
  58. $filter->equal('id', 'ID');
  59. $filter->like('name', '活动名称');
  60. $filter->equal('type', '活动类型')->select(ACTIVITY_TYPE::getAll());
  61. $filter->equal('status', '状态')->select(ACTIVITY_STATUS::getAll());
  62. $filter->between('start_time', '开始时间')->datetime();
  63. $filter->between('end_time', '结束时间')->datetime();
  64. });
  65. $grid->actions(function (Grid\Displayers\Actions $actions) {
  66. // 添加复制按钮
  67. $actions->append('<a href="' . admin_url('activity/activities/' . $actions->getKey() . '/duplicate') . '"><i class="fa fa-copy"></i> 复制</a>');
  68. // 添加更新状态按钮
  69. if ($actions->row->status === ACTIVITY_STATUS::NOT_STARTED) {
  70. $actions->append('<a href="' . admin_url('activity/activities/' . $actions->getKey() . '/start') . '"><i class="fa fa-play"></i> 开始</a>');
  71. } elseif ($actions->row->status === ACTIVITY_STATUS::IN_PROGRESS) {
  72. $actions->append('<a href="' . admin_url('activity/activities/' . $actions->getKey() . '/end') . '"><i class="fa fa-stop"></i> 结束</a>');
  73. } elseif ($actions->row->status === ACTIVITY_STATUS::ENDED) {
  74. $actions->append('<a href="' . admin_url('activity/activities/' . $actions->getKey() . '/close') . '"><i class="fa fa-times"></i> 关闭</a>');
  75. }
  76. });
  77. });
  78. }
  79. /**
  80. * 创建详情页
  81. *
  82. * @param mixed $id
  83. * @return Show
  84. */
  85. protected function detail($id)
  86. {
  87. return Show::make($id, new ActivityConfigRepository(), function (Show $show) {
  88. $show->field('id', 'ID');
  89. $show->field('name', '活动名称');
  90. $show->field('type', '活动类型')->as(function ($type) {
  91. return ACTIVITY_TYPE::getName($type);
  92. });
  93. $show->field('description', '活动描述');
  94. $show->field('start_time', '开始时间');
  95. $show->field('end_time', '结束时间');
  96. $show->field('status', '状态')->as(function ($status) {
  97. return ACTIVITY_STATUS::getName($status);
  98. });
  99. $show->field('display_order', '显示顺序');
  100. $show->field('icon', '活动图标')->image();
  101. $show->field('banner', '活动横幅')->image();
  102. $show->field('reward_group_id', '奖励组ID');
  103. $show->field('reward_group_code', '奖励组编码');
  104. $show->field('config_params', '配置参数')->json();
  105. $show->field('created_at', '创建时间');
  106. $show->field('updated_at', '更新时间');
  107. // 显示活动条件
  108. $show->divider();
  109. $show->field('条件')->as(function () {
  110. $conditions = $this->conditions()->get();
  111. if ($conditions->isEmpty()) {
  112. return '无条件';
  113. }
  114. $headers = ['ID', '条件类型', '参与条件', '完成条件', '显示顺序'];
  115. $rows = [];
  116. foreach ($conditions as $condition) {
  117. $rows[] = [
  118. $condition->id,
  119. $condition->getConditionTypeName(),
  120. $condition->is_participation_condition ? '是' : '否',
  121. $condition->is_completion_condition ? '是' : '否',
  122. $condition->display_order
  123. ];
  124. }
  125. return Card::make(
  126. Table::make($headers, $rows)
  127. );
  128. });
  129. // 显示奖励信息
  130. $show->divider();
  131. $show->field('奖励信息')->as(function () {
  132. if (!$this->reward_group_id && !$this->reward_group_code) {
  133. return '未配置奖励';
  134. }
  135. $rewardInfo = '奖励组ID: ' . ($this->reward_group_id ?: '无') . '<br>';
  136. $rewardInfo .= '奖励组编码: ' . ($this->reward_group_code ?: '无') . '<br>';
  137. // 这里可以调用奖励组服务获取更详细的奖励信息
  138. // 由于没有实际的奖励组服务,这里只返回基本信息
  139. return $rewardInfo;
  140. })->unescape();
  141. });
  142. }
  143. /**
  144. * 创建表单
  145. *
  146. * @return Form
  147. */
  148. protected function form()
  149. {
  150. return Form::make(new ActivityConfigRepository(), function (Form $form) {
  151. $form->display('id', 'ID');
  152. $form->text('name', '活动名称')->required();
  153. $form->select('type', '活动类型')->options(ACTIVITY_TYPE::getAll())->required();
  154. $form->textarea('description', '活动描述');
  155. $form->datetime('start_time', '开始时间')->required();
  156. $form->datetime('end_time', '结束时间')->required();
  157. $form->select('status', '状态')->options(ACTIVITY_STATUS::getAll())->default(ACTIVITY_STATUS::NOT_STARTED);
  158. $form->number('display_order', '显示顺序')->default(0);
  159. $form->image('icon', '活动图标')->autoUpload();
  160. $form->image('banner', '活动横幅')->autoUpload();
  161. // 奖励组选择
  162. $form->divider('奖励配置');
  163. $form->number('reward_group_id', '奖励组ID')->help('填写奖励组ID或奖励组编码,两者选其一即可');
  164. $form->text('reward_group_code', '奖励组编码')->help('填写奖励组ID或奖励组编码,两者选其一即可');
  165. // 活动条件
  166. $form->divider('活动条件');
  167. $form->hasMany('conditions', '条件', function (Form\NestedForm $form) {
  168. $form->select('condition_type', '条件类型')->options(\App\Module\Activity\Enums\CONDITION_TYPE::getAll())->required();
  169. $form->textarea('condition_params', '条件参数')->help('JSON格式,根据条件类型填写不同的参数');
  170. $form->switch('is_participation_condition', '参与条件')->default(false);
  171. $form->switch('is_completion_condition', '完成条件')->default(false);
  172. $form->number('display_order', '显示顺序')->default(0);
  173. });
  174. // 高级配置
  175. $form->divider('高级配置');
  176. $form->textarea('config_params', '配置参数')->help('JSON格式,用于存储活动特定的配置参数');
  177. $form->display('created_at', '创建时间');
  178. $form->display('updated_at', '更新时间');
  179. });
  180. }
  181. /**
  182. * 复制活动
  183. *
  184. * @param int $id
  185. * @param Content $content
  186. * @return Content
  187. */
  188. public function duplicate($id, Content $content)
  189. {
  190. $activity = ActivityConfig::with('conditions')->findOrFail($id);
  191. // 复制活动基本信息
  192. $newActivity = $activity->replicate();
  193. $newActivity->name = $activity->name . ' (复制)';
  194. $newActivity->status = ACTIVITY_STATUS::NOT_STARTED;
  195. $newActivity->save();
  196. // 复制活动条件
  197. foreach ($activity->conditions as $condition) {
  198. $newCondition = $condition->replicate();
  199. $newCondition->activity_id = $newActivity->id;
  200. $newCondition->save();
  201. }
  202. return $content
  203. ->title($this->title())
  204. ->description('复制活动')
  205. ->body(admin_success('复制成功', "已成功复制活动 [{$newActivity->name}]"))
  206. ->body("<script>setTimeout(function(){ window.location.href = '" . admin_url('activity/activities') . "'; }, 2000);</script>");
  207. }
  208. /**
  209. * 开始活动
  210. *
  211. * @param int $id
  212. * @param Content $content
  213. * @return Content
  214. */
  215. public function start($id, Content $content)
  216. {
  217. $activity = ActivityConfig::findOrFail($id);
  218. if ($activity->status !== ACTIVITY_STATUS::NOT_STARTED) {
  219. return $content
  220. ->title($this->title())
  221. ->description('开始活动')
  222. ->body(admin_error('操作失败', '只有未开始的活动才能开始'));
  223. }
  224. $activity->status = ACTIVITY_STATUS::IN_PROGRESS;
  225. $activity->save();
  226. // 触发活动状态变更事件
  227. event(new \App\Module\Activity\Events\ActivityStatusChangedEvent(
  228. $activity->id,
  229. ACTIVITY_STATUS::NOT_STARTED,
  230. ACTIVITY_STATUS::IN_PROGRESS
  231. ));
  232. return $content
  233. ->title($this->title())
  234. ->description('开始活动')
  235. ->body(admin_success('操作成功', "活动 [{$activity->name}] 已开始"))
  236. ->body("<script>setTimeout(function(){ window.location.href = '" . admin_url('activity/activities') . "'; }, 2000);</script>");
  237. }
  238. /**
  239. * 结束活动
  240. *
  241. * @param int $id
  242. * @param Content $content
  243. * @return Content
  244. */
  245. public function end($id, Content $content)
  246. {
  247. $activity = ActivityConfig::findOrFail($id);
  248. if ($activity->status !== ACTIVITY_STATUS::IN_PROGRESS) {
  249. return $content
  250. ->title($this->title())
  251. ->description('结束活动')
  252. ->body(admin_error('操作失败', '只有进行中的活动才能结束'));
  253. }
  254. $activity->status = ACTIVITY_STATUS::ENDED;
  255. $activity->save();
  256. // 触发活动状态变更事件
  257. event(new \App\Module\Activity\Events\ActivityStatusChangedEvent(
  258. $activity->id,
  259. ACTIVITY_STATUS::IN_PROGRESS,
  260. ACTIVITY_STATUS::ENDED
  261. ));
  262. return $content
  263. ->title($this->title())
  264. ->description('结束活动')
  265. ->body(admin_success('操作成功', "活动 [{$activity->name}] 已结束"))
  266. ->body("<script>setTimeout(function(){ window.location.href = '" . admin_url('activity/activities') . "'; }, 2000);</script>");
  267. }
  268. /**
  269. * 关闭活动
  270. *
  271. * @param int $id
  272. * @param Content $content
  273. * @return Content
  274. */
  275. public function close($id, Content $content)
  276. {
  277. $activity = ActivityConfig::findOrFail($id);
  278. if ($activity->status !== ACTIVITY_STATUS::ENDED) {
  279. return $content
  280. ->title($this->title())
  281. ->description('关闭活动')
  282. ->body(admin_error('操作失败', '只有已结束的活动才能关闭'));
  283. }
  284. $activity->status = ACTIVITY_STATUS::CLOSED;
  285. $activity->save();
  286. // 触发活动状态变更事件
  287. event(new \App\Module\Activity\Events\ActivityStatusChangedEvent(
  288. $activity->id,
  289. ACTIVITY_STATUS::ENDED,
  290. ACTIVITY_STATUS::CLOSED
  291. ));
  292. return $content
  293. ->title($this->title())
  294. ->description('关闭活动')
  295. ->body(admin_success('操作成功', "活动 [{$activity->name}] 已关闭"))
  296. ->body("<script>setTimeout(function(){ window.location.href = '" . admin_url('activity/activities') . "'; }, 2000);</script>");
  297. }
  298. }