11<template >
2- <el-drawer v-model =" settingsVisible" size =" 300" :title =" $t('settings.project')" >
3- <el-divider >{{ $t("settings.theme") }}</el-divider >
4-
5- <div class =" flex-center" >
6- <el-switch v-model =" isDark" active-icon =" Moon" inactive-icon =" Sunny" @change =" changeTheme" />
7- </div >
8-
9- <el-divider >{{ $t("settings.interface") }}</el-divider >
10-
11- <div class =" py-1 flex-x-between" >
12- <span class =" text-xs" >{{ $t("settings.themeColor") }}</span >
13- <ThemeColorPicker v-model =" settingsStore.themeColor" @update:model-value =" changeThemeColor" />
14- </div >
15-
16- <div class =" py-1 flex-x-between" >
17- <span class =" text-xs" >{{ $t("settings.tagsView") }}</span >
18- <el-switch v-model =" settingsStore.tagsView" />
19- </div >
20-
21- <div class =" py-1 flex-x-between" >
22- <span class =" text-xs" >{{ $t("settings.sidebarLogo") }}</span >
23- <el-switch v-model =" settingsStore.sidebarLogo" />
24- </div >
25-
26- <div class =" py-1 flex-x-between" >
27- <span class =" text-xs" >{{ $t("settings.watermark") }}</span >
28- <el-switch v-model =" settingsStore.watermarkEnabled" />
29- </div >
30- <div v-if =" !isDark" class =" py-1 flex-x-between" >
31- <span class =" text-xs" >{{ $t("settings.sidebarColorScheme") }}</span >
32- <el-radio-group v-model =" sidebarColor" @change =" changeSidebarColor" >
33- <el-radio :value =" SidebarColorEnum.CLASSIC_BLUE" >{{ $t("settings.classicBlue") }}</el-radio >
34- <el-radio :value =" SidebarColorEnum.MINIMAL_WHITE" >
35- {{ $t("settings.minimalWhite") }}
36- </el-radio >
37- </el-radio-group >
38- </div >
39-
40- <el-divider >{{ $t("settings.navigation") }}</el-divider >
41-
42- <LayoutSelect v-model =" settingsStore.layout" @update:model-value =" changeLayout" />
2+ <el-drawer
3+ v-model =" drawerVisible"
4+ size =" 300"
5+ :title =" $t('settings.project')"
6+ :before-close =" handleCloseDrawer"
7+ >
8+ <section class =" config-section" >
9+ <el-divider >{{ $t("settings.theme") }}</el-divider >
10+
11+ <div class =" flex-center" >
12+ <el-switch
13+ v-model =" isDark"
14+ active-icon =" Moon"
15+ inactive-icon =" Sunny"
16+ @change =" handleThemeChange"
17+ />
18+ </div >
19+ </section >
20+
21+ <!-- 界面设置 -->
22+ <section class =" config-section" >
23+ <el-divider >{{ $t("settings.interface") }}</el-divider >
24+
25+ <div class =" config-item flex-x-between" >
26+ <span class =" text-xs" >{{ $t("settings.themeColor") }}</span >
27+ <el-color-picker
28+ v-model =" selectedThemeColor"
29+ :predefine =" colorPresets"
30+ popper-class =" theme-picker-dropdown"
31+ />
32+ </div >
33+
34+ <div class =" config-item flex-x-between" >
35+ <span class =" text-xs" >{{ $t("settings.tagsView") }}</span >
36+ <el-switch v-model =" settingsStore.tagsView" />
37+ </div >
38+
39+ <div class =" config-item flex-x-between" >
40+ <span class =" text-xs" >{{ $t("settings.sidebarLogo") }}</span >
41+ <el-switch v-model =" settingsStore.sidebarLogo" />
42+ </div >
43+
44+ <div class =" config-item flex-x-between" >
45+ <span class =" text-xs" >{{ $t("settings.watermark") }}</span >
46+ <el-switch v-model =" settingsStore.watermarkEnabled" />
47+ </div >
48+ <div v-if =" !isDark" class =" config-item flex-x-between" >
49+ <span class =" text-xs" >{{ $t("settings.sidebarColorScheme") }}</span >
50+ <el-radio-group v-model =" sidebarColor" @change =" changeSidebarColor" >
51+ <el-radio :value =" SidebarColorEnum.CLASSIC_BLUE" >
52+ {{ $t("settings.classicBlue") }}
53+ </el-radio >
54+ <el-radio :value =" SidebarColorEnum.MINIMAL_WHITE" >
55+ {{ $t("settings.minimalWhite") }}
56+ </el-radio >
57+ </el-radio-group >
58+ </div >
59+ </section >
60+
61+ <!-- 布局设置 -->
62+ <section class =" config-section" >
63+ <el-divider >{{ $t("settings.navigation") }}</el-divider >
64+ <LayoutSelect v-model =" settingsStore.layout" @update:model-value =" handleLayoutChange" />
65+ </section >
4366 </el-drawer >
4467</template >
4568
@@ -48,6 +71,18 @@ import { LayoutEnum } from "@/enums/LayoutEnum";
4871import { ThemeEnum } from " @/enums/ThemeEnum" ;
4972import { SidebarColorEnum } from " @/enums/ThemeEnum" ;
5073import { useSettingsStore , usePermissionStore , useAppStore } from " @/store" ;
74+ // 颜色预设
75+ const colorPresets = [
76+ " #4080FF" ,
77+ " #ff4500" ,
78+ " #ff8c00" ,
79+ " #90ee90" ,
80+ " #00ced1" ,
81+ " #1e90ff" ,
82+ " #c71585" ,
83+ " rgb(255, 120, 0)" ,
84+ " hsva(120, 40, 94)" ,
85+ ];
5186
5287const route = useRoute ();
5388const appStore = useAppStore ();
@@ -57,32 +92,23 @@ const permissionStore = usePermissionStore();
5792const isDark = ref <boolean >(settingsStore .theme === ThemeEnum .DARK );
5893const sidebarColor = ref (settingsStore .sidebarColorScheme );
5994
60- const settingsVisible = computed ({
61- get() {
62- return settingsStore .settingsVisible ;
63- },
64- set() {
65- settingsStore .settingsVisible = false ;
66- },
95+ const selectedThemeColor = computed ({
96+ get : () => settingsStore .themeColor ,
97+ set : (value ) => settingsStore .changeThemeColor (value ),
6798});
6899
69- /**
70- * 切换主题颜色
71- *
72- * @param color 颜色
73- */
74- function changeThemeColor(color : string ) {
75- settingsStore .changeThemeColor (color );
76- }
100+ const drawerVisible = computed ({
101+ get : () => settingsStore .settingsVisible ,
102+ set : (value ) => (settingsStore .settingsVisible = value ),
103+ });
77104
78105/**
79- * 切换主题
106+ * 处理主题切换
80107 *
81- * @param val 是否为暗黑模式
108+ * @param isDark 是否启用暗黑模式
82109 */
83- const changeTheme = (val : any ) => {
84- isDark .value = val ;
85- settingsStore .changeTheme (isDark .value ? ThemeEnum .DARK : ThemeEnum .LIGHT );
110+ const handleThemeChange = (isDark : string | number | boolean ) => {
111+ settingsStore .changeTheme (isDark ? ThemeEnum .DARK : ThemeEnum .LIGHT );
86112};
87113
88114/**
@@ -97,34 +123,25 @@ const changeSidebarColor = (val: any) => {
97123/**
98124 * 切换布局
99125 *
100- * @param layout 布局 LayoutEnum
126+ * @param layout - 布局模式
101127 */
102- function changeLayout (layout : LayoutEnum ) {
128+ const handleLayoutChange = (layout : LayoutEnum ) => {
103129 settingsStore .changeLayout (layout );
104- if (layout === LayoutEnum .MIX ) {
105- route .name && againActiveTop (route .name as string );
106- }
107- }
108-
109- /**
110- * 重新激活顶部菜单
111- *
112- * @param routeName 路由名称
113- */
114- function againActiveTop(routeName : string ) {
115- const parent = findOutermostParent (permissionStore .routes , routeName );
116- if (appStore .activeTopMenuPath !== parent .path ) {
117- appStore .activeTopMenu (parent .path );
130+ if (layout === LayoutEnum .MIX && route .name ) {
131+ const topLevelRoute = findTopLevelRoute (permissionStore .routes , route .name as string );
132+ if (appStore .activeTopMenuPath !== topLevelRoute .path ) {
133+ appStore .activeTopMenu (topLevelRoute .path );
134+ }
118135 }
119- }
136+ };
120137
121138/**
122- * 查找最外层父级
139+ * 查找路由的顶层父路由
123140 *
124141 * @param tree 树形数据
125142 * @param findName 查找的名称
126143 */
127- function findOutermostParent (tree : any [], findName : string ) {
144+ function findTopLevelRoute (tree : any [], findName : string ) {
128145 let parentMap: any = {};
129146
130147 function buildParentMap(node : any , parent : any ) {
@@ -148,9 +165,28 @@ function findOutermostParent(tree: any[], findName: string) {
148165 }
149166 currentNode = parentMap [currentNode .name ];
150167 }
151-
152168 return null ;
153169}
170+
171+ /**
172+ * 关闭抽屉前的回调
173+ */
174+ const handleCloseDrawer = () => {
175+ settingsStore .settingsVisible = false ;
176+ };
154177 </script >
155178
156- <style lang="scss" scoped></style >
179+ <style lang="scss" scoped>
180+ .config-section {
181+ margin-bottom : 24px ;
182+
183+ .config-item {
184+ padding : 12px 0 ;
185+ border-bottom : 1px solid var (--el-border-color-light );
186+
187+ & :last-child {
188+ border-bottom : none ;
189+ }
190+ }
191+ }
192+ </style >
0 commit comments