From e61399ecd67580f009569ee5abe5bfb0a14bb13f Mon Sep 17 00:00:00 2001 From: zzm <584337238@qq.com> Date: Tue, 22 Sep 2026 14:57:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B2=B3=E5=8D=97=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9A=84=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0ui?= =?UTF-8?q?=E5=92=8C=E5=88=A0=E9=99=A4=E4=B9=8B=E5=89=8D=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E6=B8=B8=E6=88=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/updata_sql.md | 130 ++++ docs/修改记录.md | 29 + .../src/components/Setting/src/Setting.vue | 4 +- promo-ui2/src/store/modules/app.ts | 40 +- promo-ui2/src/styles/var.css | 81 ++- promo-ui2/src/views/CardMerchant/index.vue | 2 +- promo-ui2/src/views/FlowRecord/index.vue | 8 +- promo-ui2/src/views/Home/index.vue | 6 +- promo-ui2/src/views/Login/Login.vue | 146 ++--- promo-ui2/src/views/Permission/index.vue | 14 +- promo-ui2/src/views/RollRoom/index.vue | 2 +- ruoyi-ui/src/App.vue | 19 +- ruoyi-ui/src/api/game/bullet/box/api.js | 63 -- ruoyi-ui/src/api/game/bullet/dailywin/api.js | 9 - ruoyi-ui/src/api/game/bullet/ornament/api.js | 5 - ruoyi-ui/src/api/game/bullet/prize/api.js | 9 - ruoyi-ui/src/api/game/bullet/record/api.js | 13 - ruoyi-ui/src/api/game/bullet/round/api.js | 13 - ruoyi-ui/src/api/game/olympus/box/api.js | 56 -- ruoyi-ui/src/api/game/olympus/dailywin/api.js | 11 - ruoyi-ui/src/api/game/olympus/ornament/api.js | 6 - ruoyi-ui/src/api/game/olympus/prize/api.js | 11 - ruoyi-ui/src/api/game/olympus/record/api.js | 11 - .../src/api/game/olympus/rewardPool/api.js | 26 - ruoyi-ui/src/api/game/olympus/round/api.js | 6 - ruoyi-ui/src/api/game/sweet/box/api.js | 97 --- ruoyi-ui/src/api/game/sweet/dailywin/api.js | 17 - ruoyi-ui/src/api/game/sweet/ornament/api.js | 8 - ruoyi-ui/src/api/game/sweet/prize/api.js | 16 - ruoyi-ui/src/api/game/sweet/record/api.js | 9 - ruoyi-ui/src/api/game/sweet/round/api.js | 17 - ruoyi-ui/src/assets/styles/cottagecore.scss | 56 ++ ruoyi-ui/src/assets/styles/element-ui.scss | 18 +- .../src/assets/styles/element-variables.scss | 65 +- ruoyi-ui/src/assets/styles/index.scss | 64 +- ruoyi-ui/src/assets/styles/sidebar.scss | 206 ++++--- ruoyi-ui/src/assets/styles/skin.scss | 244 +++++--- ruoyi-ui/src/assets/styles/variables.scss | 55 +- ruoyi-ui/src/components/Breadcrumb/index.vue | 18 +- ruoyi-ui/src/components/FileUpload/index.vue | 4 +- .../src/components/ImagePreview/index.vue | 2 +- ruoyi-ui/src/components/ImageUpload/index.vue | 4 +- ruoyi-ui/src/components/ThemePicker/index.vue | 4 +- ruoyi-ui/src/layout/components/AppMain.vue | 8 +- ruoyi-ui/src/layout/components/Navbar.vue | 69 +-- .../src/layout/components/Settings/index.vue | 2 +- .../src/layout/components/Sidebar/Logo.vue | 18 +- .../src/layout/components/TagsView/index.vue | 111 ++-- ruoyi-ui/src/layout/index.vue | 7 +- ruoyi-ui/src/plugins/modal.js | 2 +- ruoyi-ui/src/settings.js | 3 +- ruoyi-ui/src/store/modules/settings.js | 2 +- ruoyi-ui/src/utils/request.js | 2 +- ruoyi-ui/src/views/game/bullet/box/index.vue | 281 --------- .../src/views/game/bullet/dailywin/index.vue | 61 -- .../src/views/game/bullet/ornament/index.vue | 23 - .../src/views/game/bullet/prize/index.vue | 74 --- .../src/views/game/bullet/record/index.vue | 148 ----- .../src/views/game/bullet/round/index.vue | 80 --- ruoyi-ui/src/views/game/olympus/box/index.vue | 451 -------------- .../src/views/game/olympus/dailywin/index.vue | 92 --- .../src/views/game/olympus/ornament/index.vue | 32 - .../src/views/game/olympus/prize/index.vue | 121 ---- .../src/views/game/olympus/record/index.vue | 108 ---- .../views/game/olympus/rewardPool/index.vue | 451 -------------- .../src/views/game/olympus/round/index.vue | 82 --- ruoyi-ui/src/views/game/sweet/box/index.vue | 578 ------------------ .../src/views/game/sweet/dailywin/index.vue | 80 --- .../src/views/game/sweet/ornament/index.vue | 22 - ruoyi-ui/src/views/game/sweet/prize/index.vue | 125 ---- .../src/views/game/sweet/record/index.vue | 101 --- ruoyi-ui/src/views/game/sweet/round/index.vue | 85 --- .../src/views/game/wheel/config/index.vue | 40 +- ruoyi-ui/src/views/game/wheel/prize/index.vue | 4 +- .../src/views/game/wheel/records/index.vue | 16 +- ruoyi-ui/src/views/index.vue | 248 +++++--- ruoyi-ui/src/views/monitor/operlog/index.vue | 8 +- .../src/views/skins/blankAccount/index.vue | 6 +- .../src/views/skins/blankCardKey/index.vue | 2 +- ruoyi-ui/src/views/skins/delivery/index.vue | 2 +- .../views/skins/delivery/transferApply.vue | 6 +- .../skins/delivery/transferApplyProcessed.vue | 2 +- .../src/views/skins/delivery/zbtrecord.vue | 2 +- ruoyi-ui/src/views/skins/ttBox/boxrPize.vue | 10 +- ruoyi-ui/src/views/skins/ttBox/index.vue | 4 +- .../skins/ttCardMerchantRecharge/index.vue | 21 +- .../skins/ttFight/robotFightGroupBox.vue | 2 +- .../src/views/skins/ttGenerateCard/index.vue | 2 +- .../src/views/skins/ttOrnaments/index.vue | 12 +- .../skins/ttOrnaments/websiteProperty.vue | 2 +- .../src/views/skins/ttRoll/awarddetali.vue | 2 +- ruoyi-ui/src/views/skins/ttRoll/index.vue | 10 +- ruoyi-ui/src/views/skins/ttRoll/prize.vue | 4 +- .../src/views/skins/ttRoll/prizedetail.vue | 2 +- ruoyi-ui/src/views/skins/ttUpgrade/index.vue | 2 +- .../src/views/skins/ttUpgrade/upgradeFall.vue | 2 +- .../views/skins/ttUpgrade/upgradeRecord.vue | 2 +- .../skins/ttWelfare/monthlyRecharges.vue | 2 +- .../src/views/skins/ttWelfare/welfareBox.vue | 4 +- .../views/skins/ttredPacket/lossRebate.vue | 2 +- ruoyi-ui/src/views/skins/ttuser/index.vue | 10 +- .../src/views/skins/ttuser/userTurnover.vue | 6 +- .../views/system/user/profile/userAvatar.vue | 2 +- ruoyi-ui/src/views/tool/build/RightPanel.vue | 6 +- ruoyi-ui/src/views/tool/build/index.vue | 12 +- ruoyi-ui/src/views/turnoverLottery/prize.vue | 2 +- 106 files changed, 1202 insertions(+), 4100 deletions(-) delete mode 100644 ruoyi-ui/src/api/game/bullet/box/api.js delete mode 100644 ruoyi-ui/src/api/game/bullet/dailywin/api.js delete mode 100644 ruoyi-ui/src/api/game/bullet/ornament/api.js delete mode 100644 ruoyi-ui/src/api/game/bullet/prize/api.js delete mode 100644 ruoyi-ui/src/api/game/bullet/record/api.js delete mode 100644 ruoyi-ui/src/api/game/bullet/round/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/box/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/dailywin/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/ornament/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/prize/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/record/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/rewardPool/api.js delete mode 100644 ruoyi-ui/src/api/game/olympus/round/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/box/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/dailywin/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/ornament/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/prize/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/record/api.js delete mode 100644 ruoyi-ui/src/api/game/sweet/round/api.js create mode 100644 ruoyi-ui/src/assets/styles/cottagecore.scss delete mode 100644 ruoyi-ui/src/views/game/bullet/box/index.vue delete mode 100644 ruoyi-ui/src/views/game/bullet/dailywin/index.vue delete mode 100644 ruoyi-ui/src/views/game/bullet/ornament/index.vue delete mode 100644 ruoyi-ui/src/views/game/bullet/prize/index.vue delete mode 100644 ruoyi-ui/src/views/game/bullet/record/index.vue delete mode 100644 ruoyi-ui/src/views/game/bullet/round/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/box/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/dailywin/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/ornament/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/prize/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/record/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/rewardPool/index.vue delete mode 100644 ruoyi-ui/src/views/game/olympus/round/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/box/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/dailywin/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/ornament/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/prize/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/record/index.vue delete mode 100644 ruoyi-ui/src/views/game/sweet/round/index.vue diff --git a/docs/updata_sql.md b/docs/updata_sql.md index e69de29..8edda60 100644 --- a/docs/updata_sql.md +++ b/docs/updata_sql.md @@ -0,0 +1,130 @@ +# 数据库变更台账 + +> **数据库改动只写这里**:中文标题 + 完整可执行 SQL。不再单独建 `docs/*.sql`(全量基线除外)。 +> 每条都要能回得去 —— **回滚方案与验证步骤必写**。 + +--- + +## 删除「奥林匹斯 / 荒野争锋 / 极速糖果」三个玩法的后台菜单 + +**背景**:这三个玩法不再需要,要求从后台左侧菜单移除。 + +**为什么先动数据库**:RuoYi 的左侧菜单是**数据库驱动**的(`sys_menu` → `/getRouters` 接口 → 前端 `sidebarRouters`), +代码里没有菜单清单。所以顺序是:**先删数据,再删前端页面文件**。 + +**影响面**(实查本机库 `henan`,非估算): + +| 表 | 行数 | 说明 | +|---|---|---| +| `sys_menu` | **22** | 3 个顶级菜单(`menu_type='M'`)+ 19 个子页面(`'C'`);**无** `'F'` 按钮权限行 | +| `sys_role_menu` | **22** | 全部属于 `role_id = 103` 这一个角色 | + +| 顶级 menu_id | 菜单 | path | 子菜单 | 子菜单 menu_id | 前端 component | +|---|---|---|---|---|---| +| 3130 | 奥林匹斯 | `olympus` | 7 个 | 3131~3137 | `game/olympus/*` | +| 2105 | 荒野争锋 | `bullet` | 6 个 | 2106~2110、2112 | `game/bullet/*` | +| 2125 | 极速糖果 | `sweet` | 6 个 | 2126~2131 | `game/sweet/*` | + +⚠️ **`2111`(宝箱管理→临时倍率)不在删除范围内** —— 它虽然编号紧邻 `2110`,但父级是 `2018`(宝箱管理), +且其 component 是 `game/box/mock/index`(被 `3141` 经典开箱的「临时爆率」也在用),**不要动**。 + +**变更 SQL**(2026-09-22 已在库 `henan` 执行): + +```sql +-- 1) 先清角色-菜单授权,避免留下孤儿行 +DELETE FROM sys_role_menu +WHERE menu_id IN (3130,3131,3132,3133,3134,3135,3136,3137,2105,2106,2107,2108,2109,2110,2112,2125,2126,2127,2128,2129,2130,2131); + +-- 2) 再删菜单本身 +DELETE FROM sys_menu +WHERE menu_id IN (3130,3131,3132,3133,3134,3135,3136,3137,2105,2106,2107,2108,2109,2110,2112,2125,2126,2127,2128,2129,2130,2131); +``` + +**验证**(执行后实测): + +```sql +-- 两个都必须是 0 +SELECT COUNT(*) FROM sys_menu +WHERE menu_id IN (3130,3131,3132,3133,3134,3135,3136,3137,2105,2106,2107,2108,2109,2110,2112,2125,2126,2127,2128,2129,2130,2131) + OR parent_id IN (3130, 2105, 2125); -- 实测 0 + +SELECT COUNT(*) FROM sys_role_menu +WHERE menu_id IN (3130,3131,3132,3133,3134,3135,3136,3137,2105,2106,2107,2108,2109,2110,2112,2125,2126,2127,2128,2129,2130,2131); -- 实测 0 +``` + +一级菜单复查(`SELECT menu_id, menu_name, path FROM sys_menu WHERE parent_id = 0 ORDER BY order_num, menu_id`) +实测剩余 20 项,已无「奥林匹斯 / 荒野争锋 / 极速糖果」。 + +**回滚 SQL**(22 条 `sys_menu` + 22 条 `sys_role_menu`,由 `mysqldump --no-create-info --complete-insert` 导出): + +```sql +-- 事务包裹更安全;menu_id 是显式指定,不需要自增 +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2105,'荒野争锋',0,7,'bullet',NULL,NULL,1,0,'M','0','0','','excel','admin','2026-05-14 14:36:15','admin','2026-08-01 13:37:13',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2106,'饰品列表',2105,1,'ornament','game/bullet/ornament/index',NULL,1,0,'C','0','0','game:bullet:ornament:list','button','admin','2026-05-14 14:49:48','admin','2026-05-14 14:55:16',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2107,'箱子管理',2105,2,'box','game/bullet/box/index',NULL,1,0,'C','0','0','game:bullet:box:list','bug','admin','2026-05-14 14:56:11','',NULL,''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2108,'回合管理',2105,3,'round','game/bullet/round/index',NULL,1,0,'C','0','0','game:bullet:round:list','build','admin','2026-05-14 14:56:49','',NULL,''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2109,'玩家记录',2105,4,'record','game/bullet/record/index',NULL,1,0,'C','0','0','game:bullet:record:list','button','admin','2026-05-14 14:57:29','',NULL,''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2110,'每日统计',2105,5,'dailywin','game/bullet/dailywin/index',NULL,1,0,'C','0','0','game:bullet:dailywin:list','chart','admin','2026-05-14 14:58:07','',NULL,''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2112,'奖品管理',2105,6,'prize','game/bullet/prize/index',NULL,1,0,'C','0','0','game:bullet:prize:list','component','admin','2026-05-26 04:47:02','admin','2026-05-26 05:34:40',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2125,'极速糖果',0,7,'sweet',NULL,NULL,1,0,'M','0','0','','star','admin','2026-06-18 10:15:36','admin','2026-08-01 13:29:08',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2126,'箱子管理',2125,2,' box','game/sweet/box/index',NULL,1,0,'C','0','0','game:sweet:box:list','404','admin','2026-06-18 10:17:18','admin','2026-06-18 14:34:47',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2127,'饰品列表',2125,1,'ornament','game/sweet/ornament/index',NULL,1,0,'C','0','0','game:sweet:ornament:list','bug','admin','2026-06-18 10:18:01','admin','2026-06-18 14:34:29',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2128,'奖品管理',2125,6,'prize','game/sweet/prize/index',NULL,1,0,'C','0','0','game:sweet:prize:list','build','admin','2026-06-18 10:18:41','admin','2026-06-18 14:35:55',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2129,'每日统计',2125,5,'dailywin','game/sweet/dailywin/index',NULL,1,0,'C','0','0','game:sweet:dailywin:list','button','admin','2026-06-18 10:19:39','admin','2026-06-18 14:35:39',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2130,'回合管理',2125,3,'round','game/sweet/round/index',NULL,1,0,'C','0','0','game:sweet:round:list','cascader','admin','2026-06-18 10:20:13','admin','2026-06-18 14:35:03',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2131,'玩家记录',2125,4,'record','game/sweet/record/index',NULL,1,0,'C','0','0','game:sweet:record:list','cascader','admin','2026-06-18 10:21:20','admin','2026-06-18 14:35:17',''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3130,'奥林匹斯',0,5,'olympus','',NULL,1,0,'M','0','0','','star','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯电子游戏管理'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3131,'箱子配置',3130,1,'box','game/olympus/box/index',NULL,1,0,'C','0','0','game:olympus:box','shopping','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯箱子配置与身份桶分布'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3132,'饰品列表',3130,2,'ornament','game/olympus/ornament/index',NULL,1,0,'C','0','0','game:olympus:ornament','star','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯 17 档饰品桶定义'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3133,'回合管理',3130,3,'round','game/olympus/round/index',NULL,1,0,'C','0','0','game:olympus:round','documentation','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯预生成回合查询'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3134,'奖池水位',3130,4,'rewardPool','game/olympus/rewardPool/index',NULL,1,0,'C','0','0','game:olympus:pool','money','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯按箱奖池水位(注水/抽水/批量/重置)'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3135,'玩家记录',3130,5,'record','game/olympus/record/index',NULL,1,0,'C','0','0','game:olympus:record','list','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯游戏记录'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3136,'每日统计',3130,6,'dailywin','game/olympus/dailywin/index',NULL,1,0,'C','0','0','game:olympus:win','chart','admin','2026-08-01 13:41:53','',NULL,'奥林匹斯每日盈亏统计'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3137,'奖品管理',3130,7,'prize','game/olympus/prize/index',NULL,1,0,'C','0','0','game:olympus:prize','guide','admin','2026-08-01 13:41:53','admin','2026-08-04 13:46:18','奥林匹斯返奖饰品与区间配置'); + +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2105); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2106); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2107); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2108); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2109); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2110); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2112); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2125); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2126); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2127); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2128); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2129); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2130); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,2131); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3130); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3131); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3132); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3133); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3134); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3135); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3136); +INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (103,3137); +``` + +**配套的前端文件删除**(38 个文件,全部在 git 里,`git checkout` 可恢复): + +| 目录 | 文件数 | +|---|---| +| `ruoyi-ui/src/views/game/olympus/` | 7 | +| `ruoyi-ui/src/views/game/bullet/` | 6 | +| `ruoyi-ui/src/views/game/sweet/` | 6 | +| `ruoyi-ui/src/api/game/olympus/` | 7 | +| `ruoyi-ui/src/api/game/bullet/` | 6 | +| `ruoyi-ui/src/api/game/sweet/` | 6 | + +**刻意没动**: + +- **后端 Java 代码**。`olympus / bullet / sweet / sugar` 在后端出现在**跨模块共享**的位置 —— + `TtAccountRecordSource`(流水来源码:60=奥林匹斯…)、`TtboxRecordSource`、`RedisConstants`、 + `MessageCategoryEnum`、`PromoTurnover*`、`ApiUserPackSackServiceImpl`、`WebsiteSetupServiceImpl` 等。 + 删这些会波及**其他玩法与推广/发货链路**,不在「删页面」范围内。 +- **数据库业务表**(`game_olympus_*`、`game_sweet_*` 等)原样保留,未 TRUNCATE、未 DROP。 +- `ruoyi-ui/src/views/game/sugar/`(5 个 api + 5 个页面)—— **没有任何菜单引用它**: + 菜单里的「极速糖果」指向的是 `game/sweet/*`,而 `game_sugar_*` 表在 `docs/cleanup_records.sql` 里被标注为「极速糖果」。 + 即 `sugar` 与 `sweet` 是两套并存的东西,`sugar` 未被任何菜单挂载(后端却存在 `GameSugarWin/User/StepInfo/Spin` 实体)。 + **疑似遗留或未接入的开发分支,未确认前不删。** diff --git a/docs/修改记录.md b/docs/修改记录.md index 9b0370c..0a3da1a 100644 --- a/docs/修改记录.md +++ b/docs/修改记录.md @@ -30,3 +30,32 @@ **上线前必做两件事**:① 卷是 `external: true`,**必须先 `docker volume create henan_mysql_data`**,否则报 `external volume not found` 直接起不来(`deploy.sh up -d` 会自动建,手敲 `docker-compose up` 不会);② 新卷首次初始化会建出**空**的 `henan` 库 —— `MYSQL_DATABASE` / `MYSQL_USER` / `MYSQL_PASSWORD` **只在数据卷首次初始化时生效**,原有数据需另行导入,否则应用连上的是空库。 **遗留待定**:网络没固定 `name:`,实际名会随执行目录变(在 `docker/compose` 下执行时是 `compose_henan_app_network`)。卷已用 `external` + 固定 `name` 规避「换目录丢数据」,网络是否同样钉死成 `henan_app_network` 待定。 + +- **下架三个玩法:删除「奥林匹斯 / 荒野争锋 / 极速糖果」的后台菜单与页面** + + **起因**:这三个玩法不再需要,要求从后台左侧菜单移除。 + + **关键前提**:RuoYi 的左侧菜单是**数据库驱动**的(`sys_menu` → `/getRouters` → 前端 `sidebarRouters`),**代码里没有菜单清单**,所以必须"先删数据、再删页面文件",只删前端文件的话菜单依然在。 + + **改动清单**(完整 SQL 与回滚语句见 `docs/updata_sql.md`): + + 1. **数据库**(库 `henan`,已执行):`sys_menu` 删 **22 行**(3 个顶级 M + 19 个子页面 C);`sys_role_menu` 删 **22 行**授权(全属 `role_id=103`)。**无 `'F'` 按钮权限行**。 + - 3130 奥林匹斯 `olympus` → 子菜单 3131~3137 + - 2105 荒野争锋 `bullet` → 子菜单 2106~2110、2112 + - 2125 极速糖果 `sweet` → 子菜单 2126~2131 + 2. **前端文件**(38 个,删前已确认全部被 git 跟踪):`ruoyi-ui/src/views/game/{olympus,bullet,sweet}/`(7+6+6)与 `ruoyi-ui/src/api/game/{olympus,bullet,sweet}/`(7+6+6)。 + 3. **文档**:本条 + `docs/updata_sql.md` 新条目(含 44 条回滚 INSERT)。 + + **验证**: + + - 删除后 `sys_menu` / `sys_role_menu` 命中行数**均为 0**(`printf` 实测);`SELECT ... WHERE parent_id = 0` 复查剩余 20 个一级菜单,三个玩法已消失。 + - 全量搜索 `game/olympus|game/bullet|game/sweet|api/game/...` 残留引用 **= 0**。 + - `ruoyi-ui` 生产构建 **`exitcode=0` / `DONE Build complete`**(删掉页面后仍能编译,说明没有别处静态引用它们)。 + + **刻意没动**: + + 1. **后端 Java 代码**。这些玩法名在后端出现在**跨模块共享**的文件里 —— `TtAccountRecordSource`(流水来源码 60=奥林匹斯)、`TtboxRecordSource`、`RedisConstants`、`MessageCategoryEnum`、`PromoTurnover*`、`ApiUserPackSackServiceImpl`、`WebsiteSetupServiceImpl`。删它们会波及**其他玩法与推广/发货链路**,不在「删页面」范围内。 + 2. **数据库业务表**:`game_olympus_*` / `game_sweet_*` 等原样保留,未 TRUNCATE、未 DROP。数据还在,随时可回。 + 3. **`ruoyi-ui/src/views/game/sugar/`**(5 api + 5 页面)—— **没有任何菜单引用**。菜单「极速糖果」指向的是 `game/sweet/*`,而 `docs/cleanup_records.sql` 又把 `game_sugar_*` 标注为「极速糖果」,两套并存;后端还存在 `GameSugarWin/User/StepInfo/Spin` 实体。**疑似遗留或未接入的开发分支,未确认前不删。** + + **遗留待定**:① 仪表盘「实时 RTP」卡片与「流水统计」折线里仍有 **玫瑰女郎(=olympus)** 一条 —— 那是后端 `/getRtpData` 返回的玩法列表,**与菜单无关**,删菜单不会让它消失;若要一并去掉得动后端。② `game/sugar/*` 是否清理待定。③ 是否需要把 `game_olympus_*` / `game_sweet_*` 业务表也清掉(现在只是入口没了,数据仍在库里占空间)。 diff --git a/promo-ui2/src/components/Setting/src/Setting.vue b/promo-ui2/src/components/Setting/src/Setting.vue index ecbe72d..a258916 100644 --- a/promo-ui2/src/components/Setting/src/Setting.vue +++ b/promo-ui2/src/components/Setting/src/Setting.vue @@ -177,7 +177,7 @@ const clear = () => { @@ -415,7 +415,7 @@ onMounted(() => { } .summary-card { background: #fff; - border: 1px solid #409eff; + border: 1px solid #9a5c35; border-radius: 4px; padding: 12px 24px; color: #303133; @@ -455,7 +455,7 @@ onMounted(() => { } .daily-card { background: #fff; - border: 1px solid #409eff; + border: 1px solid #9a5c35; border-radius: 6px; padding: 10px 12px; display: flex; @@ -475,7 +475,7 @@ onMounted(() => { } .weekly-total-card { background: #fff; - border: 1px solid #409eff; + border: 1px solid #9a5c35; border-radius: 6px; padding: 12px 24px; color: #303133; diff --git a/promo-ui2/src/views/Home/index.vue b/promo-ui2/src/views/Home/index.vue index 202bc5e..0860c03 100644 --- a/promo-ui2/src/views/Home/index.vue +++ b/promo-ui2/src/views/Home/index.vue @@ -372,10 +372,10 @@ onMounted(async () => { } .rate-card:hover { - background-color: #ecf5ff; - border-color: #409eff; + background-color: #fbf5ea; + border-color: #9a5c35; transform: translateY(-2px); - box-shadow: 0 2px 12px rgba(64, 158, 255, 0.1); + box-shadow: 0 2px 12px rgba(154, 92, 53, 0.10); } .rate-card-title { diff --git a/promo-ui2/src/views/Login/Login.vue b/promo-ui2/src/views/Login/Login.vue index 0e11729..3e92f1a 100644 --- a/promo-ui2/src/views/Login/Login.vue +++ b/promo-ui2/src/views/Login/Login.vue @@ -53,16 +53,20 @@ const inviteCode = computed(() => { z-index: 0; overflow: hidden; - background: radial-gradient(circle at 72% 18%, rgba(92, 86, 176, 0.15), transparent 30%), - linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%); + /* 原为 #0f0c29 → #302b63 → #24243e 的紫蓝渐变(规范明令禁止), + 改成亚麻→奶油暖渐变 + 雏菊黄/草绿柔光斑 */ + background: radial-gradient(circle at 72% 18%, rgba(245, 215, 95, 0.24), transparent 34%), + radial-gradient(circle at 12% 88%, rgba(90, 143, 90, 0.14), transparent 36%), + linear-gradient(135deg, #fdfaf5 0%, #f7f0e4 52%, #f3ece0 100%); } .grid-overlay { position: absolute; inset: 0; - background-image: linear-gradient(rgba(255, 255, 255, 0.028) 1px, transparent 1px), - linear-gradient(90deg, rgba(255, 255, 255, 0.028) 1px, transparent 1px); + /* 亚麻织纹:暖棕细线,不再是白色科技网格 */ + background-image: linear-gradient(rgba(139, 115, 85, 0.055) 1px, transparent 1px), + linear-gradient(90deg, rgba(139, 115, 85, 0.055) 1px, transparent 1px); background-size: 50px 50px; } @@ -89,23 +93,21 @@ const inviteCode = computed(() => { ② 受光放在右上角,与背景光斑方向一致 ③ 投影反方向往左下,棱线只亮右上 */ - background-color: rgba(126, 132, 240, 0.24); + /* 原来是半透明靛蓝玻璃卡 + backdrop-filter; + Cottagecore 不把玻璃态当默认风格,改成不透明奶油卡 + 花粉细边 + 暖棕柔影 */ + background-color: #fffdfa; background-image: radial-gradient( 130% 110% at 100% 0%, - rgba(152, 158, 255, 0.22), + rgba(245, 215, 95, 0.20), transparent 62% ); - border: 1px solid rgba(255, 255, 255, 0.12); + border: 1px solid rgba(212, 160, 160, 0.45); box-shadow: - -20px 24px 56px -20px rgba(5, 4, 24, 0.68), - inset -1px 1px 0 rgba(255, 255, 255, 0.2), - inset 1px -1px 0 rgba(255, 255, 255, 0.02); - - backdrop-filter: blur(24px) saturate(150%); - -webkit-backdrop-filter: blur(24px) saturate(150%); + 0 18px 48px -18px rgba(139, 115, 85, 0.34), + inset 0 1px 0 rgba(255, 255, 255, 0.9); /* ========================= 标题 @@ -124,10 +126,11 @@ const inviteCode = computed(() => { h2 { margin: 0 16px; + font-family: 'Songti SC', 'Source Han Serif SC', 'Noto Serif SC', STSong, SimSun, Georgia, serif; font-size: 24px; font-weight: 650; - color: #f7f8ff; + color: #4f4130; } .title-decoration { @@ -136,10 +139,10 @@ const inviteCode = computed(() => { border-radius: 2px; - background: linear-gradient(90deg, transparent, rgba(184, 194, 232, 0.55)); + background: linear-gradient(90deg, transparent, rgba(192, 138, 138, 0.8)); &:last-child { - background: linear-gradient(90deg, rgba(184, 194, 232, 0.55), transparent); + background: linear-gradient(90deg, rgba(192, 138, 138, 0.8), transparent); } } } @@ -152,13 +155,13 @@ const inviteCode = computed(() => { } :deep(.el-form-item__label) { - color: rgba(255, 255, 255, 0.72); + color: #5f4f3d; font-size: 13px; } /* ========================= 输入框 - 玻璃上的凹槽:比卡片暗,形成内嵌感 + 奶油底上的凹槽:比卡片略深,形成内嵌感 不再改内部 Row / Col 结构 ========================= */ :deep(.el-input__wrapper) { @@ -168,11 +171,11 @@ const inviteCode = computed(() => { border-radius: 12px; - background: rgba(10, 8, 34, 0.34); + background: #faf6f0; - border: 1px solid rgba(255, 255, 255, 0.1); + border: 1px solid rgba(212, 160, 160, 0.45); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.22); + box-shadow: inset 0 1px 2px rgba(139, 115, 85, 0.08); transition: border-color 0.22s ease, @@ -180,34 +183,34 @@ const inviteCode = computed(() => { box-shadow 0.22s ease; &:hover { - border-color: rgba(255, 255, 255, 0.2); - background: rgba(10, 8, 34, 0.26); + border-color: #c08a8a; + background: #fdfaf5; } &.is-focus { - border-color: rgba(150, 158, 255, 0.62); - background: rgba(10, 8, 34, 0.22); + border-color: rgba(154, 92, 53, 0.55); + background: #fffdfa; box-shadow: - inset 0 1px 2px rgba(0, 0, 0, 0.22), - 0 0 0 3px rgba(120, 128, 255, 0.16); + inset 0 1px 2px rgba(139, 115, 85, 0.08), + 0 0 0 3px rgba(154, 92, 53, 0.14); } } :deep(.el-input__inner) { height: 46px; - color: #fff; + color: #4f4130; font-size: 14px; &::placeholder { - color: rgba(255, 255, 255, 0.4); + color: #9a886e; } } :deep(.el-input__prefix), :deep(.el-input__suffix) { - color: rgba(255, 255, 255, 0.55); + color: #7a664e; } /* ========================= @@ -232,16 +235,16 @@ const inviteCode = computed(() => { border-radius: 12px; - border: 1px solid rgba(133, 150, 255, 0.38); + border: 1px solid rgba(212, 160, 160, 0.6); - background: linear-gradient(135deg, rgba(112, 131, 255, 0.28), rgba(121, 91, 200, 0.24)); + background: rgba(245, 215, 95, 0.22); - color: #e3e7ff; + color: #9a5c35; font-size: 13px; font-weight: 600; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); + box-shadow: none; transition: background 0.2s ease, @@ -250,24 +253,24 @@ const inviteCode = computed(() => { transform 0.2s ease; &:hover { - color: #fff; + color: #7d4a2a; - border-color: rgba(151, 164, 255, 0.62); + border-color: #c08a8a; - background: linear-gradient(135deg, rgba(112, 131, 255, 0.4), rgba(121, 91, 200, 0.34)); + background: rgba(245, 215, 95, 0.34); } &:active { - transform: scale(0.98); + transform: scale(0.97); } &.is-disabled, &:disabled { - color: rgba(255, 255, 255, 0.34); + color: #9a886e; - border-color: rgba(255, 255, 255, 0.1); + border-color: #eadfd0; - background: rgba(255, 255, 255, 0.05); + background: #f6efe3; } } @@ -282,11 +285,11 @@ const inviteCode = computed(() => { border-radius: 12px; - border: 1px solid rgba(133, 150, 255, 0.38); + border: 1px solid rgba(212, 160, 160, 0.6); - background: linear-gradient(135deg, rgba(112, 131, 255, 0.28), rgba(121, 91, 200, 0.24)); + background: rgba(245, 215, 95, 0.22); - color: #e3e7ff; + color: #9a5c35; font-size: 13px; font-weight: 600; @@ -321,19 +324,21 @@ const inviteCode = computed(() => { color: #fff; - background: linear-gradient(100deg, #667eea 0%, #7075dc 48%, #875bbb 100%); + /* 原为 #667eea → #7075dc → #875bbb 的紫蓝渐变(规范明令禁止),改陶土; + 渐变两端白字对比度 5.31:1 / 7.28:1,均过 AA */ + background: linear-gradient(100deg, #9a5c35 0%, #8a5230 48%, #7d4a2a 100%); - box-shadow: 0 7px 20px rgba(91, 98, 220, 0.27); + box-shadow: 0 7px 20px rgba(154, 92, 53, 0.24); &:hover { - transform: translateY(-1px); - filter: brightness(1.06); + /* 去掉原来的 filter: brightness(硬闪),改规范要求的微风感:轻微旋转 + 小幅放大 */ + transform: rotate(-0.6deg) scale(1.02); - box-shadow: 0 10px 24px rgba(91, 98, 220, 0.36); + box-shadow: 0 10px 24px rgba(154, 92, 53, 0.32); } &:active { - transform: translateY(0); + transform: scale(0.98); } } } @@ -344,44 +349,45 @@ const inviteCode = computed(() => { :deep(.el-select__wrapper) { min-height: 48px; - background: rgba(255, 255, 255, 0.08); + background: #faf6f0; - border: 1px solid rgba(255, 255, 255, 0.15); + border: 1px solid rgba(212, 160, 160, 0.45); border-radius: 12px; box-shadow: none; - color: #fff; + color: #4f4130; } :deep(.el-select__placeholder) { - color: rgba(255, 255, 255, 0.7); + color: #9a886e; } :deep(.el-checkbox__label) { - color: rgba(255, 255, 255, 0.72); + color: #5f4f3d; } :deep(.el-checkbox__inner) { - background: rgba(255, 255, 255, 0.08); + background: #faf6f0; - border-color: rgba(255, 255, 255, 0.3); + border-color: #d8c3b0; } :deep(.el-checkbox__input.is-checked .el-checkbox__inner) { - background: #667eea; - border-color: #667eea; + background: #9a5c35; + border-color: #9a5c35; } - /* 密码强度条 */ + /* 密码强度条:弱→强 用 莓红 → 雏菊金 → 草绿 → 深草绿,色相递进而不是明度递进, + 保证色盲用户也能分辨(不靠单一颜色维度传递状态) */ :deep(.@{adminNamespace}-input-password__bar) { height: 4px; margin-top: 8px; margin-bottom: 0; - background-color: rgba(255, 255, 255, 0.12); + background-color: #eadfd0; border-radius: 999px; @@ -398,19 +404,19 @@ const inviteCode = computed(() => { &[data-score='0'], &[data-score='1'] { - background-color: #ff6b81; + background-color: #a4485a; } &[data-score='2'] { - background-color: #ffc069; + background-color: #8f6418; } &[data-score='3'] { - background-color: #7c8cff; + background-color: #457450; } &[data-score='4'] { - background: linear-gradient(90deg, #667eea, #4facfe); + background: linear-gradient(90deg, #457450, #3f6b45); } } @@ -419,14 +425,14 @@ const inviteCode = computed(() => { background: transparent; - border: 1px solid rgba(255, 255, 255, 0.24); + border: 1px solid #d8c3b0; - color: rgba(255, 255, 255, 0.82); + color: #5f4f3d; &:hover { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.42); - color: #fff; + background: #f6efe3; + border-color: #c08a8a; + color: #9a5c35; } } diff --git a/promo-ui2/src/views/Permission/index.vue b/promo-ui2/src/views/Permission/index.vue index 32c1617..4ccdc6c 100644 --- a/promo-ui2/src/views/Permission/index.vue +++ b/promo-ui2/src/views/Permission/index.vue @@ -275,14 +275,14 @@ const handleClearAll = () => { } .role-card:hover { - border-color: #b3d8ff; - box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1); + border-color: #c08a8a; + box-shadow: 0 2px 8px rgba(154, 92, 53, 0.10); } .role-card.active { - border-color: #409eff; - background: linear-gradient(135deg, #ecf5ff 0%, #f0f9ff 100%); - box-shadow: 0 2px 12px rgba(64, 158, 255, 0.15); + border-color: #9a5c35; + background: linear-gradient(135deg, #fbf5ea 0%, #f6efe3 100%); + box-shadow: 0 2px 12px rgba(154, 92, 53, 0.14); } .role-icon { @@ -344,8 +344,8 @@ const handleClearAll = () => { } .menu-item:hover { - border-color: #c6e2ff; - box-shadow: 0 1px 4px rgba(64, 158, 255, 0.08); + border-color: #d8c3b0; + box-shadow: 0 1px 4px rgba(154, 92, 53, 0.08); } .drag-handle { diff --git a/promo-ui2/src/views/RollRoom/index.vue b/promo-ui2/src/views/RollRoom/index.vue index afd4298..3542ca0 100644 --- a/promo-ui2/src/views/RollRoom/index.vue +++ b/promo-ui2/src/views/RollRoom/index.vue @@ -890,7 +890,7 @@ const handleSaveTemplate = async () => { .ornament-grid { display: flex; flex-wrap: wrap; gap: 10px; max-height: 240px; overflow-y: auto; padding: 4px; } .ornament-card { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border: 1px solid #e4e7ed; border-radius: 6px; cursor: pointer; transition: all 0.2s; width: 250px; } -.ornament-card:hover { border-color: #409eff; background: #f0f9ff; } +.ornament-card:hover { border-color: #9a5c35; background: #fbf5ea; } .ornament-img { width: 50px; height: 38px; object-fit: cover; border-radius: 4px; flex-shrink: 0; background: #f5f5f5; } .ornament-info { flex: 1; min-width: 0; } .ornament-name { font-size: 12px; line-height: 1.3; word-break: break-all; } diff --git a/ruoyi-ui/src/App.vue b/ruoyi-ui/src/App.vue index f392ff0..57f6ba0 100644 --- a/ruoyi-ui/src/App.vue +++ b/ruoyi-ui/src/App.vue @@ -1,16 +1,22 @@ - diff --git a/ruoyi-ui/src/api/game/bullet/box/api.js b/ruoyi-ui/src/api/game/bullet/box/api.js deleted file mode 100644 index 468bf9e..0000000 --- a/ruoyi-ui/src/api/game/bullet/box/api.js +++ /dev/null @@ -1,63 +0,0 @@ -import request from '@/utils/request' - -// 箱子列表 (支持分页+筛选) -export function boxList(params) { - return request({ - url: '/admin/bullet/box/list', - method: 'get', - params - }) -} - -// 新增/编辑箱子 -export function boxSave(data) { - return request({ - url: '/admin/bullet/box/save', - method: 'post', - data: data - }) -} - -// 删除箱子 -export function boxDelete(boxId) { - return request({ - url: '/admin/bullet/box/delete', - method: 'post', - params: { boxId } - }) -} - -// 查看箱子饰品配置 -export function boxOrnaments(boxId) { - return request({ - url: '/admin/bullet/box/ornaments', - method: 'get', - params: { boxId } - }) -} - -// 一键重算全部箱子饰品分布 -export function recalcAll() { - return request({ url: '/admin/bullet/box/recalc_all', method: 'post' }) -} - -// 新增/编辑饰品数量 (upsert) -export function saveOrnaments(boxId, data) { - return request({ - url: '/admin/bullet/box/ornaments/save', - method: 'post', - params: { boxId }, - data: data - }) -} - -// 版本管理 -export function getBoxVersions(boxId) { - return request({ url: '/admin/bullet/box/versions', method: 'get', params: { boxId } }) -} -export function publishVersion(boxId, version) { - return request({ url: '/admin/bullet/box/publish', method: 'post', params: { boxId, version } }) -} -export function rollbackVersion(boxId, version) { - return request({ url: '/admin/bullet/box/rollback', method: 'post', params: { boxId, version } }) -} diff --git a/ruoyi-ui/src/api/game/bullet/dailywin/api.js b/ruoyi-ui/src/api/game/bullet/dailywin/api.js deleted file mode 100644 index 12c6625..0000000 --- a/ruoyi-ui/src/api/game/bullet/dailywin/api.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request' - -export function winStats(params) { - return request({ url: '/admin/bullet/winstats', method: 'get', params }) -} - -export function rewardPoolReset() { - return request({ url: '/admin/bullet/rewardpool/reset', method: 'post' }) -} diff --git a/ruoyi-ui/src/api/game/bullet/ornament/api.js b/ruoyi-ui/src/api/game/bullet/ornament/api.js deleted file mode 100644 index 678eab4..0000000 --- a/ruoyi-ui/src/api/game/bullet/ornament/api.js +++ /dev/null @@ -1,5 +0,0 @@ -import request from '@/utils/request' - -export function ornamentList() { - return request({ url: '/admin/bullet/ornament/list', method: 'get' }) -} diff --git a/ruoyi-ui/src/api/game/bullet/prize/api.js b/ruoyi-ui/src/api/game/bullet/prize/api.js deleted file mode 100644 index 00b1e41..0000000 --- a/ruoyi-ui/src/api/game/bullet/prize/api.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request' - -export function prizeList() { - return request({ url: '/admin/bullet/prize/list', method: 'get' }) -} - -export function prizeSave(data) { - return request({ url: '/admin/bullet/prize/save', method: 'post', data }) -} diff --git a/ruoyi-ui/src/api/game/bullet/record/api.js b/ruoyi-ui/src/api/game/bullet/record/api.js deleted file mode 100644 index 6b90630..0000000 --- a/ruoyi-ui/src/api/game/bullet/record/api.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from '@/utils/request' - -export function recordList(params) { - return request({ url: '/admin/bullet/records', method: 'get', params }) -} - -export function deleteRecord(recordId) { - return request({ url: '/admin/bullet/records/delete', method: 'post', params: { recordId } }) -} - -export function clearRecords() { - return request({ url: '/admin/bullet/records/clear', method: 'post' }) -} diff --git a/ruoyi-ui/src/api/game/bullet/round/api.js b/ruoyi-ui/src/api/game/bullet/round/api.js deleted file mode 100644 index beb32da..0000000 --- a/ruoyi-ui/src/api/game/bullet/round/api.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from '@/utils/request' - -export function roundList(params) { - return request({ url: '/admin/bullet/round/list', method: 'get', params }) -} - -export function roundByOrnament(params) { - return request({ url: '/admin/bullet/round/byOrnament', method: 'get', params }) -} - -export function roundDelete(roundId) { - return request({ url: '/admin/bullet/round/delete', method: 'post', params: { roundId } }) -} diff --git a/ruoyi-ui/src/api/game/olympus/box/api.js b/ruoyi-ui/src/api/game/olympus/box/api.js deleted file mode 100644 index 430349d..0000000 --- a/ruoyi-ui/src/api/game/olympus/box/api.js +++ /dev/null @@ -1,56 +0,0 @@ -import request from '@/utils/request' - -// 箱子列表(分页 + 按模式筛选) -export function getBoxList(params) { - return request({ url: '/admin/olympus/box/list', method: 'get', params }) -} - -// 新增/编辑箱子 -export function saveBox(data) { - return request({ url: '/admin/olympus/box/save', method: 'post', data }) -} - -// 某箱某身份的饰品桶分布(含 convergeCount / fixedRounds / convergeRounds) -export function getBoxOrnaments(boxId, audience) { - return request({ url: `/admin/olympus/box/ornaments/${boxId}`, method: 'get', params: { audience }}) -} - -// 保存某箱某身份饰品回合分布 -export function saveBoxOrnaments(data) { - return request({ url: '/admin/olympus/box/ornaments/save', method: 'post', data }) -} - -// 按 RTP 重算某箱某身份分布 -export function calcDistribution(data) { - return request({ url: '/admin/olympus/box/ornaments/calc', method: 'post', data }) -} - -// 模拟 payoutCap 约束下的预估实际 RTP -export function simulateRtp(data) { - return request({ url: '/admin/olympus/box/ornaments/simulate-rtp', method: 'post', data }) -} - -// ==================== 分布模板(按身份) ==================== - -export function getBoxTemplates(boxId, audience) { - return request({ url: `/admin/olympus/box/templates/${boxId}`, method: 'get', params: { audience }}) -} -export function saveBoxTemplate(data) { - return request({ url: '/admin/olympus/box/template/save', method: 'post', data }) -} -export function deleteBoxTemplate(id) { - return request({ url: `/admin/olympus/box/template/${id}`, method: 'delete' }) -} -export function applyBoxTemplate(data) { - return request({ url: '/admin/olympus/box/template/apply', method: 'post', data }) -} - -// 一键重算所有箱子 × 所有身份(按各箱现有配置) -export function recalcAll() { - return request({ url: '/admin/olympus/box/recalc_all', method: 'post' }) -} - -// 重算分布:按参数批量重算(boxType 可选=全部模式;audience 可选=全部身份;rtp/totalRounds/convergeRatio 必传统一设置) -export function recalcBatch(data) { - return request({ url: '/admin/olympus/box/recalcBatch', method: 'post', data }) -} diff --git a/ruoyi-ui/src/api/game/olympus/dailywin/api.js b/ruoyi-ui/src/api/game/olympus/dailywin/api.js deleted file mode 100644 index e3ba04f..0000000 --- a/ruoyi-ui/src/api/game/olympus/dailywin/api.js +++ /dev/null @@ -1,11 +0,0 @@ -import request from '@/utils/request' - -// 每日统计列表(分页) -export function getWinList(params) { - return request({ url: '/admin/olympus/win/list', method: 'get', params }) -} - -// 汇总(按日期区间) -export function getWinSummary(params) { - return request({ url: '/admin/olympus/win/summary', method: 'get', params }) -} diff --git a/ruoyi-ui/src/api/game/olympus/ornament/api.js b/ruoyi-ui/src/api/game/olympus/ornament/api.js deleted file mode 100644 index cfd2379..0000000 --- a/ruoyi-ui/src/api/game/olympus/ornament/api.js +++ /dev/null @@ -1,6 +0,0 @@ -import request from '@/utils/request' - -// 饰品桶定义列表(17 桶) -export function getOrnamentList() { - return request({ url: '/admin/olympus/ornament/list', method: 'get' }) -} diff --git a/ruoyi-ui/src/api/game/olympus/prize/api.js b/ruoyi-ui/src/api/game/olympus/prize/api.js deleted file mode 100644 index d38b1cf..0000000 --- a/ruoyi-ui/src/api/game/olympus/prize/api.js +++ /dev/null @@ -1,11 +0,0 @@ -import request from '@/utils/request' - -// 返奖饰品列表(含返奖区间) -export function prizeList() { - return request({ url: '/admin/olympus/prize/list', method: 'get' }) -} - -// 新增/编辑返奖饰品(含区间) -export function prizeSave(data) { - return request({ url: '/admin/olympus/prize/save', method: 'post', data }) -} diff --git a/ruoyi-ui/src/api/game/olympus/record/api.js b/ruoyi-ui/src/api/game/olympus/record/api.js deleted file mode 100644 index 49268e9..0000000 --- a/ruoyi-ui/src/api/game/olympus/record/api.js +++ /dev/null @@ -1,11 +0,0 @@ -import request from '@/utils/request' - -// 游戏记录列表(分页 + 按玩家ID/身份筛选;identity=common/anchor/robot/white,空=全部身份) -export function getRecordList(params) { - return request({ url: '/admin/olympus/record/list', method: 'get', params }) -} - -// 返奖汇总(按日期区间) -export function getWinSummary(params) { - return request({ url: '/admin/olympus/win/summary', method: 'get', params }) -} diff --git a/ruoyi-ui/src/api/game/olympus/rewardPool/api.js b/ruoyi-ui/src/api/game/olympus/rewardPool/api.js deleted file mode 100644 index 15e4143..0000000 --- a/ruoyi-ui/src/api/game/olympus/rewardPool/api.js +++ /dev/null @@ -1,26 +0,0 @@ -import request from '@/utils/request' - -// 奖池配置快照(总池 + 各箱子池),按身份 audience=common/anchor/robot/white -export function getPoolConfig(params) { - return request({ url: '/admin/olympus/rewardPool/config', method: 'get', params }) -} - -// 逐箱注水/抽水(type=1 注水 / 2 抽水,含 audience、remark) -export function adjustPool(data) { - return request({ url: '/admin/olympus/rewardPool/adjust', method: 'post', data }) -} - -// 批量按一轮花费比例注水/抽水:{ audience, type, ratio, remark },每箱金额=一轮总花费(底注×模式倍数×总回合数)×ratio% -export function adjustPoolBatch(data) { - return request({ url: '/admin/olympus/rewardPool/adjustBatch', method: 'post', data }) -} - -// 重置人工调整:该身份所有箱子注水/抽水累计归零,只保留真实水位(下注−返奖):{ audience, remark } -export function adjustPoolReset(data) { - return request({ url: '/admin/olympus/rewardPool/adjustReset', method: 'post', data }) -} - -// 奖池调整历史(分页,params 含 audience) -export function getPoolLogs(params) { - return request({ url: '/admin/olympus/rewardPool/adjustLog', method: 'get', params }) -} diff --git a/ruoyi-ui/src/api/game/olympus/round/api.js b/ruoyi-ui/src/api/game/olympus/round/api.js deleted file mode 100644 index 2337472..0000000 --- a/ruoyi-ui/src/api/game/olympus/round/api.js +++ /dev/null @@ -1,6 +0,0 @@ -import request from '@/utils/request' - -// 预生成回合列表(分页 + 按回合ID/模式筛选) -export function getRoundList(params) { - return request({ url: '/admin/olympus/round/list', method: 'get', params }) -} diff --git a/ruoyi-ui/src/api/game/sweet/box/api.js b/ruoyi-ui/src/api/game/sweet/box/api.js deleted file mode 100644 index dc71336..0000000 --- a/ruoyi-ui/src/api/game/sweet/box/api.js +++ /dev/null @@ -1,97 +0,0 @@ -import request from '@/utils/request' - -export function getBoxList(params) { - return request({ - url: '/admin/sweet/box/list', - method: 'get', - params - }) -} - -export function saveBox(data) { - return request({ - url: '/admin/sweet/box/save', - method: 'post', - data - }) -} - -export function getBoxOrnaments(boxId) { - return request({ - url: `/admin/sweet/box/ornaments/${boxId}`, - method: 'get' - }) -} - -export function saveBoxOrnaments(data) { - return request({ - url: '/admin/sweet/box/ornaments/save', - method: 'post', - data - }) -} - -export function calcDistribution(data) { - return request({ - url: '/admin/sweet/box/ornaments/calc', - method: 'post', - data - }) -} - -// 模拟 payoutCap 约束下的预估实际 RTP -export function simulateRtp(data) { - return request({ - url: '/admin/sweet/box/ornaments/simulate-rtp', - method: 'post', - data - }) -} - -// ==================== 箱子饰品分布模板(后端持久化) ==================== - -// 查询某箱子的模板列表 -export function getBoxTemplates(boxId) { - return request({ - url: `/admin/sweet/box/templates/${boxId}`, - method: 'get' - }) -} - -// 保存当前分布为模板 -export function saveBoxTemplate(data) { - return request({ - url: '/admin/sweet/box/template/save', - method: 'post', - data - }) -} - -// 删除模板 -export function deleteBoxTemplate(id) { - return request({ - url: `/admin/sweet/box/template/${id}`, - method: 'delete' - }) -} - -// 应用模板(写入分布 + 标记为生效模板) -export function applyBoxTemplate(data) { - return request({ - url: '/admin/sweet/box/template/apply', - method: 'post', - data - }) -} - -// ==================== 奖池水位 ==================== - -export function getPoolStatus() { - return request({ url: '/admin/sweet/pool/status', method: 'get' }) -} -export function addPoolBet(data) { - return request({ url: '/admin/sweet/pool/addBet', method: 'post', data }) -} -export function addPoolWin(data) { - return request({ url: '/admin/sweet/pool/addWin', method: 'post', data }) -} diff --git a/ruoyi-ui/src/api/game/sweet/dailywin/api.js b/ruoyi-ui/src/api/game/sweet/dailywin/api.js deleted file mode 100644 index 733b711..0000000 --- a/ruoyi-ui/src/api/game/sweet/dailywin/api.js +++ /dev/null @@ -1,17 +0,0 @@ -import request from '@/utils/request' - -export function getWinList(params) { - return request({ - url: '/admin/sweet/win/list', - method: 'get', - params - }) -} - -export function getWinSummary(params) { - return request({ - url: '/admin/sweet/win/summary', - method: 'get', - params - }) -} diff --git a/ruoyi-ui/src/api/game/sweet/ornament/api.js b/ruoyi-ui/src/api/game/sweet/ornament/api.js deleted file mode 100644 index 2188984..0000000 --- a/ruoyi-ui/src/api/game/sweet/ornament/api.js +++ /dev/null @@ -1,8 +0,0 @@ -import request from '@/utils/request' - -export function getOrnamentList() { - return request({ - url: '/admin/sweet/ornament/list', - method: 'get' - }) -} diff --git a/ruoyi-ui/src/api/game/sweet/prize/api.js b/ruoyi-ui/src/api/game/sweet/prize/api.js deleted file mode 100644 index f28b8e2..0000000 --- a/ruoyi-ui/src/api/game/sweet/prize/api.js +++ /dev/null @@ -1,16 +0,0 @@ -import request from '@/utils/request' - -export function prizeList() { - return request({ - url: '/admin/sweet/prize/list', - method: 'get' - }) -} - -export function prizeSave(data) { - return request({ - url: '/admin/sweet/prize/save', - method: 'post', - data - }) -} diff --git a/ruoyi-ui/src/api/game/sweet/record/api.js b/ruoyi-ui/src/api/game/sweet/record/api.js deleted file mode 100644 index 188a22f..0000000 --- a/ruoyi-ui/src/api/game/sweet/record/api.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request' - -export function getRecordList(params) { - return request({ - url: '/admin/sweet/record/list', - method: 'get', - params - }) -} diff --git a/ruoyi-ui/src/api/game/sweet/round/api.js b/ruoyi-ui/src/api/game/sweet/round/api.js deleted file mode 100644 index 059261b..0000000 --- a/ruoyi-ui/src/api/game/sweet/round/api.js +++ /dev/null @@ -1,17 +0,0 @@ -import request from '@/utils/request' - -export function getRoundList(params) { - return request({ - url: '/admin/sweet/round/list', - method: 'get', - params - }) -} - -export function roundDelete(ids) { - return request({ - url: '/admin/sweet/round/delete', - method: 'delete', - data: ids - }) -} diff --git a/ruoyi-ui/src/assets/styles/cottagecore.scss b/ruoyi-ui/src/assets/styles/cottagecore.scss new file mode 100644 index 0000000..6faeab0 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/cottagecore.scss @@ -0,0 +1,56 @@ +/* ========================================================================== + Cottagecore(田园核风)色板 —— 全站唯一色源 + 改色只改这里;skin.scss / sidebar.scss / variables.scss / element-variables.scss + 全部引用本文件的变量,不再各自写死十六进制。 + + ★ 无障碍(已按 WCAG 2.1 AA 实算,承载文字的组合均 ≥ 4.5:1) + - 规范原值 #8b7355 作正文只有 4.17:1 ⇒ 正文用 $cc-ink-2 + - 规范原值 #5a8f5a 作浅底文字只有 3.56:1、白字只有 3.81:1 + ⇒ 它只做装饰与大面积色块,绿色文字一律用 $cc-grass-text + ========================================================================== */ + +/* ---- 底色 ---- */ +$cc-cream: #faf6f0; // 卡片底(规范「背景主色」) +$cc-cream-hi: #fffdfa; // 卡片悬停/更亮 +$cc-linen: #f3ece0; // 页面底(比卡片深一档,卡片才浮得起来) +$cc-linen-2: #ece2d3; // 表头 / 浅槽 / 斑马纹 + +/* ---- 绿:草绿只做装饰,绿色文字用深值 ---- */ +$cc-grass: #5a8f5a; // 装饰、大色块 +$cc-grass-deep: #457450; // 绿底填充(白字 5.43:1) +$cc-grass-text: #3f6b45; // 浅底上的绿色文字(5.73:1) + +/* ---- 雏菊黄 ---- */ +$cc-daisy: #f5d75f; // 强调块 / 区块底(不承载小字) +$cc-daisy-deep: #8f6418; // 深雏菊金 · 警告(白字 5.24:1) + +/* ---- 大地色 ---- */ +$cc-earth: #8b7355; // 土棕 · 仅大号字与装饰 +$cc-terra: #9a5c35; // 陶土棕 · 主色 primary(白字 5.31:1) +$cc-rose: #a4485a; // 莓红 · 危险(白字 5.75:1) +$cc-ash: #6b6152; // 暖褐灰 · 信息(白字 6.08:1) +$cc-blossom: #d4a0a0; // 花粉 · 描边 / 徽章 +$cc-blossom-deep: #c08a8a; // 花粉加深 · 悬停描边 + +/* ---- 墨色(文字)---- */ +$cc-ink: #4f4130; // 主文字(奶油底 9.16:1) +$cc-ink-2: #5f4f3d; // 正文(6.37:1) +$cc-ink-3: #7a664e; // 次级 / 弱化(5.08:1) +$cc-ink-4: #8b755a; // 占位符 / 禁用(原 #9a886e 太淡,看不出还有内容) + +/* ---- 线 ---- */ +$cc-line: rgba(212, 160, 160, 0.55); // 花粉细边(原 .42 的卡片描边几乎看不见) +$cc-line-2: rgba(139, 115, 85, 0.20); // 暖棕分隔线 + +/* ---- 柔影:暖棕扩散,不用灰黑硬影 ---- */ +$cc-shadow-sm: 0 2px 8px rgba(139, 115, 85, 0.10); +$cc-shadow-md: 0 6px 18px rgba(139, 115, 85, 0.13); +$cc-shadow-lg: 0 12px 32px rgba(139, 115, 85, 0.17); + +/* ---- 字体 ---- + Cottagecore 要求衬线,但后台是拿表格干活的:13px 宋体在密集表格里可读性明显下降。 + 因此只在「标题类」(≥ 16px 的页面标题 / 弹窗标题)用衬线, + 正文、表单、表格一律保持系统无衬线,数字用 tabular-nums 保证列对齐(不是等宽字体)。 */ +$cc-serif: 'Songti SC', 'Source Han Serif SC', 'Noto Serif SC', STSong, SimSun, Georgia, 'Times New Roman', serif; +$cc-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + diff --git a/ruoyi-ui/src/assets/styles/element-ui.scss b/ruoyi-ui/src/assets/styles/element-ui.scss index d25704d..ee91ebf 100644 --- a/ruoyi-ui/src/assets/styles/element-ui.scss +++ b/ruoyi-ui/src/assets/styles/element-ui.scss @@ -52,13 +52,15 @@ left: 0; position: relative; margin: 0 auto; - border-radius: 12px; + border-radius: 18px; + border: 1px solid $cc-line; + box-shadow: $cc-shadow-lg; overflow: hidden; } -// 优化遮罩层 +// 优化遮罩层:暖棕调,不再是纯黑 .v-modal { - background: rgba(0, 0, 0, 0.4) !important; + background: rgba(79, 65, 48, 0.42) !important; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } @@ -73,25 +75,25 @@ // 对话框头部 .el-dialog__header { padding: 20px 24px 16px; - border-bottom: 1px solid rgba(115, 133, 166, 0.12); + border-bottom: 1px solid $cc-line-2; } .el-dialog__title { font-size: 18px; font-weight: 600; - color: #263654; + color: $cc-ink; } // 对话框内容 .el-dialog__body { padding: 24px; - color: #5a6478; + color: $cc-ink-2; } // 对话框底部 .el-dialog__footer { padding: 16px 24px; - border-top: 1px solid rgba(115, 133, 166, 0.12); + border-top: 1px solid $cc-line-2; } // refine element ui upload @@ -129,4 +131,4 @@ > .el-submenu__title .el-submenu__icon-arrow { display: none; -} \ No newline at end of file +} diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss index 1615ff2..ab9fd60 100644 --- a/ruoyi-ui/src/assets/styles/element-variables.scss +++ b/ruoyi-ui/src/assets/styles/element-variables.scss @@ -1,23 +1,62 @@ /** -* I think element-ui's default theme color is too light for long-term use. -* So I modified the default color and you can modify it to your liking. -**/ + * Element UI 主题变量(Cottagecore / 田园核风) + * + * 这里覆盖的变量会在 @import element-ui 主题源码之前生效, + * 因此整包 theme-chalk 是「从源码编译」出来的新主题,而不是事后打补丁。 + * 色值全部来自 cottagecore.scss(唯一色源),本文件只做「语义 → Element」的映射。 + * + * ★ 主色用陶土棕而不是草绿:Element 的 success 已经被工具栏的「修改」按钮占用为绿色, + * 若 primary 也用绿色,「新增 / 修改」两个按钮就变成同色系分不清。 + * 想改回草绿主色 → 把下面 $--color-primary 换成 $cc-grass-deep 即可(链接文字同样达标)。 + **/ + +@import './cottagecore.scss'; /* theme color */ -$--color-primary: #1890ff; -$--color-success: #13ce66; -$--color-warning: #ffba00; -$--color-danger: #ff4949; -// $--color-info: #1E1E1E; +$--color-primary: $cc-terra; // 陶土棕 · 白字 5.31:1 / 奶油底文字 4.93:1 +$--color-success: $cc-grass-deep; // 草绿 · 白字 5.43:1 / 奶油底文字 5.05:1 +$--color-warning: $cc-daisy-deep; // 深雏菊金 · 白字 5.24:1 +$--color-danger: $cc-rose; // 莓红 · 白字 5.75:1 +$--color-info: $cc-ash; // 暖褐灰 · 白字 6.08:1 -$--button-font-weight: 400; +$--button-font-weight: 500; -// $--color-text-regular: #1f2d3d; +/* 文字层级:一律暖棕,不用冷灰 */ +$--color-text-primary: $cc-ink; +$--color-text-regular: $cc-ink-2; +$--color-text-secondary: $cc-ink-3; +$--color-text-placeholder: $cc-ink-4; -$--border-color-light: #dfe4ed; -$--border-color-lighter: #e6ebf5; +/* 描边:花粉细边,禁止纯黑硬线 */ +$--border-color-base: #d8c3b0; +$--border-color-light: #e2d3c2; +$--border-color-lighter: #eadfd0; +$--border-color-extra-light: #f0e8dc; -$--table-border: 1px solid #dfe6ec; +/* 底色 */ +$--background-color-base: $cc-linen; +$--disabled-fill-base: $cc-linen; +$--disabled-color-base: $cc-ink-4; +$--disabled-border-base: #e2d3c2; + +/* 圆润:Cottagecore 的圆角一律大于 Element 默认的 4px */ +$--border-radius-base: 12px; +$--border-radius-small: 10px; +$--border-radius-circle: 100%; + +/* 柔影:暖棕扩散 */ +$--box-shadow-base: $cc-shadow-md; +$--box-shadow-dark: $cc-shadow-lg; +$--box-shadow-light: $cc-shadow-sm; + +/* 表格:柔和暖线,禁用 #dfe6ec 冷灰 */ +$--table-border: 1px solid #eadfd0; +$--table-border-color: #eadfd0; +$--table-header-background-color: $cc-linen; +$--table-header-font-color: $cc-ink-3; +$--table-row-hover-background-color: #fbf5ea; +$--table-current-row-background-color: $cc-linen; +$--table-font-color: $cc-ink-2; /* icon font path, required */ $--font-path: '~element-ui/lib/theme-chalk/fonts'; diff --git a/ruoyi-ui/src/assets/styles/index.scss b/ruoyi-ui/src/assets/styles/index.scss index b520173..ce84289 100644 --- a/ruoyi-ui/src/assets/styles/index.scss +++ b/ruoyi-ui/src/assets/styles/index.scss @@ -1,3 +1,4 @@ +@import './cottagecore.scss'; @import './variables.scss'; @import './mixin.scss'; @import './transition.scss'; @@ -11,7 +12,8 @@ body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - background: #f3f7ff; + background: $cc-linen; + color: $cc-ink-2; } label { @@ -21,7 +23,7 @@ label { html { height: 100%; box-sizing: border-box; - background: #f3f7ff; + background: $cc-linen; } #app { @@ -99,24 +101,24 @@ div:focus { } aside { - background: #eef1f6; + background: $cc-linen-2; padding: 8px 24px; margin-bottom: 20px; - border-radius: 2px; + border-radius: 12px; display: block; line-height: 32px; font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: #2c3e50; + color: $cc-ink; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; a { - color: #337ab7; + color: $cc-grass-text; cursor: pointer; &:hover { - color: rgb(32, 160, 255); + color: $cc-grass-deep; } } } @@ -125,12 +127,15 @@ aside { // 注意:这两张卡片都不能加 backdrop-filter / filter / transform, // 它们会创建层叠上下文,把 position:fixed 的 el-dialog 困在卡片里, // 而 Element UI 的 .v-modal 遮罩挂在 body 上(z-index:2000) → 弹窗被遮罩盖住(整页变黑、点一下才恢复) +// Cottagecore 皮肤下也严格只用 background / border / box-shadow 三样做卡片。 +// 另:整页卡片刻意「弱化」——去掉描边、底色贴近页面底、阴影收薄。 +// 否则「页卡 > 区块卡 > 小卡」三层卡片套在一起,画面很碎(规范也禁止卡片嵌套)。 .app-container { padding: 24px; - background: rgba(255, 255, 255, 0.88); - border: 1px solid rgba(255, 255, 255, 0.9); - border-radius: 16px; - box-shadow: 0 8px 24px rgba(72, 105, 166, 0.09), inset 0 1px 0 rgba(255, 255, 255, 0.95); + background: #fdfaf5; + border: 0; + border-radius: 20px; + box-shadow: 0 2px 10px rgba(139, 115, 85, 0.07); min-height: 500px; } @@ -140,37 +145,34 @@ aside { position: relative; margin: 6px 10px 6px 0; padding: 10px 24px 24px; - background: rgba(255, 255, 255, 0.88); - border: 1px solid rgba(255, 255, 255, 0.9); - border-radius: 16px; - box-shadow: 0 8px 24px rgba(72, 105, 166, 0.09), inset 0 1px 0 rgba(255, 255, 255, 0.95); + background: #fdfaf5; + border: 0; + border-radius: 20px; + box-shadow: 0 2px 10px rgba(139, 115, 85, 0.07); min-height: calc(100vh - 150px); } /* 只有「固定顶栏」时顶栏才脱离文档流,卡片才需要给它让位; - fixedHeader=false(本项目默认)时顶栏自己占位置,再加边距就会多出一条空白 */ + fixedHeader=false(本项目默认)时顶栏自己占位置,再加边距就会多出一条空白。 + 注意:标签页已并入顶栏,有/无标签页都只有一条 58px 的栏,不再区分 76 / 126px。 */ .fixed-header + .page-card { margin-top: 76px; } -.hasTagsView .fixed-header + .page-card { - margin-top: 126px; -} - // 页面标题通用样式 .page-header { display: flex; align-items: baseline; margin-bottom: 20px; padding-bottom: 16px; - border-bottom: 1px solid rgba(115, 133, 166, 0.12); + border-bottom: 1px solid $cc-line-2; } .page-title { margin: 0; font-size: 24px; font-weight: 700; - color: #263654; + color: $cc-ink; letter-spacing: 0.3px; } @@ -178,19 +180,19 @@ aside { margin-left: 12px; font-size: 16px; font-weight: 500; - color: #7385a6; - + color: $cc-ink-3; + &::before { content: '·'; margin-right: 8px; - color: #b0bace; + color: $cc-ink-4; } } .page-description { margin-top: 8px; font-size: 14px; - color: #7385a6; + color: $cc-ink-3; line-height: 1.6; } @@ -215,7 +217,7 @@ aside { text-align: right; padding-right: 20px; transition: 600ms ease position; - background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + background: linear-gradient(90deg, $cc-grass-deep 0%, $cc-grass-deep 0%, $cc-grass 100%, $cc-grass 100%); .subtitle { font-size: 20px; @@ -223,21 +225,21 @@ aside { } &.draft { - background: #d0d0d0; + background: $cc-ink-4; } &.deleted { - background: #d0d0d0; + background: $cc-ink-4; } } .link-type, .link-type:focus { - color: #337ab7; + color: $cc-terra; cursor: pointer; &:hover { - color: rgb(32, 160, 255); + color: $cc-grass-text; } } diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss index 35d671b..095bef0 100644 --- a/ruoyi-ui/src/assets/styles/sidebar.scss +++ b/ruoyi-ui/src/assets/styles/sidebar.scss @@ -1,46 +1,60 @@ /* ========================================================================== - 悬浮卡片侧栏(主题核心文件) + 悬浮卡片侧栏(主题核心文件)· Cottagecore / 田园核风 - 侧栏容器完全透明:页面上只有一张张独立卡片 - - 一级菜单:48px 毛玻璃卡片 + 28px 彩色图标块 + - 一级菜单:48px 奶油卡片 + 28px 暖色图标块 - 二/三级:原地向下展开,用竖线 + 圆点区分层级 - 收起态:54px 窄栏只留图标,悬停向右弹出子菜单 - 移动端:整栏抽屉 + + 改动说明(相对上一版蓝色皮肤): + 1. 去掉毛玻璃(backdrop-filter)—— 规范明确不把玻璃态当默认风格, + 且不透明奶油卡在亚麻底上层次更清楚,也少一层层叠上下文隐患。 + 2. 8 色图标渐变换成大地/花卉色,不再有一个蓝。 + 3. 所有选中/悬停色由陶土棕 $cc-terra + 雏菊黄 $cc-daisy 派生。 ========================================================================== */ -$sidebar-width: $base-sidebar-width; -$menu-h: 48px; -$submenu-h: 36px; -$card-radius: 13px; -$brand: #2f6bff; -$text-main: #263654; -$text-sub: #66738b; -$text-muted: #98a3b7; -$card-bg: rgba(255, 255, 255, .84); -$card-border: rgba(255, 255, 255, .88); -$card-shadow: 0 7px 20px rgba(72, 105, 166, .11), inset 0 1px 0 rgba(255, 255, 255, .92); +@import './cottagecore.scss'; -/* 一级菜单图标色板:8 色循环(浅色→深色),避免整栏一个蓝 */ -$icon-palette: - (#4e9bff, #2f6bff), // 1 蓝 - (#ffb648, #f97316), // 2 橙 - (#4ade80, #16a34a), // 3 绿 - (#fb7185, #ef4444), // 4 红 - (#a78bfa, #7c3aed), // 5 紫 - (#38bdf8, #0ea5e9), // 6 青 - (#f472b6, #db2777), // 7 粉 - (#fcd34d, #f59e0b); // 8 黄 +$sidebar-width: $base-sidebar-width; +/* 菜单密度 + ★ 注意:用户说「拥挤」指的是视觉憋闷,不是占得高。上一轮缩成 42px/3px 反而更挤了。 + 正确做法是「加大项高 + 加大间距」:现在每项 54px + 上下 7px = 68px。 + 17 个一级菜单会超一屏 → 走 el-scrollbar 滚动,这是可接受的代价。 */ +$menu-h: 54px; +$submenu-h: 38px; +$card-radius: 14px; +$brand: $cc-terra; +$text-main: $cc-ink; +$text-sub: $cc-ink-2; +$text-muted: $cc-ink-3; +$card-bg: $cc-cream-hi; +$card-border: $cc-line; +$card-shadow: $cc-shadow-sm; + +/* 一级菜单图标色板:只留 4 个田园色循环(陶土 / 草绿 / 雏菊金 / 玫瑰粉) + 原来是 8 色高饱和渐变,15 个菜单项齐上像调色盘; + 现在与仪表盘统计卡共用同一套 4 色,整站配色口径统一。 */ +$icon-hues: + #9a5c35, // 1 陶土 + #457450, // 2 草绿 + #a8791f, // 3 雏菊金 + #b57474; // 4 玫瑰粉 +$icon-hue-count: length($icon-hues); html, body { - background: #f3f7ff; + background: $cc-linen; } #app { min-height: 100%; + /* 亚麻底整体加深一档(原来是 #fdfaf5→#f3ece0,顶部近白, + 和奶油卡片几乎同色,卡片边界会糊掉)。现在卡片是亮面、页面是麻面,层次清楚。 */ background: - radial-gradient(760px 520px at 4% 100%, rgba(78, 155, 255, .18), transparent 62%), - radial-gradient(760px 520px at 96% 0%, rgba(124, 92, 252, .12), transparent 62%), - linear-gradient(155deg, #f5f8ff 0%, #fbfdff 46%, #edf4ff 100%); + radial-gradient(760px 520px at 4% 100%, rgba(90, 143, 90, .11), transparent 62%), + radial-gradient(760px 520px at 96% 0%, rgba(212, 160, 160, .13), transparent 62%), + radial-gradient(520px 420px at 78% 88%, rgba(245, 215, 95, .14), transparent 60%), + linear-gradient(155deg, #f7f1e6 0%, #f3ece0 48%, #ece2d3 100%); background-attachment: fixed; .main-container { @@ -83,9 +97,9 @@ body { background: transparent !important; } - /* Logo 卡:10 + 64 + 6 = 80px */ + /* Logo 卡:10 + 60 + 8 = 78px */ &.has-logo .el-scrollbar { - height: calc(100% - 80px); + height: calc(100% - 78px); } .scrollbar-wrapper { @@ -98,7 +112,7 @@ body { } .el-scrollbar__thumb { - background: rgba(123, 144, 181, .28); + background: rgba(139, 115, 85, .26); } .is-horizontal { @@ -140,19 +154,17 @@ body { min-width: 0 !important; height: $menu-h; line-height: $menu-h; - margin: 6px 10px !important; + margin: 7px 10px !important; padding: 0 14px !important; box-sizing: border-box; border: 1px solid $card-border; border-radius: $card-radius; background: $card-bg !important; - -webkit-backdrop-filter: blur(14px) saturate(155%); - backdrop-filter: blur(14px) saturate(155%); box-shadow: $card-shadow; color: $text-main !important; - font-size: 14px; + font-size: 14.5px; font-weight: 600; transition: @@ -164,34 +176,34 @@ body { .el-menu:not(.el-menu--inline) > div > a > .el-menu-item:hover, .el-menu:not(.el-menu--inline) > div > .el-submenu > .el-submenu__title:hover { - background: rgba(255, 255, 255, .95) !important; - border-color: rgba(150, 179, 235, .38); - box-shadow: 0 9px 24px rgba(57, 94, 159, .14), inset 0 1px 0 #fff; + background: $cc-cream !important; + border-color: $cc-blossom-deep; + box-shadow: $cc-shadow-md; transform: translateY(-1px); } /* 展开中的一级菜单 */ .el-menu:not(.el-menu--inline) > div > .el-submenu.is-opened > .el-submenu__title, .el-menu:not(.el-menu--inline) > div > .el-submenu.is-active > .el-submenu__title { - color: #173f94 !important; - border-color: rgba(67, 126, 255, .28); - background: linear-gradient(135deg, rgba(255, 255, 255, .96), rgba(235, 242, 255, .91)) !important; - box-shadow: 0 8px 22px rgba(47, 107, 255, .13), inset 3px 0 0 $brand; + color: $cc-grass-text !important; + border-color: $cc-blossom; + background: linear-gradient(135deg, $cc-cream-hi, rgba(245, 215, 95, .18)) !important; + box-shadow: $cc-shadow-md, inset 3px 0 0 $brand; } /* 一级叶子菜单选中态 */ .el-menu:not(.el-menu--inline) > div > a > .el-menu-item.is-active { color: $brand !important; - border-color: rgba(67, 126, 255, .30); - background: linear-gradient(135deg, rgba(255, 255, 255, .98), rgba(231, 239, 255, .92)) !important; - box-shadow: 0 8px 22px rgba(47, 107, 255, .14), inset 3px 0 0 $brand; + border-color: $cc-blossom; + background: linear-gradient(135deg, $cc-cream-hi, rgba(212, 160, 160, .22)) !important; + box-shadow: $cc-shadow-md, inset 3px 0 0 $brand; } /* 展开箭头 */ .el-menu:not(.el-menu--inline) > div > .el-submenu > .el-submenu__title .el-submenu__icon-arrow { right: 14px; margin-top: -5px; - color: #7385a6; + color: $cc-ink-3; font-size: 12px; font-weight: 700; } @@ -206,27 +218,29 @@ body { align-items: center; justify-content: center; box-sizing: border-box; - width: 28px; - height: 28px; + width: 30px; + height: 30px; margin: 0 11px 0 0 !important; - padding: 5px; - border-radius: 9px; - color: #fff !important; - fill: #fff; - background: linear-gradient(135deg, #4e9bff, #2f6bff); - box-shadow: 0 5px 12px rgba(47, 107, 255, .25); + padding: 6px; + border-radius: 11px; + /* 浅底 + 同色深图标。底色不能太淡,否则小图标「看不见」(用户反馈对比度不够), + 所以 tint 用 .22 并加 1px 内描边。 */ + color: #9a5c35 !important; + fill: currentColor; + background: rgba(154, 92, 53, .22); + box-shadow: inset 0 0 0 1px rgba(154, 92, 53, .32); } - /* 按菜单顺序轮换图标配色:第 1~8 个一组,之后循环 */ - @for $i from 1 through 8 { - $pair: nth($icon-palette, $i); - $from: nth($pair, 1); - $to: nth($pair, 2); + /* 按菜单顺序在这 4 个色里轮换 */ + @for $i from 1 through $icon-hue-count { + $hue: nth($icon-hues, $i); - .el-menu:not(.el-menu--inline) > div:nth-child(8n + #{$i}) > a > .el-menu-item .svg-icon, - .el-menu:not(.el-menu--inline) > div:nth-child(8n + #{$i}) > .el-submenu > .el-submenu__title .svg-icon { - background: linear-gradient(135deg, $from, $to); - box-shadow: 0 5px 12px rgba($to, .28); + .el-menu:not(.el-menu--inline) > div:nth-child(#{$icon-hue-count}n + #{$i}) > a > .el-menu-item .svg-icon, + .el-menu:not(.el-menu--inline) > div:nth-child(#{$icon-hue-count}n + #{$i}) > .el-submenu > .el-submenu__title .svg-icon { + background: rgba($hue, .22); + box-shadow: inset 0 0 0 1px rgba($hue, .32); + color: $hue !important; + fill: currentColor; } } @@ -236,8 +250,8 @@ body { .el-menu--inline { position: relative; width: calc(100% - 30px) !important; - margin: -1px 10px 5px 20px; - padding: 4px 0 5px 17px; + margin: -2px 10px 6px 18px; + padding: 4px 0 6px 17px; box-sizing: border-box; background: transparent !important; border: 0 !important; @@ -253,7 +267,7 @@ body { bottom: 7px; width: 2px; border-radius: 1px; - background: linear-gradient(180deg, rgba(47, 107, 255, .40), rgba(115, 133, 166, .22)); + background: linear-gradient(180deg, rgba(154, 92, 53, .38), rgba(212, 160, 160, .22)); } .el-menu--inline .el-menu-item, @@ -265,12 +279,12 @@ body { width: 100%; height: $submenu-h; line-height: $submenu-h; - margin: 1px 0 !important; - padding: 0 12px 0 24px !important; + margin: 2px 0 !important; + padding: 0 12px 0 26px !important; box-sizing: border-box; border: 0 !important; - border-radius: 9px; + border-radius: 10px; background: transparent !important; box-shadow: none !important; @@ -293,8 +307,8 @@ body { margin-top: -4px; box-sizing: border-box; border-radius: 50%; - border: 2px solid #7385a6; - background: #fff; + border: 2px solid $cc-ink-4; + background: $cc-cream; transition: all .2s ease; } @@ -306,20 +320,20 @@ body { .el-menu--inline .el-menu-item:hover, .el-menu--inline .el-submenu > .el-submenu__title:hover { - color: #2f6bff !important; - background: rgba(234, 241, 255, .72) !important; + color: $brand !important; + background: rgba(245, 215, 95, .20) !important; transform: none !important; &::before { - border-color: #2f6bff; - background: rgba(47, 107, 255, .15); + border-color: $brand; + background: rgba(154, 92, 53, .16); } } .el-menu--inline .el-menu-item.is-active { color: $brand !important; font-weight: 650; - background: linear-gradient(90deg, rgba(222, 234, 255, .92), rgba(239, 245, 255, .72)) !important; + background: linear-gradient(90deg, rgba(212, 160, 160, .30), rgba(245, 215, 95, .16)) !important; } .el-menu--inline .el-menu-item.is-active::before { @@ -328,7 +342,7 @@ body { margin-top: -5px; border-color: $brand; background: $brand; - box-shadow: 0 0 0 4px rgba(47, 107, 255, .15); + box-shadow: 0 0 0 4px rgba(154, 92, 53, .16); } /* 三级:在二级基础上小步缩进,不把内容推到很右边 */ @@ -345,16 +359,16 @@ body { .el-menu--inline .el-menu--inline .el-menu-item, .el-menu--inline .el-menu--inline .el-submenu > .el-submenu__title { - height: 34px; - line-height: 34px; - padding-left: 22px !important; - font-size: 12.5px; - color: #7c879a !important; + height: 36px; + line-height: 36px; + padding-left: 24px !important; + font-size: 13px; + color: $cc-ink-3 !important; } .el-menu--inline .el-submenu__icon-arrow { right: 10px; - color: #9aa6bb; + color: $cc-ink-4; font-size: 11px; } } @@ -438,12 +452,10 @@ body { .el-menu--vertical { > .el-menu--popup { padding: 8px; - border-radius: 12px; - background: rgba(255, 255, 255, .96); - -webkit-backdrop-filter: blur(14px) saturate(155%); - backdrop-filter: blur(14px) saturate(155%); - border: 1px solid rgba(255, 255, 255, .9); - box-shadow: 0 12px 32px rgba(72, 105, 166, .18); + border-radius: 14px; + background: $cc-cream-hi; + border: 1px solid $cc-line; + box-shadow: $cc-shadow-lg; .el-menu-item { height: 36px; @@ -451,21 +463,21 @@ body { min-width: 150px; margin: 2px 0; padding: 0 14px !important; - border-radius: 8px; + border-radius: 10px; color: $text-sub !important; font-size: 13px; font-weight: 500; background: transparent !important; &:hover { - background: rgba(234, 241, 255, .85) !important; + background: rgba(245, 215, 95, .24) !important; color: $brand !important; } &.is-active { color: $brand !important; font-weight: 650; - background: linear-gradient(90deg, rgba(222, 234, 255, .95), rgba(239, 245, 255, .8)) !important; + background: linear-gradient(90deg, rgba(212, 160, 160, .32), rgba(245, 215, 95, .18)) !important; } .svg-icon { @@ -487,7 +499,7 @@ body { bottom: 7px; width: 2px; border-radius: 1px; - background: linear-gradient(180deg, rgba(47, 107, 255, .35), rgba(115, 133, 166, .2)); + background: linear-gradient(180deg, rgba(154, 92, 53, .34), rgba(212, 160, 160, .2)); } .el-menu-item, @@ -497,7 +509,7 @@ body { line-height: 34px; padding-left: 20px !important; font-size: 12.5px; - color: #7c879a !important; + color: $cc-ink-3 !important; background: transparent !important; &::before { @@ -510,13 +522,13 @@ body { margin-top: -4px; box-sizing: border-box; border-radius: 50%; - border: 2px solid #9aa6bb; - background: #fff; + border: 2px solid $cc-ink-4; + background: $cc-cream; } &:hover { color: $brand !important; - background: rgba(234, 241, 255, .85) !important; + background: rgba(245, 215, 95, .24) !important; &::before { border-color: $brand; @@ -526,7 +538,7 @@ body { &.is-active { color: $brand !important; font-weight: 650; - background: rgba(234, 241, 255, .9) !important; + background: rgba(212, 160, 160, .26) !important; &::before { border-color: $brand; diff --git a/ruoyi-ui/src/assets/styles/skin.scss b/ruoyi-ui/src/assets/styles/skin.scss index 3fbb24b..5e3d31e 100644 --- a/ruoyi-ui/src/assets/styles/skin.scss +++ b/ruoyi-ui/src/assets/styles/skin.scss @@ -1,28 +1,48 @@ /* ========================================================================== - 皮肤层:按钮 / 表单 / 表格 / 分页 / 页头 / 水印 / 暗色 + 皮肤层:按钮 / 表单 / 表格 / 分页 / 页头 / 弹层 · Cottagecore / 田园核风 只覆盖 Element UI 默认样式,不改组件源码;需要整体回滚时删掉本文件的 import 即可 + (index.scss 最后一行 @import './skin.scss') + + 交互节奏按规范走「Gentle / Watercolor」:过渡 .4s ease-in-out, + 悬停做轻微旋转(≤0.6deg)与小幅放大,按下柔和回弹 scale(.97), + 不使用 bounce / elastic,也不用 filter: brightness 那种硬闪。 ========================================================================== */ -$brand: #2f6bff; -$ink: #263654; -$ink-2: #5b6880; -$ink-3: #98a3b7; -$line: #eef2f9; +@import './cottagecore.scss'; + +$brand: $cc-terra; +$ink: $cc-ink; +$ink-2: $cc-ink-2; +$ink-3: $cc-ink-3; +$line: #eadfd0; /* ------------------------------- 按钮 ------------------------------- */ .el-button { - border-radius: 10px; + border-radius: 12px; font-size: 13px; font-weight: 600; line-height: 1; - transition: filter .16s ease, box-shadow .16s ease; + border-color: $cc-line; + background: $cc-cream-hi; + color: $ink-2; + transition: + transform .4s ease-in-out, + box-shadow .4s ease-in-out, + background-color .4s ease-in-out, + border-color .4s ease-in-out; > i { font-size: 14px; } - &:hover { - filter: brightness(1.06); + &:hover:not(.is-disabled) { + transform: rotate(-0.4deg) scale(1.02); + border-color: $cc-blossom-deep; + box-shadow: $cc-shadow-sm; + } + + &:active:not(.is-disabled) { + transform: scale(0.97); } } @@ -31,109 +51,115 @@ $line: #eef2f9; font-size: 13px; } -/* 工具栏按钮:实心胶囊(新增蓝 / 修改绿 / 删除红 / 导入青 / 导出橙) */ +/* 工具栏按钮:实心胶囊(新增陶土 / 修改草绿 / 删除莓红 / 导入褐灰 / 导出雏菊金) + —— 五种色相刻意拉开,避免「新增 / 修改」变成同色系分不清 */ .el-button--primary.is-plain { - background: #2f6bff; - border-color: #2f6bff; + background: $cc-terra; + border-color: $cc-terra; color: #fff; &:hover, &:focus { - background: #1f57e0; - border-color: #1f57e0; + background: #854c2a; + border-color: #854c2a; color: #fff; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { - background: #a9c1ff; - border-color: #a9c1ff; + background: #cfa98f; + border-color: #cfa98f; color: #fff; } } .el-button--success.is-plain { - background: #22c55e; - border-color: #22c55e; + background: $cc-grass-deep; + border-color: $cc-grass-deep; color: #fff; &:hover, &:focus { - background: #16a34a; - border-color: #16a34a; + background: #3a6243; + border-color: #3a6243; color: #fff; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { - background: #a5e5bf; - border-color: #a5e5bf; + background: #a9c9ae; + border-color: #a9c9ae; color: #fff; } } .el-button--danger.is-plain { - background: #ef4444; - border-color: #ef4444; + background: $cc-rose; + border-color: $cc-rose; color: #fff; &:hover, &:focus { - background: #dc2626; - border-color: #dc2626; + background: #8b3c4c; + border-color: #8b3c4c; color: #fff; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { - background: #f7b0b0; - border-color: #f7b0b0; + background: #d9a9b2; + border-color: #d9a9b2; color: #fff; } } .el-button--info.is-plain { - background: #06b6d4; - border-color: #06b6d4; + background: $cc-ash; + border-color: $cc-ash; color: #fff; &:hover, &:focus { - background: #0891b2; - border-color: #0891b2; + background: #5b5244; + border-color: #5b5244; color: #fff; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { - background: #9adcea; - border-color: #9adcea; + background: #b8b0a3; + border-color: #b8b0a3; color: #fff; } } .el-button--warning.is-plain { - background: #f59e0b; - border-color: #f59e0b; + background: $cc-daisy-deep; + border-color: $cc-daisy-deep; color: #fff; &:hover, &:focus { - background: #d97706; - border-color: #d97706; + background: #7a5512; + border-color: #7a5512; color: #fff; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { - background: #fbd08a; - border-color: #fbd08a; + background: #d6bb86; + border-color: #d6bb86; color: #fff; } } -/* 表格行内文字按钮:编辑蓝、删除红 */ +/* 表格行内文字按钮:编辑陶土、删除莓红 */ .el-table .el-button--text { padding: 4px 6px; font-size: 13px; font-weight: 600; + color: $brand; + + &:hover, &:focus { + color: $cc-grass-text; + } } .el-table .el-button--text.text-danger { - color: #ef4444; + color: $cc-rose; &:hover, &:focus { - color: #dc2626; + color: #8b3c4c; } } @@ -141,21 +167,27 @@ $line: #eef2f9; .el-table .more-dot { padding: 4px 10px; font-size: 16px; - color: $ink-3; + color: $cc-ink-4; } /* ------------------------------- 表单 ------------------------------- */ .el-input__inner, .el-textarea__inner { - border-radius: 10px; - border-color: #e6ecf6; + border-radius: 12px; + border-color: $cc-line; + background: $cc-cream-hi; color: $ink; } +.el-input__inner::placeholder, +.el-textarea__inner::placeholder { + color: $cc-ink-4; +} + .el-input__inner:focus, .el-textarea__inner:focus { - border-color: rgba(47, 107, 255, .55); - box-shadow: 0 0 0 3px rgba(47, 107, 255, .1); + border-color: rgba(154, 92, 53, .55); + box-shadow: 0 0 0 3px rgba(154, 92, 53, .12); } /* 搜索条不再显示 label,用 placeholder 表达(与设计图一致) */ @@ -168,10 +200,20 @@ $line: #eef2f9; margin-bottom: 6px; } +/* 下拉/日期浮层的输入框跟着圆 */ +.el-select-dropdown__item.selected, +.el-select-dropdown__item.hover, +.el-select-dropdown__item:hover { + background: rgba(245, 215, 95, .26); +} + /* ------------------------------- 表格 ------------------------------- */ .el-table { font-size: 13px; - color: #2b3a55; + color: $ink-2; + background: transparent; + /* 数字列右对齐时天然对齐,不用等宽字体(等宽被规范列为禁止项) */ + font-variant-numeric: tabular-nums; &::before { display: none; @@ -179,8 +221,8 @@ $line: #eef2f9; th.el-table__cell { height: 42px; - background: #f7f9fe; - color: $ink-2; + background: $cc-linen; + color: $cc-ink-3; font-size: 13px; font-weight: 600; } @@ -191,7 +233,7 @@ $line: #eef2f9; } .el-table__row:hover > td.el-table__cell { - background: #f8fbff; + background: #fbf5ea; } .el-button--text { @@ -212,7 +254,7 @@ $line: #eef2f9; .app-container .pagination-container { margin-top: 6px; padding: 8px 16px 6px; - border-radius: 12px; + border-radius: 14px; } .el-pagination { @@ -227,13 +269,20 @@ $line: #eef2f9; height: 32px; line-height: 30px; margin: 0 3px; - border: 1px solid #e9eff8; - border-radius: 8px; - background: #fff; + border: 1px solid $line; + border-radius: 10px; + background: $cc-cream-hi; color: $ink-2; font-weight: 600; } + .btn-prev:hover, + .btn-next:hover, + .el-pager li:hover { + border-color: $cc-blossom-deep; + color: $brand; + } + .el-pager li.active { background: $brand; border-color: $brand; @@ -242,7 +291,7 @@ $line: #eef2f9; .el-pagination__sizes .el-input__inner, .el-pagination__jump .el-input__inner { - border-radius: 8px; + border-radius: 10px; } } @@ -256,6 +305,14 @@ $line: #eef2f9; border-bottom: 0; } +/* 标题类走衬线:只在 ≥16px 的大号字上用,制造田园感而不牺牲表格可读性 */ +.page-title, +.el-dialog__title, +.el-message-box__title { + font-family: $cc-serif; + letter-spacing: .2px; +} + /* ------------------------------- 弹层 ------------------------------- $confirm / $alert(el-message-box)之前完全没被皮肤层覆盖,还是 Element 默认的 4px 方角 + 15px 内边距,和 12px 的 el-dialog、10px 的按钮/输入框 @@ -263,14 +320,14 @@ $line: #eef2f9; ------------------------------------------------------------------- */ .el-message-box { padding-bottom: 0; - border: 1px solid rgba(255, 255, 255, 0.9); - border-radius: 12px; - box-shadow: 0 12px 32px rgba(72, 105, 166, 0.18); + border: 1px solid $cc-line; + border-radius: 18px; + box-shadow: $cc-shadow-lg; } .el-message-box__header { padding: 20px 24px 16px; - border-bottom: 1px solid rgba(115, 133, 166, 0.12); + border-bottom: 1px solid $cc-line-2; } .el-message-box__title { @@ -292,13 +349,13 @@ $line: #eef2f9; .el-message-box__status { &.el-icon-warning { - color: #f59e0b; + color: $cc-daisy-deep; } &.el-icon-success { - color: #22c55e; + color: $cc-grass-deep; } &.el-icon-error { - color: #ef4444; + color: $cc-rose; } &.el-icon-info { color: $brand; @@ -307,7 +364,7 @@ $line: #eef2f9; .el-message-box__btns { padding: 16px 24px; - border-top: 1px solid rgba(115, 133, 166, 0.12); + border-top: 1px solid $cc-line-2; .el-button { min-width: 76px; @@ -322,12 +379,61 @@ $line: #eef2f9; .el-picker-panel, .el-message, .el-notification { - border-color: rgba(115, 133, 166, 0.14); - border-radius: 10px; - box-shadow: 0 8px 24px rgba(72, 105, 166, 0.12); + border-color: $cc-line-2; + border-radius: 14px; + box-shadow: $cc-shadow-lg; overflow: hidden; } .el-message { min-width: 320px; } + +/* 标签:圆润小球形,配色跟随语义色 */ +.el-tag { + border-radius: 999px; + padding: 0 12px; + border-color: $cc-line; +} + +/* 复选框/单选框/开关:跟随陶土主色 */ +.el-checkbox__input.is-checked .el-checkbox__inner, +.el-checkbox__input.is-indeterminate .el-checkbox__inner, +.el-radio__input.is-checked .el-radio__inner { + background-color: $brand; + border-color: $brand; +} + +.el-checkbox__input.is-checked + .el-checkbox__label, +.el-radio__input.is-checked + .el-radio__label { + color: $brand; +} + +/* 卡片 / 折叠面板 / 描述列表:统一的奶油卡 */ +.el-card, +.el-collapse, +.el-collapse-item__header, +.el-collapse-item__wrap, +.el-descriptions__body { + border-color: $cc-line; + border-radius: 16px; + background: $cc-cream; +} + +.el-collapse-item__header, +.el-collapse-item__wrap { + border-radius: 0; + border-bottom-color: $cc-line-2; +} + +/* ------------------------------- 无障碍 ------------------------------- + 规范要求动效提供 reduced-motion 备选:关掉悬停位移/旋转,只留颜色变化 + ------------------------------------------------------------------- */ +@media (prefers-reduced-motion: reduce) { + .el-button, + .el-button:hover, + .el-button:active { + transform: none !important; + transition: background-color .01ms linear, border-color .01ms linear !important; + } +} diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss index 72f4cb9..aacb6bd 100644 --- a/ruoyi-ui/src/assets/styles/variables.scss +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -1,40 +1,29 @@ -// base color -$blue:#324157; -$light-blue:#3A71A8; -$red:#C03639; -$pink: #E65D6E; -$green: #30B08F; -$tiffany: #4AB7BD; -$yellow:#FEC171; -$panGreen: #30B08F; +@import './cottagecore.scss'; -// 默认菜单主题风格 -$base-menu-color:#bfcbd9; -$base-menu-color-active:#f4f4f5; -$base-menu-background:#304156; +// base color(沿用 cottagecore 色板,避免这里的 $blue/$green 与主题脱节) +$blue: $cc-earth; +$light-blue: $cc-grass; +$red: $cc-rose; +$pink: $cc-blossom; +$green: $cc-grass-deep; +$tiffany: $cc-grass; +$yellow: $cc-daisy; +$panGreen: $cc-grass-deep; + +// 深色菜单主题风格(sideTheme: 'theme-dark' 时用;Cottagecore 皮肤默认走下面的浅色) +$base-menu-color: #bfcbd9; +$base-menu-color-active: #f4f4f5; +$base-menu-background: #304156; $base-logo-title-color: #ffffff; -$base-menu-light-color:rgba(0,0,0,.70); -$base-menu-light-background:#ffffff; -$base-logo-light-title-color: #001529; +// 浅色菜单主题风格(当前使用:奶油底 + 暖棕文字) +$base-menu-light-color: $cc-ink-2; +$base-menu-light-background: $cc-cream; +$base-logo-light-title-color: $cc-ink; -$base-sub-menu-background:#1f2d3d; -$base-sub-menu-hover:#001528; - -// 自定义暗色菜单风格 -/** -$base-menu-color:hsla(0,0%,100%,.65); -$base-menu-color-active:#fff; -$base-menu-background:#001529; -$base-logo-title-color: #ffffff; - -$base-menu-light-color:rgba(0,0,0,.70); -$base-menu-light-background:#ffffff; -$base-logo-light-title-color: #001529; - -$base-sub-menu-background:#000c17; -$base-sub-menu-hover:#001528; -*/ +// 深色主题的二级菜单底色(未使用,留作回退) +$base-sub-menu-background: #1f2d3d; +$base-sub-menu-hover: #001528; $base-sidebar-width: 240px; diff --git a/ruoyi-ui/src/components/Breadcrumb/index.vue b/ruoyi-ui/src/components/Breadcrumb/index.vue index d533384..df2aa9e 100644 --- a/ruoyi-ui/src/components/Breadcrumb/index.vue +++ b/ruoyi-ui/src/components/Breadcrumb/index.vue @@ -65,48 +65,48 @@ export default { font-size: 14px; line-height: 58px; margin-left: 4px; - color: #7385a6; + color: #7a664e; ::v-deep .el-breadcrumb__separator { - color: #b0bace; + color: #9a886e; margin: 0 6px; font-weight: 400; } ::v-deep .el-breadcrumb__item { .el-breadcrumb__inner { - color: #5a6478; + color: #5f4f3d; font-weight: 500; transition: color 0.2s ease; &:hover { - color: #2f6bff; + color: #9a5c35; } &.is-link { - color: #7385a6; + color: #7a664e; font-weight: 400; } } &:last-child .el-breadcrumb__inner { - color: #2f6bff; + color: #9a5c35; font-weight: 600; } } .no-redirect { - color: #2f6bff; + color: #9a5c35; cursor: text; font-weight: 600; } a { - color: #7385a6; + color: #7a664e; font-weight: 500; &:hover { - color: #2f6bff; + color: #9a5c35; } } } diff --git a/ruoyi-ui/src/components/FileUpload/index.vue b/ruoyi-ui/src/components/FileUpload/index.vue index 6c583cf..d579555 100644 --- a/ruoyi-ui/src/components/FileUpload/index.vue +++ b/ruoyi-ui/src/components/FileUpload/index.vue @@ -19,8 +19,8 @@
请上传 - - + + 的文件
diff --git a/ruoyi-ui/src/components/ImagePreview/index.vue b/ruoyi-ui/src/components/ImagePreview/index.vue index 3c770c7..7f79d03 100644 --- a/ruoyi-ui/src/components/ImagePreview/index.vue +++ b/ruoyi-ui/src/components/ImagePreview/index.vue @@ -83,7 +83,7 @@ export default { align-items: center; width: 100%; height: 100%; - color: #909399; + color: #7a664e; font-size: 30px; } } diff --git a/ruoyi-ui/src/components/ImageUpload/index.vue b/ruoyi-ui/src/components/ImageUpload/index.vue index 19a9957..ad0756f 100644 --- a/ruoyi-ui/src/components/ImageUpload/index.vue +++ b/ruoyi-ui/src/components/ImageUpload/index.vue @@ -23,8 +23,8 @@
请上传 - - + + 的文件
diff --git a/ruoyi-ui/src/components/ThemePicker/index.vue b/ruoyi-ui/src/components/ThemePicker/index.vue index 1714e1f..a110dd6 100644 --- a/ruoyi-ui/src/components/ThemePicker/index.vue +++ b/ruoyi-ui/src/components/ThemePicker/index.vue @@ -1,7 +1,7 @@ @@ -122,8 +122,8 @@ diff --git a/ruoyi-ui/src/views/skins/delivery/transferApplyProcessed.vue b/ruoyi-ui/src/views/skins/delivery/transferApplyProcessed.vue index b3ff524..a2131a1 100644 --- a/ruoyi-ui/src/views/skins/delivery/transferApplyProcessed.vue +++ b/ruoyi-ui/src/views/skins/delivery/transferApplyProcessed.vue @@ -105,7 +105,7 @@ 已用:{{ scope.row.dailyUsedCount }}
审核中:{{ scope.row.dailyPendingCount }} - + diff --git a/ruoyi-ui/src/views/skins/delivery/zbtrecord.vue b/ruoyi-ui/src/views/skins/delivery/zbtrecord.vue index 2654fca..448ee93 100644 --- a/ruoyi-ui/src/views/skins/delivery/zbtrecord.vue +++ b/ruoyi-ui/src/views/skins/delivery/zbtrecord.vue @@ -265,7 +265,7 @@ export default { align-items: center; justify-content: space-between; &:hover { - background-color: #409eff; + background-color: #9a5c35; transition: all ease 0.3s; } } diff --git a/ruoyi-ui/src/views/skins/ttBox/boxrPize.vue b/ruoyi-ui/src/views/skins/ttBox/boxrPize.vue index 5d04983..8d07411 100644 --- a/ruoyi-ui/src/views/skins/ttBox/boxrPize.vue +++ b/ruoyi-ui/src/views/skins/ttBox/boxrPize.vue @@ -414,7 +414,7 @@ -
暂无饰品
+
暂无饰品
@@ -70,7 +70,7 @@ @@ -99,7 +99,7 @@ {{ currentMerchant.nickName }}(ID: {{ currentMerchant.userId }})
- 当前卡商余额:{{ currentMerchant.merchantBalance }} + 当前卡商余额:{{ currentMerchant.merchantBalance }}
@@ -134,7 +134,7 @@ {{ currentMerchant.nickName }}(ID: {{ currentMerchant.userId }})
- 当前卡商余额:{{ currentMerchant.merchantBalance }} + 当前卡商余额:{{ currentMerchant.merchantBalance }} @@ -149,10 +149,10 @@ /> - + {{ balanceDelta > 0 ? '+' : '' }}{{ balanceDelta }} - (按差额记入充值 / 消费记录) + (按差额记入充值 / 消费记录)