From 1027612cc0b8884a6728eb2da03be9b3d8d4c98b Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Wed, 25 Mar 2026 14:33:58 +0800 Subject: [PATCH] =?UTF-8?q?[=E8=89=B2=E5=AD=90=E6=B8=B8=E6=88=8F]=E5=BA=95?= =?UTF-8?q?=E6=B3=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../locales/langs/en/dice/ante_config.json | 37 +++++ .../locales/langs/zh/dice/ante_config.json | 37 +++++ .../plugin/dice/ante_config/index/index.vue | 139 ++++++++++++++++++ .../ante_config/index/modules/edit-dialog.vue | 126 ++++++++++++++++ .../index/modules/table-search.vue | 68 +++++++++ .../plugin/dice/api/ante_config/index.ts | 40 +++++ .../ante_config/DiceAnteConfigController.php | 78 ++++++++++ .../logic/ante_config/DiceAnteConfigLogic.php | 90 ++++++++++++ .../dice/model/ante_config/DiceAnteConfig.php | 48 ++++++ .../ante_config/DiceAnteConfigValidate.php | 34 +++++ server/db/dice_ante_config.sql | 17 +++ server/db/dice_ante_config_menu.sql | 62 ++++++++ server/plugin/saiadmin/config/route.php | 1 + 13 files changed, 777 insertions(+) create mode 100644 saiadmin-artd/src/locales/langs/en/dice/ante_config.json create mode 100644 saiadmin-artd/src/locales/langs/zh/dice/ante_config.json create mode 100644 saiadmin-artd/src/views/plugin/dice/ante_config/index/index.vue create mode 100644 saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/edit-dialog.vue create mode 100644 saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/table-search.vue create mode 100644 saiadmin-artd/src/views/plugin/dice/api/ante_config/index.ts create mode 100644 server/app/dice/controller/ante_config/DiceAnteConfigController.php create mode 100644 server/app/dice/logic/ante_config/DiceAnteConfigLogic.php create mode 100644 server/app/dice/model/ante_config/DiceAnteConfig.php create mode 100644 server/app/dice/validate/ante_config/DiceAnteConfigValidate.php create mode 100644 server/db/dice_ante_config.sql create mode 100644 server/db/dice_ante_config_menu.sql diff --git a/saiadmin-artd/src/locales/langs/en/dice/ante_config.json b/saiadmin-artd/src/locales/langs/en/dice/ante_config.json new file mode 100644 index 0000000..2130a3c --- /dev/null +++ b/saiadmin-artd/src/locales/langs/en/dice/ante_config.json @@ -0,0 +1,37 @@ +{ + "search": { + "name": "Name", + "title": "Title", + "isDefault": "Default", + "placeholderName": "Please enter name", + "placeholderTitle": "Please enter title", + "placeholderIsDefault": "Please select default status" + }, + "table": { + "id": "ID", + "name": "Name", + "title": "Title", + "mult": "Ante Multiplier", + "isDefault": "Default Ante", + "defaultYes": "Yes", + "defaultNo": "No", + "createTime": "Create Time", + "updateTime": "Update Time" + }, + "form": { + "titleAdd": "Add Ante Config", + "titleEdit": "Edit Ante Config", + "labelName": "Name", + "labelTitle": "Title", + "labelMult": "Ante Multiplier", + "labelIsDefault": "Default Ante", + "placeholderName": "Please enter name", + "placeholderTitle": "Please enter title", + "ruleNameRequired": "Please enter name", + "ruleTitleRequired": "Please enter title", + "ruleMultRequired": "Please enter ante multiplier", + "ruleDefaultRequired": "Please select default status", + "addSuccess": "Added successfully", + "editSuccess": "Updated successfully" + } +} diff --git a/saiadmin-artd/src/locales/langs/zh/dice/ante_config.json b/saiadmin-artd/src/locales/langs/zh/dice/ante_config.json new file mode 100644 index 0000000..4d33405 --- /dev/null +++ b/saiadmin-artd/src/locales/langs/zh/dice/ante_config.json @@ -0,0 +1,37 @@ +{ + "search": { + "name": "名称", + "title": "标题", + "isDefault": "是否默认", + "placeholderName": "请输入名称", + "placeholderTitle": "请输入标题", + "placeholderIsDefault": "请选择是否默认" + }, + "table": { + "id": "ID", + "name": "名称", + "title": "标题", + "mult": "底注倍率", + "isDefault": "默认底注", + "defaultYes": "是", + "defaultNo": "否", + "createTime": "创建时间", + "updateTime": "更新时间" + }, + "form": { + "titleAdd": "新增底注配置", + "titleEdit": "编辑底注配置", + "labelName": "名称", + "labelTitle": "标题", + "labelMult": "底注倍率", + "labelIsDefault": "默认底注", + "placeholderName": "请输入名称", + "placeholderTitle": "请输入标题", + "ruleNameRequired": "请输入名称", + "ruleTitleRequired": "请输入标题", + "ruleMultRequired": "请输入底注倍率", + "ruleDefaultRequired": "请选择是否默认底注", + "addSuccess": "新增成功", + "editSuccess": "修改成功" + } +} diff --git a/saiadmin-artd/src/views/plugin/dice/ante_config/index/index.vue b/saiadmin-artd/src/views/plugin/dice/ante_config/index/index.vue new file mode 100644 index 0000000..4da7ac2 --- /dev/null +++ b/saiadmin-artd/src/views/plugin/dice/ante_config/index/index.vue @@ -0,0 +1,139 @@ + + + diff --git a/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/edit-dialog.vue b/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/edit-dialog.vue new file mode 100644 index 0000000..1c1b738 --- /dev/null +++ b/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/edit-dialog.vue @@ -0,0 +1,126 @@ + + + diff --git a/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/table-search.vue b/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/table-search.vue new file mode 100644 index 0000000..17a5d81 --- /dev/null +++ b/saiadmin-artd/src/views/plugin/dice/ante_config/index/modules/table-search.vue @@ -0,0 +1,68 @@ + + + diff --git a/saiadmin-artd/src/views/plugin/dice/api/ante_config/index.ts b/saiadmin-artd/src/views/plugin/dice/api/ante_config/index.ts new file mode 100644 index 0000000..ab6fd1b --- /dev/null +++ b/saiadmin-artd/src/views/plugin/dice/api/ante_config/index.ts @@ -0,0 +1,40 @@ +import request from '@/utils/http' + +/** + * 底注配置 API + */ +export default { + list(params: Record) { + return request.get({ + url: '/core/dice/ante_config/DiceAnteConfig/index', + params + }) + }, + + read(id: number | string) { + return request.get({ + url: '/core/dice/ante_config/DiceAnteConfig/read?id=' + id + }) + }, + + save(params: Record) { + return request.post({ + url: '/core/dice/ante_config/DiceAnteConfig/save', + data: params + }) + }, + + update(params: Record) { + return request.put({ + url: '/core/dice/ante_config/DiceAnteConfig/update', + data: params + }) + }, + + delete(params: Record) { + return request.del({ + url: '/core/dice/ante_config/DiceAnteConfig/destroy', + data: params + }) + } +} diff --git a/server/app/dice/controller/ante_config/DiceAnteConfigController.php b/server/app/dice/controller/ante_config/DiceAnteConfigController.php new file mode 100644 index 0000000..6207181 --- /dev/null +++ b/server/app/dice/controller/ante_config/DiceAnteConfigController.php @@ -0,0 +1,78 @@ +logic = new DiceAnteConfigLogic(); + $this->validate = new DiceAnteConfigValidate(); + parent::__construct(); + } + + #[Permission('底注配置列表', 'dice:ante_config:index:index')] + public function index(Request $request): Response + { + $where = $request->more([ + ['name', ''], + ['title', ''], + ['is_default', ''], + ]); + $query = $this->logic->search($where); + $data = $this->logic->getList($query); + return $this->success($data); + } + + #[Permission('底注配置读取', 'dice:ante_config:index:read')] + public function read(Request $request): Response + { + $id = $request->input('id', ''); + $model = $this->logic->read($id); + $data = is_array($model) ? $model : $model->toArray(); + return $this->success($data); + } + + #[Permission('底注配置添加', 'dice:ante_config:index:save')] + public function save(Request $request): Response + { + $data = $request->post(); + $this->validate('save', $data); + $result = $this->logic->add($data); + return $result ? $this->success('add success') : $this->fail('add failed'); + } + + #[Permission('底注配置修改', 'dice:ante_config:index:update')] + public function update(Request $request): Response + { + $data = $request->post(); + $this->validate('update', $data); + $result = $this->logic->edit($data['id'], $data); + return $result ? $this->success('update success') : $this->fail('update failed'); + } + + #[Permission('底注配置删除', 'dice:ante_config:index:destroy')] + public function destroy(Request $request): Response + { + $ids = $request->post('ids', ''); + if (empty($ids)) { + return $this->fail('please select data to delete'); + } + $result = $this->logic->destroy($ids); + return $result ? $this->success('delete success') : $this->fail('delete failed'); + } +} diff --git a/server/app/dice/logic/ante_config/DiceAnteConfigLogic.php b/server/app/dice/logic/ante_config/DiceAnteConfigLogic.php new file mode 100644 index 0000000..27d1283 --- /dev/null +++ b/server/app/dice/logic/ante_config/DiceAnteConfigLogic.php @@ -0,0 +1,90 @@ +model = new DiceAnteConfig(); + } + + public function add(array $data): mixed + { + return $this->transaction(function () use ($data) { + $this->normalizeDefaultField($data); + if ((int) ($data['is_default'] ?? 0) === 1) { + $this->clearOtherDefaults(); + } + return parent::add($data); + }); + } + + public function edit($id, array $data): mixed + { + return $this->transaction(function () use ($id, $data) { + $this->normalizeDefaultField($data); + if ((int) ($data['is_default'] ?? 0) === 1) { + $this->clearOtherDefaults((int) $id); + } + return parent::edit($id, $data); + }); + } + + /** + * 防止删除后全表无默认:若删除了默认项,自动把最小 id 设为默认。 + */ + public function destroy($ids): bool + { + return $this->transaction(function () use ($ids) { + $idList = is_array($ids) ? $ids : explode(',', (string) $ids); + $intIds = []; + foreach ($idList as $v) { + $iv = (int) $v; + if ($iv > 0) { + $intIds[] = $iv; + } + } + if ($intIds === []) { + return false; + } + + $deletedDefaultCount = $this->model->whereIn('id', $intIds)->where('is_default', 1)->count(); + $result = $this->model->destroy($intIds); + if ($result && $deletedDefaultCount > 0) { + $first = $this->model->order('id', 'asc')->find(); + if ($first) { + $this->model->where('id', (int) $first['id'])->update(['is_default' => 1]); + } + } + return (bool) $result; + }); + } + + private function normalizeDefaultField(array &$data): void + { + if (!array_key_exists('is_default', $data)) { + return; + } + $data['is_default'] = ((int) $data['is_default']) === 1 ? 1 : 0; + } + + private function clearOtherDefaults(?int $excludeId = null): void + { + $query = $this->model->where('is_default', 1); + if ($excludeId !== null && $excludeId > 0) { + $query->where('id', '<>', $excludeId); + } + $query->update(['is_default' => 0]); + } +} diff --git a/server/app/dice/model/ante_config/DiceAnteConfig.php b/server/app/dice/model/ante_config/DiceAnteConfig.php new file mode 100644 index 0000000..6d46477 --- /dev/null +++ b/server/app/dice/model/ante_config/DiceAnteConfig.php @@ -0,0 +1,48 @@ +where('name', 'like', '%' . $value . '%'); + } + } + + public function searchTitleAttr($query, $value): void + { + if ($value !== '' && $value !== null) { + $query->where('title', 'like', '%' . $value . '%'); + } + } + + public function searchIsDefaultAttr($query, $value): void + { + if ($value !== '' && $value !== null) { + $query->where('is_default', (int) $value); + } + } +} diff --git a/server/app/dice/validate/ante_config/DiceAnteConfigValidate.php b/server/app/dice/validate/ante_config/DiceAnteConfigValidate.php new file mode 100644 index 0000000..d081829 --- /dev/null +++ b/server/app/dice/validate/ante_config/DiceAnteConfigValidate.php @@ -0,0 +1,34 @@ + 'require|max:64', + 'title' => 'require|max:255', + 'is_default' => 'require|in:0,1', + 'mult' => 'require|integer|gt:0', + ]; + + protected $message = [ + 'name' => '名称必须填写', + 'title' => '标题必须填写', + 'is_default' => '默认底注标记必须为 0 或 1', + 'mult' => '底注倍率必须为大于 0 的整数', + ]; + + protected $scene = [ + 'save' => ['name', 'title', 'is_default', 'mult'], + 'update' => ['name', 'title', 'is_default', 'mult'], + ]; +} diff --git a/server/db/dice_ante_config.sql b/server/db/dice_ante_config.sql new file mode 100644 index 0000000..a2e5977 --- /dev/null +++ b/server/db/dice_ante_config.sql @@ -0,0 +1,17 @@ +-- 底注配置表 +CREATE TABLE IF NOT EXISTS `dice_ante_config` ( + `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(64) NOT NULL COMMENT '名称', + `title` varchar(255) NOT NULL COMMENT '标题', + `is_default` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否默认底注:0否 1是(全表只允许一条)', + `mult` int NOT NULL DEFAULT 1 COMMENT '底注倍率', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_is_default` (`is_default`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Dice 底注配置表'; + +-- 可选初始化数据(保留一条默认底注) +INSERT INTO `dice_ante_config` (`name`, `title`, `is_default`, `mult`) +SELECT 'default', '默认底注', 1, 1 +WHERE NOT EXISTS (SELECT 1 FROM `dice_ante_config` LIMIT 1); diff --git a/server/db/dice_ante_config_menu.sql b/server/db/dice_ante_config_menu.sql new file mode 100644 index 0000000..e95ecb6 --- /dev/null +++ b/server/db/dice_ante_config_menu.sql @@ -0,0 +1,62 @@ +-- 底注配置菜单与权限 +-- 说明:默认挂载在「大富翁」目录(path=/dice)下;若不存在则自动创建目录。 + +SET @now = NOW(); + +-- 1) 找到或创建 Dice 顶级目录 +SET @dice_root_id = ( + SELECT `id` FROM `sa_system_menu` + WHERE `path` = '/dice' AND `type` = 1 + ORDER BY `id` ASC LIMIT 1 +); + +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`icon`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT 0, '大富翁', 'Dice', NULL, 1, '/dice', NULL, NULL, 'ri:gamepad-line', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE @dice_root_id IS NULL; + +SET @dice_root_id = ( + SELECT `id` FROM `sa_system_menu` + WHERE `path` = '/dice' AND `type` = 1 + ORDER BY `id` ASC LIMIT 1 +); + +-- 2) 创建底注配置菜单 +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`icon`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @dice_root_id, '底注配置', 'AnteConfig', NULL, 2, 'ante_config', '/dice/ante_config/index', NULL, 'ri:coins-line', 92, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS ( + SELECT 1 FROM `sa_system_menu` WHERE `path` = 'ante_config' AND `component` = '/dice/ante_config/index' AND `type` = 2 +); + +SET @ante_menu_id = ( + SELECT `id` FROM `sa_system_menu` + WHERE `path` = 'ante_config' AND `component` = '/dice/ante_config/index' AND `type` = 2 + ORDER BY `id` ASC LIMIT 1 +); + +-- 3) 创建按钮权限 +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @ante_menu_id, '数据列表', '', 'dice:ante_config:index:index', 3, '', '', '', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `sa_system_menu` WHERE `slug` = 'dice:ante_config:index:index' AND `type` = 3); + +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @ante_menu_id, '读取', '', 'dice:ante_config:index:read', 3, '', '', '', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `sa_system_menu` WHERE `slug` = 'dice:ante_config:index:read' AND `type` = 3); + +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @ante_menu_id, '添加', '', 'dice:ante_config:index:save', 3, '', '', '', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `sa_system_menu` WHERE `slug` = 'dice:ante_config:index:save' AND `type` = 3); + +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @ante_menu_id, '修改', '', 'dice:ante_config:index:update', 3, '', '', '', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `sa_system_menu` WHERE `slug` = 'dice:ante_config:index:update' AND `type` = 3); + +INSERT INTO `sa_system_menu` +(`parent_id`,`name`,`code`,`slug`,`type`,`path`,`component`,`method`,`sort`,`is_iframe`,`is_keep_alive`,`is_hidden`,`is_fixed_tab`,`is_full_page`,`generate_id`,`generate_key`,`status`,`create_time`,`update_time`) +SELECT @ante_menu_id, '删除', '', 'dice:ante_config:index:destroy', 3, '', '', '', 100, 2, 2, 2, 2, 2, 0, NULL, 1, @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `sa_system_menu` WHERE `slug` = 'dice:ante_config:index:destroy' AND `type` = 3); diff --git a/server/plugin/saiadmin/config/route.php b/server/plugin/saiadmin/config/route.php index 8dee7a0..2fbe077 100644 --- a/server/plugin/saiadmin/config/route.php +++ b/server/plugin/saiadmin/config/route.php @@ -118,6 +118,7 @@ Route::group('/core', function () { Route::post('/dice/reward_config/DiceRewardConfig/batchUpdate', [\app\dice\controller\reward_config\DiceRewardConfigController::class, 'batchUpdate']); Route::post('/dice/reward_config/DiceRewardConfig/createRewardReference', [\app\dice\controller\reward_config\DiceRewardConfigController::class, 'createRewardReference']); Route::post('/dice/reward_config/DiceRewardConfig/runWeightTest', [\app\dice\controller\reward_config\DiceRewardConfigController::class, 'runWeightTest']); + fastRoute('dice/ante_config/DiceAnteConfig', \app\dice\controller\ante_config\DiceAnteConfigController::class); fastRoute('dice/lottery_pool_config/DiceLotteryPoolConfig', \app\dice\controller\lottery_pool_config\DiceLotteryPoolConfigController::class); Route::get('/dice/lottery_pool_config/DiceLotteryPoolConfig/getOptions', [\app\dice\controller\lottery_pool_config\DiceLotteryPoolConfigController::class, 'getOptions']); Route::get('/dice/lottery_pool_config/DiceLotteryPoolConfig/getCurrentPool', [\app\dice\controller\lottery_pool_config\DiceLotteryPoolConfigController::class, 'getCurrentPool']);