MexAdminToolController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. namespace App\Module\Mex\AdminControllers;
  3. use App\Module\Mex\Services\MexAdminService;
  4. use App\Module\Mex\Logic\MexAdminLogic;
  5. use Spatie\RouteAttributes\Attributes\Get;
  6. use Spatie\RouteAttributes\Attributes\Post;
  7. use UCore\DcatAdmin\AdminController;
  8. use Dcat\Admin\Form;
  9. use Dcat\Admin\Layout\Content;
  10. use Dcat\Admin\Widgets\Card;
  11. use Dcat\Admin\Admin;
  12. use Illuminate\Http\Request;
  13. /**
  14. * 农贸市场管理员工具
  15. *
  16. * 提供物品注入、回收等管理员操作功能
  17. *
  18. * @menu 游戏运营管理/农贸市场管理/🛠 管理工具
  19. */
  20. class MexAdminToolController extends AdminController
  21. {
  22. /**
  23. * 页面标题
  24. *
  25. * @var string
  26. */
  27. protected $title = '农贸市场管理工具';
  28. /**
  29. * 工具页面
  30. */
  31. #[Get('mex-admin-tools', name: 'dcat.admin.mex-admin-tools.index')]
  32. public function index(Content $content)
  33. {
  34. return $content
  35. ->title($this->title)
  36. ->description('管理员操作工具')
  37. ->body($this->buildToolsPage());
  38. }
  39. /**
  40. * 物品注入页面
  41. */
  42. #[Get('mex-admin-tools/inject', name: 'dcat.admin.mex-admin-tools.inject')]
  43. public function inject(Content $content)
  44. {
  45. return $content
  46. ->title('物品注入')
  47. ->description('向市场注入物品,增加供应量')
  48. ->body($this->buildInjectForm());
  49. }
  50. /**
  51. * 物品回收页面
  52. */
  53. #[Get('mex-admin-tools/recycle', name: 'dcat.admin.mex-admin-tools.recycle')]
  54. public function recycle(Content $content)
  55. {
  56. return $content
  57. ->title('物品回收')
  58. ->description('从市场回收物品,减少供应量')
  59. ->body($this->buildRecycleForm());
  60. }
  61. /**
  62. * 初始化库存页面
  63. */
  64. #[Get('mex-admin-tools/initialize', name: 'dcat.admin.mex-admin-tools.initialize')]
  65. public function initialize(Content $content)
  66. {
  67. return $content
  68. ->title('初始化库存')
  69. ->description('为所有已定价的商品创建库存记录')
  70. ->body($this->buildInitializeForm());
  71. }
  72. /**
  73. * 处理物品注入
  74. */
  75. #[Post('mex-admin-tools/inject', name: 'dcat.admin.mex-admin-tools.inject.store')]
  76. public function storeInject(Request $request)
  77. {
  78. $request->validate([
  79. 'item_id' => 'required|integer|min:1',
  80. 'quantity' => 'required|integer|min:1',
  81. 'price' => 'required|numeric|min:0',
  82. 'remark' => 'nullable|string|max:255',
  83. ], [
  84. 'item_id.required' => '商品ID不能为空',
  85. 'item_id.integer' => '商品ID必须是整数',
  86. 'item_id.min' => '商品ID必须大于0',
  87. 'quantity.required' => '数量不能为空',
  88. 'quantity.integer' => '数量必须是整数',
  89. 'quantity.min' => '数量必须大于0',
  90. 'price.required' => '价格不能为空',
  91. 'price.numeric' => '价格必须是数字',
  92. 'price.min' => '价格不能为负数',
  93. 'remark.max' => '备注不能超过255个字符',
  94. ]);
  95. try {
  96. $result = MexAdminService::injectItem(
  97. adminUserId: Admin::user()->id,
  98. itemId: $request->item_id,
  99. quantity: $request->quantity,
  100. price: $request->price,
  101. remark: $request->remark ?? '后台管理员注入'
  102. );
  103. if ($result['success']) {
  104. admin_success('注入成功!', '操作ID: ' . $result['operation_id'] . ', 成交ID: ' . $result['transaction_id']);
  105. return redirect()->route('dcat.admin.mex-admin-tools.inject');
  106. } else {
  107. admin_error('注入失败', $result['message']);
  108. return back()->withInput();
  109. }
  110. } catch (\Exception $e) {
  111. admin_error('注入失败', $e->getMessage());
  112. return back()->withInput();
  113. }
  114. }
  115. /**
  116. * 处理物品回收
  117. */
  118. #[Post('mex-admin-tools/recycle', name: 'dcat.admin.mex-admin-tools.recycle.store')]
  119. public function storeRecycle(Request $request)
  120. {
  121. $request->validate([
  122. 'item_id' => 'required|integer|min:1',
  123. 'quantity' => 'required|integer|min:1',
  124. 'price' => 'required|numeric|min:0',
  125. 'remark' => 'nullable|string|max:255',
  126. ], [
  127. 'item_id.required' => '商品ID不能为空',
  128. 'item_id.integer' => '商品ID必须是整数',
  129. 'item_id.min' => '商品ID必须大于0',
  130. 'quantity.required' => '数量不能为空',
  131. 'quantity.integer' => '数量必须是整数',
  132. 'quantity.min' => '数量必须大于0',
  133. 'price.required' => '价格不能为空',
  134. 'price.numeric' => '价格必须是数字',
  135. 'price.min' => '价格不能为负数',
  136. 'remark.max' => '备注不能超过255个字符',
  137. ]);
  138. try {
  139. $result = MexAdminService::recycleItem(
  140. adminUserId: Admin::user()->id,
  141. itemId: $request->item_id,
  142. quantity: $request->quantity,
  143. price: $request->price,
  144. remark: $request->remark ?? '后台管理员回收'
  145. );
  146. if ($result['success']) {
  147. admin_success('回收成功!', '操作ID: ' . $result['operation_id'] . ', 成交ID: ' . $result['transaction_id']);
  148. return redirect()->route('dcat.admin.mex-admin-tools.recycle');
  149. } else {
  150. admin_error('回收失败', $result['message']);
  151. return back()->withInput();
  152. }
  153. } catch (\Exception $e) {
  154. admin_error('回收失败', $e->getMessage());
  155. return back()->withInput();
  156. }
  157. }
  158. /**
  159. * 处理初始化库存请求
  160. */
  161. #[Post('mex-admin-tools/initialize', name: 'dcat.admin.mex-admin-tools.initialize.store')]
  162. public function storeInitialize(Request $request)
  163. {
  164. try {
  165. $result = MexAdminLogic::initializeWarehouse(Admin::user()->id);
  166. if ($result['success']) {
  167. admin_success('初始化成功!', $result['message'] . ',共初始化了 ' . $result['initialized_count'] . ' 个商品的库存记录。');
  168. return redirect()->route('dcat.admin.mex-admin-tools.initialize');
  169. } else {
  170. admin_error('初始化失败', $result['message']);
  171. return back()->withInput();
  172. }
  173. } catch (\Exception $e) {
  174. admin_error('初始化失败', $e->getMessage());
  175. return back()->withInput();
  176. }
  177. }
  178. /**
  179. * 构建工具页面
  180. */
  181. private function buildToolsPage()
  182. {
  183. $card = new Card('农贸市场管理工具', '
  184. <div class="row">
  185. <div class="col-md-4">
  186. <div class="card">
  187. <div class="card-body text-center">
  188. <i class="fa fa-plus-circle fa-3x text-success mb-3"></i>
  189. <h5>物品注入</h5>
  190. <p class="text-muted">向市场投放商品,增加供应量</p>
  191. <a href="' . route('dcat.admin.mex-admin-tools.inject') . '" class="btn btn-success">
  192. <i class="fa fa-plus"></i> 开始注入
  193. </a>
  194. </div>
  195. </div>
  196. </div>
  197. <div class="col-md-4">
  198. <div class="card">
  199. <div class="card-body text-center">
  200. <i class="fa fa-minus-circle fa-3x text-warning mb-3"></i>
  201. <h5>物品回收</h5>
  202. <p class="text-muted">从市场回收商品,减少供应量</p>
  203. <a href="' . route('dcat.admin.mex-admin-tools.recycle') . '" class="btn btn-warning">
  204. <i class="fa fa-minus"></i> 开始回收
  205. </a>
  206. </div>
  207. </div>
  208. </div>
  209. <div class="col-md-4">
  210. <div class="card">
  211. <div class="card-body text-center">
  212. <i class="fa fa-database fa-3x text-info mb-3"></i>
  213. <h5>初始化库存</h5>
  214. <p class="text-muted">为已定价商品创建库存记录</p>
  215. <a href="' . route('dcat.admin.mex-admin-tools.initialize') . '" class="btn btn-info">
  216. <i class="fa fa-database"></i> 开始初始化
  217. </a>
  218. </div>
  219. </div>
  220. </div>
  221. </div>
  222. <div class="row mt-4">
  223. <div class="col-md-12">
  224. <div class="alert alert-info">
  225. <h6><i class="fa fa-info-circle"></i> 使用说明</h6>
  226. <ul class="mb-0">
  227. <li><strong>物品注入</strong>:相当于系统向仓库"卖出"物品,增加仓库库存,系统获得资金</li>
  228. <li><strong>物品回收</strong>:相当于系统从仓库"买入"物品,减少仓库库存,系统支出资金</li>
  229. <li>所有操作都会记录在管理员操作记录中,并生成对应的成交记录</li>
  230. <li>操作前请确认商品ID、数量和价格的准确性</li>
  231. </ul>
  232. </div>
  233. </div>
  234. </div>
  235. ');
  236. return $card;
  237. }
  238. /**
  239. * 构建注入表单
  240. */
  241. private function buildInjectForm()
  242. {
  243. $form = new Form();
  244. $form->action(route('dcat.admin.mex-admin-tools.inject.store'));
  245. $form->number('item_id', '商品ID')
  246. ->required()
  247. ->min(1)
  248. ->help('请输入要注入的商品ID');
  249. $form->number('quantity', '注入数量')
  250. ->required()
  251. ->min(1)
  252. ->help('请输入要注入的数量');
  253. $form->decimal('price', '注入价格')
  254. ->required()
  255. ->help('请输入注入价格(每个商品的价格)');
  256. $form->textarea('remark', '操作备注')
  257. ->rows(3)
  258. ->help('可选,记录本次操作的原因或说明');
  259. $form->html('<div class="alert alert-warning">
  260. <h6><i class="fa fa-exclamation-triangle"></i> 注意事项</h6>
  261. <ul class="mb-0">
  262. <li>注入操作相当于系统向仓库"卖出"物品</li>
  263. <li>会增加仓库的库存数量</li>
  264. <li>系统会获得相应的资金收入</li>
  265. <li>操作不可撤销,请谨慎操作</li>
  266. </ul>
  267. </div>');
  268. return $form;
  269. }
  270. /**
  271. * 构建回收表单
  272. */
  273. private function buildRecycleForm()
  274. {
  275. $form = new Form();
  276. $form->action(route('dcat.admin.mex-admin-tools.recycle.store'));
  277. $form->number('item_id', '商品ID')
  278. ->required()
  279. ->min(1)
  280. ->help('请输入要回收的商品ID');
  281. $form->number('quantity', '回收数量')
  282. ->required()
  283. ->min(1)
  284. ->help('请输入要回收的数量');
  285. $form->decimal('price', '回收价格')
  286. ->required()
  287. ->help('请输入回收价格(每个商品的价格)');
  288. $form->textarea('remark', '操作备注')
  289. ->rows(3)
  290. ->help('可选,记录本次操作的原因或说明');
  291. $form->html('<div class="alert alert-warning">
  292. <h6><i class="fa fa-exclamation-triangle"></i> 注意事项</h6>
  293. <ul class="mb-0">
  294. <li>回收操作相当于系统从仓库"买入"物品</li>
  295. <li>会减少仓库的库存数量</li>
  296. <li>系统会支出相应的资金</li>
  297. <li>回收数量不能超过当前库存</li>
  298. <li>操作不可撤销,请谨慎操作</li>
  299. </ul>
  300. </div>');
  301. return $form;
  302. }
  303. /**
  304. * 构建初始化库存表单
  305. */
  306. private function buildInitializeForm()
  307. {
  308. $form = new Form();
  309. $form->action(route('dcat.admin.mex-admin-tools.initialize.store'));
  310. $form->html('<div class="alert alert-info">
  311. <h6><i class="fa fa-info-circle"></i> 初始化说明</h6>
  312. <ul class="mb-0">
  313. <li>此操作将为所有已启用定价的商品创建库存记录</li>
  314. <li>初始库存数量为0,可通过注入操作增加库存</li>
  315. <li>只有当库存表为空时才能执行初始化</li>
  316. <li>初始化后可以正常进行注入、回收和用户交易</li>
  317. </ul>
  318. </div>');
  319. $form->html('<div class="alert alert-warning">
  320. <h6><i class="fa fa-exclamation-triangle"></i> 注意事项</h6>
  321. <ul class="mb-0">
  322. <li>初始化操作只能在库存表为空时执行</li>
  323. <li>如果已有库存记录,将无法执行初始化</li>
  324. <li>初始化完成后,所有已定价商品的库存都为0</li>
  325. <li>操作不可撤销,请确认后再执行</li>
  326. </ul>
  327. </div>');
  328. // 添加一个隐藏字段,确保表单可以提交
  329. $form->hidden('action')->value('initialize');
  330. return $form;
  331. }
  332. }