Commit 4ff6b73c2bb57764db2bcd8212d82f028e25e36d

Authored by vben
1 parent 5832ee66

perf: optimize settingDrawer code

CHANGELOG.zh_CN.md
@@ -4,6 +4,10 @@ @@ -4,6 +4,10 @@
4 4
5 - 表单项的`componentsProps`支持函数类型 5 - 表单项的`componentsProps`支持函数类型
6 6
  7 +### ⚡ Performance Improvements
  8 +
  9 +- 优化 settingDrawer 代码
  10 +
7 ### 🐛 Bug Fixes 11 ### 🐛 Bug Fixes
8 12
9 - 修复多个富文本编辑器只显示一个 13 - 修复多个富文本编辑器只显示一个
index.html
@@ -30,8 +30,7 @@ @@ -30,8 +30,7 @@
30 .app-loading { 30 .app-loading {
31 width: 100%; 31 width: 100%;
32 height: 100%; 32 height: 100%;
33 -  
34 - /* background: #f0f2f5; */ 33 + background: #f0f2f5;
35 } 34 }
36 35
37 .app-loading .app-loading-wrap { 36 .app-loading .app-loading-wrap {
mock/demo/table-demo.ts
@@ -11,7 +11,7 @@ const demoList = (() => { @@ -11,7 +11,7 @@ const demoList = (() => {
11 address: '@city()', 11 address: '@city()',
12 name: '@cname()', 12 name: '@cname()',
13 'no|100000-10000000': 100000, 13 'no|100000-10000000': 100000,
14 - 'status|1': ['正常', '启用', '停用'], 14 + 'status|1': ['normal', 'enable', 'disable'],
15 }); 15 });
16 } 16 }
17 return result; 17 return result;
src/api/demo/error.ts
1 import { defHttp } from '/@/utils/http/axios'; 1 import { defHttp } from '/@/utils/http/axios';
2 2
3 enum Api { 3 enum Api {
4 - // 该地址不存在 4 + // The address does not exist
5 Error = '/error', 5 Error = '/error',
6 } 6 }
7 7
8 /** 8 /**
9 - * @description: 触发ajax错误 9 + * @description: Trigger ajax error
10 */ 10 */
11 export function fireErrorApi() { 11 export function fireErrorApi() {
12 return defHttp.request({ 12 return defHttp.request({
src/api/demo/model/tableModel.ts
1 import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; 1 import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
2 /** 2 /**
3 - * @description: 请求列表接口参数 3 + * @description: Request list interface parameters
4 */ 4 */
5 export type DemoParams = BasicPageParams; 5 export type DemoParams = BasicPageParams;
6 6
@@ -15,6 +15,6 @@ export interface DemoListItem { @@ -15,6 +15,6 @@ export interface DemoListItem {
15 } 15 }
16 16
17 /** 17 /**
18 - * @description: 请求列表返回值 18 + * @description: Request list return value
19 */ 19 */
20 export type DemoListGetResultModel = BasicFetchResult<DemoListItem>; 20 export type DemoListGetResultModel = BasicFetchResult<DemoListItem>;
src/api/demo/table.ts
@@ -6,7 +6,7 @@ enum Api { @@ -6,7 +6,7 @@ enum Api {
6 } 6 }
7 7
8 /** 8 /**
9 - * @description: 获取示例列表值 9 + * @description: Get sample list value
10 */ 10 */
11 export function demoListApi(params: DemoParams) { 11 export function demoListApi(params: DemoParams) {
12 return defHttp.request<DemoListGetResultModel>({ 12 return defHttp.request<DemoListGetResultModel>({
src/components/Form/src/types/index.ts
@@ -89,7 +89,6 @@ export type ComponentType = @@ -89,7 +89,6 @@ export type ComponentType =
89 | 'InputNumber' 89 | 'InputNumber'
90 | 'InputCountDown' 90 | 'InputCountDown'
91 | 'Select' 91 | 'Select'
92 - | 'DictSelect'  
93 | 'SelectOptGroup' 92 | 'SelectOptGroup'
94 | 'SelectOption' 93 | 'SelectOption'
95 | 'TreeSelect' 94 | 'TreeSelect'
src/components/Menu/src/BasicMenu.tsx
@@ -52,7 +52,8 @@ export default defineComponent({ @@ -52,7 +52,8 @@ export default defineComponent({
52 toRef(props, 'items'), 52 toRef(props, 'items'),
53 toRef(props, 'flatItems'), 53 toRef(props, 'flatItems'),
54 toRef(props, 'isAppMenu'), 54 toRef(props, 'isAppMenu'),
55 - toRef(props, 'mode') 55 + toRef(props, 'mode'),
  56 + toRef(props, 'accordion')
56 ); 57 );
57 58
58 const getOpenKeys = computed(() => { 59 const getOpenKeys = computed(() => {
src/components/Menu/src/props.ts
@@ -58,6 +58,10 @@ export const basicProps = { @@ -58,6 +58,10 @@ export const basicProps = {
58 type: Boolean as PropType<boolean>, 58 type: Boolean as PropType<boolean>,
59 default: false, 59 default: false,
60 }, 60 },
  61 + accordion: {
  62 + type: Boolean as PropType<boolean>,
  63 + default: true,
  64 + },
61 beforeClickFn: { 65 beforeClickFn: {
62 type: Function as PropType<Fn>, 66 type: Function as PropType<Fn>,
63 default: null, 67 default: null,
src/components/Menu/src/useOpenKeys.ts
@@ -6,21 +6,31 @@ import type { Ref } from &#39;vue&#39;; @@ -6,21 +6,31 @@ import type { Ref } from &#39;vue&#39;;
6 import { unref } from 'vue'; 6 import { unref } from 'vue';
7 import { menuStore } from '/@/store/modules/menu'; 7 import { menuStore } from '/@/store/modules/menu';
8 import { getAllParentPath } from '/@/utils/helper/menuHelper'; 8 import { getAllParentPath } from '/@/utils/helper/menuHelper';
  9 +import { es6Unique } from '/@/utils';
9 10
10 export function useOpenKeys( 11 export function useOpenKeys(
11 menuState: MenuState, 12 menuState: MenuState,
12 menus: Ref<MenuType[]>, 13 menus: Ref<MenuType[]>,
13 flatMenusRef: Ref<MenuType[]>, 14 flatMenusRef: Ref<MenuType[]>,
14 isAppMenu: Ref<boolean>, 15 isAppMenu: Ref<boolean>,
15 - mode: Ref<MenuModeEnum> 16 + mode: Ref<MenuModeEnum>,
  17 + accordion: Ref<boolean>
16 ) { 18 ) {
17 /** 19 /**
18 * @description:设置展开 20 * @description:设置展开
19 */ 21 */
20 function setOpenKeys(menu: MenuType) { 22 function setOpenKeys(menu: MenuType) {
21 const flatMenus = unref(flatMenusRef); 23 const flatMenus = unref(flatMenusRef);
22 - menuState.openKeys = getAllParentPath(flatMenus, menu.path); 24 + if (!unref(accordion)) {
  25 + menuState.openKeys = es6Unique([
  26 + ...menuState.openKeys,
  27 + ...getAllParentPath(flatMenus, menu.path),
  28 + ]);
  29 + } else {
  30 + menuState.openKeys = getAllParentPath(flatMenus, menu.path);
  31 + }
23 } 32 }
  33 +
24 /** 34 /**
25 * @description: 重置值 35 * @description: 重置值
26 */ 36 */
@@ -30,7 +40,7 @@ export function useOpenKeys( @@ -30,7 +40,7 @@ export function useOpenKeys(
30 } 40 }
31 41
32 function handleOpenChange(openKeys: string[]) { 42 function handleOpenChange(openKeys: string[]) {
33 - if (unref(mode) === MenuModeEnum.HORIZONTAL) { 43 + if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion)) {
34 menuState.openKeys = openKeys; 44 menuState.openKeys = openKeys;
35 } else { 45 } else {
36 const rootSubMenuKeys: string[] = []; 46 const rootSubMenuKeys: string[] = [];
src/layouts/default/LayoutContent.tsx
@@ -2,11 +2,8 @@ import { defineComponent } from &#39;vue&#39;; @@ -2,11 +2,8 @@ import { defineComponent } from &#39;vue&#39;;
2 import { Layout } from 'ant-design-vue'; 2 import { Layout } from 'ant-design-vue';
3 import { RouterView } from 'vue-router'; 3 import { RouterView } from 'vue-router';
4 4
5 -// hooks  
6 -  
7 import { ContentEnum } from '/@/enums/appEnum'; 5 import { ContentEnum } from '/@/enums/appEnum';
8 import { appStore } from '/@/store/modules/app'; 6 import { appStore } from '/@/store/modules/app';
9 -// import PageLayout from '/@/layouts/page/index';  
10 export default defineComponent({ 7 export default defineComponent({
11 name: 'DefaultLayoutContent', 8 name: 'DefaultLayoutContent',
12 setup() { 9 setup() {
@@ -17,7 +14,6 @@ export default defineComponent({ @@ -17,7 +14,6 @@ export default defineComponent({
17 return ( 14 return (
18 <Layout.Content class={`layout-content ${wrapClass} `}> 15 <Layout.Content class={`layout-content ${wrapClass} `}>
19 {() => <RouterView />} 16 {() => <RouterView />}
20 - {/* <PageLayout class={`layout-content ${wrapClass} `} /> */}  
21 </Layout.Content> 17 </Layout.Content>
22 ); 18 );
23 }; 19 };
src/layouts/default/LayoutMenu.tsx
@@ -55,27 +55,25 @@ export default defineComponent({ @@ -55,27 +55,25 @@ export default defineComponent({
55 }, 55 },
56 }, 56 },
57 setup(props) { 57 setup(props) {
  58 + // Menu array
58 const menusRef = ref<Menu[]>([]); 59 const menusRef = ref<Menu[]>([]);
  60 + // flat menu array
59 const flatMenusRef = ref<Menu[]>([]); 61 const flatMenusRef = ref<Menu[]>([]);
60 const { currentRoute, push } = useRouter(); 62 const { currentRoute, push } = useRouter();
61 - // const { addTab } = useTabs();  
62 63
  64 + // get app config
63 const getProjectConfigRef = computed(() => { 65 const getProjectConfigRef = computed(() => {
64 return appStore.getProjectConfig; 66 return appStore.getProjectConfig;
65 }); 67 });
66 68
  69 + // get is Horizontal
67 const getIsHorizontalRef = computed(() => { 70 const getIsHorizontalRef = computed(() => {
68 return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL; 71 return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
69 }); 72 });
70 73
71 const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50); 74 const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
72 75
73 - // watch(  
74 - // () => menuStore.getCurrentTopSplitMenuPathState,  
75 - // async (parentPath: string) => {  
76 - // throttleHandleSplitLeftMenu(parentPath);  
77 - // }  
78 - // ); 76 + // Route change split menu
79 watch( 77 watch(
80 [() => unref(currentRoute).path, () => props.splitType], 78 [() => unref(currentRoute).path, () => props.splitType],
81 async ([path, splitType]: [string, MenuSplitTyeEnum]) => { 79 async ([path, splitType]: [string, MenuSplitTyeEnum]) => {
@@ -88,23 +86,26 @@ export default defineComponent({ @@ -88,23 +86,26 @@ export default defineComponent({
88 } 86 }
89 ); 87 );
90 88
  89 + // Menu changes
91 watch( 90 watch(
92 - [() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState], 91 + [() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState],
93 () => { 92 () => {
94 genMenus(); 93 genMenus();
95 } 94 }
96 ); 95 );
97 96
  97 + // split Menu changes
98 watch([() => appStore.getProjectConfig.menuSetting.split], () => { 98 watch([() => appStore.getProjectConfig.menuSetting.split], () => {
99 if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return; 99 if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return;
100 genMenus(); 100 genMenus();
101 }); 101 });
102 102
  103 + // Handle left menu split
103 async function handleSplitLeftMenu(parentPath: string) { 104 async function handleSplitLeftMenu(parentPath: string) {
104 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split; 105 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
105 if (!isSplitMenu) return; 106 if (!isSplitMenu) return;
106 const { splitType } = props; 107 const { splitType } = props;
107 - // 菜单分割模式-left 108 + // spilt mode left
108 if (splitType === MenuSplitTyeEnum.LEFT) { 109 if (splitType === MenuSplitTyeEnum.LEFT) {
109 const children = await getChildrenMenus(parentPath); 110 const children = await getChildrenMenus(parentPath);
110 if (!children) { 111 if (!children) {
@@ -128,11 +129,11 @@ export default defineComponent({ @@ -128,11 +129,11 @@ export default defineComponent({
128 } 129 }
129 } 130 }
130 131
  132 + // get menus
131 async function genMenus() { 133 async function genMenus() {
132 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split; 134 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
133 135
134 - // 普通模式  
135 - 136 + // normal mode
136 const { splitType } = props; 137 const { splitType } = props;
137 if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) { 138 if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) {
138 flatMenusRef.value = await getFlatMenus(); 139 flatMenusRef.value = await getFlatMenus();
@@ -140,7 +141,7 @@ export default defineComponent({ @@ -140,7 +141,7 @@ export default defineComponent({
140 return; 141 return;
141 } 142 }
142 143
143 - // 菜单分割模式-top 144 + // split-top
144 if (splitType === MenuSplitTyeEnum.TOP) { 145 if (splitType === MenuSplitTyeEnum.TOP) {
145 const parentPath = await getCurrentParentPath(unref(currentRoute).path); 146 const parentPath = await getCurrentParentPath(unref(currentRoute).path);
146 menuStore.commitCurrentTopSplitMenuPathState(parentPath); 147 menuStore.commitCurrentTopSplitMenuPathState(parentPath);
@@ -156,12 +157,11 @@ export default defineComponent({ @@ -156,12 +157,11 @@ export default defineComponent({
156 const { path } = menu; 157 const { path } = menu;
157 if (path) { 158 if (path) {
158 const { splitType } = props; 159 const { splitType } = props;
159 - // 菜单分割模式-top 160 + // split mode top
160 if (splitType === MenuSplitTyeEnum.TOP) { 161 if (splitType === MenuSplitTyeEnum.TOP) {
161 menuStore.commitCurrentTopSplitMenuPathState(path); 162 menuStore.commitCurrentTopSplitMenuPathState(path);
162 } 163 }
163 push(path); 164 push(path);
164 - // addTab(path as PageEnum, true);  
165 } 165 }
166 } 166 }
167 167
@@ -205,6 +205,7 @@ export default defineComponent({ @@ -205,6 +205,7 @@ export default defineComponent({
205 collapsed, 205 collapsed,
206 collapsedShowTitle, 206 collapsedShowTitle,
207 collapsedShowSearch, 207 collapsedShowSearch,
  208 + accordion,
208 }, 209 },
209 } = unref(getProjectConfigRef); 210 } = unref(getProjectConfigRef);
210 211
@@ -227,6 +228,7 @@ export default defineComponent({ @@ -227,6 +228,7 @@ export default defineComponent({
227 onClickSearchInput={handleClickSearchInput} 228 onClickSearchInput={handleClickSearchInput}
228 appendClass={props.splitType === MenuSplitTyeEnum.TOP} 229 appendClass={props.splitType === MenuSplitTyeEnum.TOP}
229 isTop={props.isTop} 230 isTop={props.isTop}
  231 + accordion={accordion}
230 > 232 >
231 {{ 233 {{
232 header: () => 234 header: () =>
src/layouts/default/LayoutSideBar.tsx
@@ -4,9 +4,6 @@ import { Layout } from &#39;ant-design-vue&#39;; @@ -4,9 +4,6 @@ import { Layout } from &#39;ant-design-vue&#39;;
4 import LayoutTrigger from './LayoutTrigger'; 4 import LayoutTrigger from './LayoutTrigger';
5 import { menuStore } from '/@/store/modules/menu'; 5 import { menuStore } from '/@/store/modules/menu';
6 6
7 -// import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';  
8 -// import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';  
9 -// import lightImg from '/@/assets/images/sidebar/light.png';  
10 import { appStore } from '/@/store/modules/app'; 7 import { appStore } from '/@/store/modules/app';
11 import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum'; 8 import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
12 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; 9 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
@@ -44,7 +41,7 @@ export default defineComponent({ @@ -44,7 +41,7 @@ export default defineComponent({
44 initRef.value = true; 41 initRef.value = true;
45 } 42 }
46 43
47 - // 菜单区域拖拽 - 鼠标移动 44 + // Menu area drag and drop-mouse movement
48 function handleMouseMove(ele: any, wrap: any, clientX: number) { 45 function handleMouseMove(ele: any, wrap: any, clientX: number) {
49 document.onmousemove = function (innerE) { 46 document.onmousemove = function (innerE) {
50 let iT = ele.left + ((innerE || event).clientX - clientX); 47 let iT = ele.left + ((innerE || event).clientX - clientX);
@@ -98,7 +95,6 @@ export default defineComponent({ @@ -98,7 +95,6 @@ export default defineComponent({
98 const side = unref(sideRef); 95 const side = unref(sideRef);
99 96
100 const wrap = (side || {}).$el; 97 const wrap = (side || {}).$el;
101 - // const eleWidth = 6;  
102 ele && 98 ele &&
103 (ele.onmousedown = (e: any) => { 99 (ele.onmousedown = (e: any) => {
104 menuStore.commitDragStartState(true); 100 menuStore.commitDragStartState(true);
src/layouts/default/index.tsx
@@ -19,12 +19,11 @@ import &#39;./index.less&#39;; @@ -19,12 +19,11 @@ import &#39;./index.less&#39;;
19 export default defineComponent({ 19 export default defineComponent({
20 name: 'DefaultLayout', 20 name: 'DefaultLayout',
21 setup() { 21 setup() {
22 - // ! 在这里才注册全局组件  
23 - // ! 可以减少首屏代码体积  
24 - // default layout是在登录后才加载的。所以不会打包到首屏去 22 + // ! Only register global components here
  23 + // ! Can reduce the size of the first screen code
  24 + // default layout It is loaded after login. So it won’t be packaged to the first screen
25 registerGlobComp(); 25 registerGlobComp();
26 26
27 - // 获取项目配置  
28 const { getFullContent } = useFullContent(); 27 const { getFullContent } = useFullContent();
29 28
30 const getProjectConfigRef = computed(() => { 29 const getProjectConfigRef = computed(() => {
@@ -56,8 +55,6 @@ export default defineComponent({ @@ -56,8 +55,6 @@ export default defineComponent({
56 return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent)); 55 return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent));
57 }); 56 });
58 57
59 - // Get project configuration  
60 - // const { getFullContent } = useFullContent(currentRoute);  
61 function getTarget(): any { 58 function getTarget(): any {
62 const { 59 const {
63 headerSetting: { fixed }, 60 headerSetting: { fixed },
src/layouts/default/setting/SettingDrawer.tsx
@@ -2,14 +2,7 @@ import { defineComponent, computed, unref, ref } from &#39;vue&#39;; @@ -2,14 +2,7 @@ import { defineComponent, computed, unref, ref } from &#39;vue&#39;;
2 import { BasicDrawer } from '/@/components/Drawer/index'; 2 import { BasicDrawer } from '/@/components/Drawer/index';
3 import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue'; 3 import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
4 import Button from '/@/components/Button/index.vue'; 4 import Button from '/@/components/Button/index.vue';
5 -import {  
6 - MenuModeEnum,  
7 - MenuTypeEnum,  
8 - MenuThemeEnum,  
9 - TopMenuAlignEnum,  
10 - TriggerEnum,  
11 -} from '/@/enums/menuEnum';  
12 -import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum'; 5 +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
13 import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue'; 6 import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
14 import { appStore } from '/@/store/modules/app'; 7 import { appStore } from '/@/store/modules/app';
15 import { userStore } from '/@/store/modules/user'; 8 import { userStore } from '/@/store/modules/user';
@@ -24,70 +17,15 @@ import mixImg from &#39;/@/assets/images/layout/menu-mix.svg&#39;; @@ -24,70 +17,15 @@ import mixImg from &#39;/@/assets/images/layout/menu-mix.svg&#39;;
24 import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg'; 17 import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg';
25 import menuTopImg from '/@/assets/images/layout/menu-top.svg'; 18 import menuTopImg from '/@/assets/images/layout/menu-top.svg';
26 import { updateColorWeak, updateGrayMode } from '/@/setup/theme'; 19 import { updateColorWeak, updateGrayMode } from '/@/setup/theme';
27 -  
28 -const themeOptions = [  
29 - {  
30 - value: MenuThemeEnum.LIGHT,  
31 - label: '亮色',  
32 - },  
33 - {  
34 - value: MenuThemeEnum.DARK,  
35 - label: '暗色',  
36 - },  
37 -];  
38 -const contentModeOptions = [  
39 - {  
40 - value: ContentEnum.FULL,  
41 - label: '流式',  
42 - },  
43 - {  
44 - value: ContentEnum.FIXED,  
45 - label: '定宽',  
46 - },  
47 -];  
48 -const topMenuAlignOptions = [  
49 - {  
50 - value: TopMenuAlignEnum.CENTER,  
51 - label: '居中',  
52 - },  
53 - {  
54 - value: TopMenuAlignEnum.START,  
55 - label: '居左',  
56 - },  
57 - {  
58 - value: TopMenuAlignEnum.END,  
59 - label: '居右',  
60 - },  
61 -];  
62 -  
63 -const menuTriggerOptions = [  
64 - {  
65 - value: TriggerEnum.NONE,  
66 - label: '不显示',  
67 - },  
68 - {  
69 - value: TriggerEnum.FOOTER,  
70 - label: '底部',  
71 - },  
72 - {  
73 - value: TriggerEnum.HEADER,  
74 - label: '顶部',  
75 - },  
76 -];  
77 -  
78 -const routerTransitionOptions = [  
79 - RouterTransitionEnum.ZOOM_FADE,  
80 - RouterTransitionEnum.FADE,  
81 - RouterTransitionEnum.ZOOM_OUT,  
82 - RouterTransitionEnum.FADE_SIDE,  
83 - RouterTransitionEnum.FADE_BOTTOM,  
84 -].map((item) => {  
85 - return {  
86 - label: item,  
87 - value: item,  
88 - key: item,  
89 - };  
90 -}); 20 +import { baseHandler } from './handler';
  21 +import {
  22 + HandlerEnum,
  23 + themeOptions,
  24 + contentModeOptions,
  25 + topMenuAlignOptions,
  26 + menuTriggerOptions,
  27 + routerTransitionOptions,
  28 +} from './const';
91 29
92 interface SwitchOptions { 30 interface SwitchOptions {
93 config?: DeepPartial<ProjectConfig>; 31 config?: DeepPartial<ProjectConfig>;
@@ -139,6 +77,25 @@ export default defineComponent({ @@ -139,6 +77,25 @@ export default defineComponent({
139 }); 77 });
140 } 78 }
141 79
  80 + function handleResetSetting() {
  81 + try {
  82 + appStore.commitProjectConfigState(defaultSetting);
  83 + const { colorWeak, grayMode } = defaultSetting;
  84 + // updateTheme(themeColor);
  85 + updateColorWeak(colorWeak);
  86 + updateGrayMode(grayMode);
  87 + createMessage.success('重置成功!');
  88 + } catch (error) {
  89 + createMessage.error(error);
  90 + }
  91 + }
  92 +
  93 + function handleClearAndRedo() {
  94 + localStorage.clear();
  95 + userStore.resumeAllState();
  96 + location.reload();
  97 + }
  98 +
142 function renderSidebar() { 99 function renderSidebar() {
143 const { 100 const {
144 headerSetting: { theme: headerTheme }, 101 headerSetting: { theme: headerTheme },
@@ -175,7 +132,7 @@ export default defineComponent({ @@ -175,7 +132,7 @@ export default defineComponent({
175 {{ 132 {{
176 default: () => ( 133 default: () => (
177 <div 134 <div
178 - onClick={baseHandler.bind(null, 'layout', { 135 + onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
179 mode: mode, 136 mode: mode,
180 type: ItemType, 137 type: ItemType,
181 split: unref(getIsHorizontalRef) ? false : undefined, 138 split: unref(getIsHorizontalRef) ? false : undefined,
@@ -192,14 +149,14 @@ export default defineComponent({ @@ -192,14 +149,14 @@ export default defineComponent({
192 </div>, 149 </div>,
193 renderSwitchItem('分割菜单', { 150 renderSwitchItem('分割菜单', {
194 handler: (e) => { 151 handler: (e) => {
195 - baseHandler('splitMenu', e); 152 + baseHandler(HandlerEnum.MENU_SPLIT, e);
196 }, 153 },
197 def: split, 154 def: split,
198 disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX, 155 disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
199 }), 156 }),
200 renderSelectItem('顶栏主题', { 157 renderSelectItem('顶栏主题', {
201 handler: (e) => { 158 handler: (e) => {
202 - baseHandler('headerMenu', e); 159 + baseHandler(HandlerEnum.HEADER_THEME, e);
203 }, 160 },
204 def: headerTheme, 161 def: headerTheme,
205 options: themeOptions, 162 options: themeOptions,
@@ -207,7 +164,7 @@ export default defineComponent({ @@ -207,7 +164,7 @@ export default defineComponent({
207 }), 164 }),
208 renderSelectItem('菜单主题', { 165 renderSelectItem('菜单主题', {
209 handler: (e) => { 166 handler: (e) => {
210 - baseHandler('menuTheme', e); 167 + baseHandler(HandlerEnum.MENU_THEME, e);
211 }, 168 },
212 def: menuTheme, 169 def: menuTheme,
213 options: themeOptions, 170 options: themeOptions,
@@ -230,48 +187,49 @@ export default defineComponent({ @@ -230,48 +187,49 @@ export default defineComponent({
230 topMenuAlign, 187 topMenuAlign,
231 collapsedShowTitle, 188 collapsedShowTitle,
232 trigger, 189 trigger,
  190 + accordion,
233 } = {}, 191 } = {},
234 } = appStore.getProjectConfig; 192 } = appStore.getProjectConfig;
235 return [ 193 return [
236 renderSwitchItem('侧边菜单拖拽', { 194 renderSwitchItem('侧边菜单拖拽', {
237 handler: (e) => { 195 handler: (e) => {
238 - baseHandler('hasDrag', e); 196 + baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
239 }, 197 },
240 def: hasDrag, 198 def: hasDrag,
241 disabled: !unref(getShowMenuRef), 199 disabled: !unref(getShowMenuRef),
242 }), 200 }),
243 renderSwitchItem('侧边菜单搜索', { 201 renderSwitchItem('侧边菜单搜索', {
244 handler: (e) => { 202 handler: (e) => {
245 - baseHandler('showSearch', e); 203 + baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
246 }, 204 },
247 def: showSearch, 205 def: showSearch,
248 disabled: !unref(getShowMenuRef), 206 disabled: !unref(getShowMenuRef),
249 }), 207 }),
  208 + renderSwitchItem('侧边菜单手风琴模式', {
  209 + handler: (e) => {
  210 + baseHandler(HandlerEnum.MENU_ACCORDION, e);
  211 + },
  212 + def: accordion,
  213 + disabled: !unref(getShowMenuRef),
  214 + }),
250 renderSwitchItem('折叠菜单', { 215 renderSwitchItem('折叠菜单', {
251 handler: (e) => { 216 handler: (e) => {
252 - baseHandler('collapsed', e); 217 + baseHandler(HandlerEnum.MENU_COLLAPSED, e);
253 }, 218 },
254 def: collapsed, 219 def: collapsed,
255 disabled: !unref(getShowMenuRef), 220 disabled: !unref(getShowMenuRef),
256 }), 221 }),
257 renderSwitchItem('折叠菜单显示名称', { 222 renderSwitchItem('折叠菜单显示名称', {
258 handler: (e) => { 223 handler: (e) => {
259 - baseHandler('collapsedShowTitle', e); 224 + baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
260 }, 225 },
261 def: collapsedShowTitle, 226 def: collapsedShowTitle,
262 disabled: !unref(getShowMenuRef) || !collapsed, 227 disabled: !unref(getShowMenuRef) || !collapsed,
263 }), 228 }),
264 229
265 - renderSwitchItem('固定header', {  
266 - handler: (e) => {  
267 - baseHandler('headerFixed', e);  
268 - },  
269 - def: fixed,  
270 - disabled: !unref(getShowHeaderRef),  
271 - }),  
272 renderSelectItem('顶部菜单布局', { 230 renderSelectItem('顶部菜单布局', {
273 handler: (e) => { 231 handler: (e) => {
274 - baseHandler('topMenuAlign', e); 232 + baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
275 }, 233 },
276 def: topMenuAlign, 234 def: topMenuAlign,
277 options: topMenuAlignOptions, 235 options: topMenuAlignOptions,
@@ -279,14 +237,21 @@ export default defineComponent({ @@ -279,14 +237,21 @@ export default defineComponent({
279 }), 237 }),
280 renderSelectItem('菜单折叠按钮', { 238 renderSelectItem('菜单折叠按钮', {
281 handler: (e) => { 239 handler: (e) => {
282 - baseHandler('menuTrigger', e); 240 + baseHandler(HandlerEnum.MENU_TRIGGER, e);
283 }, 241 },
284 def: trigger, 242 def: trigger,
285 options: menuTriggerOptions, 243 options: menuTriggerOptions,
286 }), 244 }),
  245 + renderSwitchItem('固定header', {
  246 + handler: (e) => {
  247 + baseHandler(HandlerEnum.HEADER_FIXED, e);
  248 + },
  249 + def: fixed,
  250 + disabled: !unref(getShowHeaderRef),
  251 + }),
287 renderSelectItem('内容区域宽度', { 252 renderSelectItem('内容区域宽度', {
288 handler: (e) => { 253 handler: (e) => {
289 - baseHandler('contentMode', e); 254 + baseHandler(HandlerEnum.CONTENT_MODE, e);
290 }, 255 },
291 def: contentMode, 256 def: contentMode,
292 options: contentModeOptions, 257 options: contentModeOptions,
@@ -297,8 +262,8 @@ export default defineComponent({ @@ -297,8 +262,8 @@ export default defineComponent({
297 style="width:120px" 262 style="width:120px"
298 size="small" 263 size="small"
299 min={0} 264 min={0}
300 - onChange={(e) => {  
301 - baseHandler('lockTime', e); 265 + onChange={(e: any) => {
  266 + baseHandler(HandlerEnum.LOCK_TIME, e);
302 }} 267 }}
303 defaultValue={appStore.getProjectConfig.lockTime} 268 defaultValue={appStore.getProjectConfig.lockTime}
304 formatter={(value: string) => { 269 formatter={(value: string) => {
@@ -321,7 +286,7 @@ export default defineComponent({ @@ -321,7 +286,7 @@ export default defineComponent({
321 defaultValue={menuWidth} 286 defaultValue={menuWidth}
322 formatter={(value: string) => `${parseInt(value)}px`} 287 formatter={(value: string) => `${parseInt(value)}px`}
323 onChange={(e: any) => { 288 onChange={(e: any) => {
324 - baseHandler('menuWidth', e); 289 + baseHandler(HandlerEnum.MENU_WIDTH, e);
325 }} 290 }}
326 /> 291 />
327 </div>, 292 </div>,
@@ -334,19 +299,19 @@ export default defineComponent({ @@ -334,19 +299,19 @@ export default defineComponent({
334 <> 299 <>
335 {renderSwitchItem('页面切换loading', { 300 {renderSwitchItem('页面切换loading', {
336 handler: (e) => { 301 handler: (e) => {
337 - baseHandler('openPageLoading', e); 302 + baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
338 }, 303 },
339 def: openPageLoading, 304 def: openPageLoading,
340 })} 305 })}
341 {renderSwitchItem('切换动画', { 306 {renderSwitchItem('切换动画', {
342 handler: (e) => { 307 handler: (e) => {
343 - baseHandler('openRouterTransition', e); 308 + baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
344 }, 309 },
345 def: openRouterTransition, 310 def: openRouterTransition,
346 })} 311 })}
347 {renderSelectItem('路由动画', { 312 {renderSelectItem('路由动画', {
348 handler: (e) => { 313 handler: (e) => {
349 - baseHandler('routerTransition', e); 314 + baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
350 }, 315 },
351 def: routerTransition, 316 def: routerTransition,
352 options: routerTransitionOptions, 317 options: routerTransitionOptions,
@@ -370,289 +335,77 @@ export default defineComponent({ @@ -370,289 +335,77 @@ export default defineComponent({
370 return [ 335 return [
371 renderSwitchItem('面包屑', { 336 renderSwitchItem('面包屑', {
372 handler: (e) => { 337 handler: (e) => {
373 - baseHandler('showBreadCrumb', e); 338 + baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
374 }, 339 },
375 def: showBreadCrumb, 340 def: showBreadCrumb,
376 disabled: !unref(getShowHeaderRef), 341 disabled: !unref(getShowHeaderRef),
377 }), 342 }),
378 renderSwitchItem('面包屑图标', { 343 renderSwitchItem('面包屑图标', {
379 handler: (e) => { 344 handler: (e) => {
380 - baseHandler('showBreadCrumbIcon', e); 345 + baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
381 }, 346 },
382 def: showBreadCrumbIcon, 347 def: showBreadCrumbIcon,
383 disabled: !unref(getShowHeaderRef), 348 disabled: !unref(getShowHeaderRef),
384 }), 349 }),
385 renderSwitchItem('标签页', { 350 renderSwitchItem('标签页', {
386 handler: (e) => { 351 handler: (e) => {
387 - baseHandler('showMultiple', e); 352 + baseHandler(HandlerEnum.TABS_SHOW, e);
388 }, 353 },
389 def: showMultiple, 354 def: showMultiple,
390 }), 355 }),
391 renderSwitchItem('标签页快捷按钮', { 356 renderSwitchItem('标签页快捷按钮', {
392 handler: (e) => { 357 handler: (e) => {
393 - baseHandler('showQuick', e); 358 + baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
394 }, 359 },
395 def: showQuick, 360 def: showQuick,
396 disabled: !unref(getShowTabsRef), 361 disabled: !unref(getShowTabsRef),
397 }), 362 }),
398 renderSwitchItem('标签页图标', { 363 renderSwitchItem('标签页图标', {
399 handler: (e) => { 364 handler: (e) => {
400 - baseHandler('showTabIcon', e); 365 + baseHandler(HandlerEnum.TABS_SHOW_ICON, e);
401 }, 366 },
402 def: showTabIcon, 367 def: showTabIcon,
403 disabled: !unref(getShowTabsRef), 368 disabled: !unref(getShowTabsRef),
404 }), 369 }),
405 renderSwitchItem('左侧菜单', { 370 renderSwitchItem('左侧菜单', {
406 handler: (e) => { 371 handler: (e) => {
407 - baseHandler('showSidebar', e); 372 + baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
408 }, 373 },
409 def: showMenu, 374 def: showMenu,
410 disabled: unref(getIsHorizontalRef), 375 disabled: unref(getIsHorizontalRef),
411 }), 376 }),
412 renderSwitchItem('顶栏', { 377 renderSwitchItem('顶栏', {
413 handler: (e) => { 378 handler: (e) => {
414 - baseHandler('showHeader', e); 379 + baseHandler(HandlerEnum.HEADER_SHOW, e);
415 }, 380 },
416 def: showHeader, 381 def: showHeader,
417 }), 382 }),
418 renderSwitchItem('Logo', { 383 renderSwitchItem('Logo', {
419 handler: (e) => { 384 handler: (e) => {
420 - baseHandler('showLogo', e); 385 + baseHandler(HandlerEnum.SHOW_LOGO, e);
421 }, 386 },
422 def: showLogo, 387 def: showLogo,
423 }), 388 }),
424 renderSwitchItem('全屏内容', { 389 renderSwitchItem('全屏内容', {
425 handler: (e) => { 390 handler: (e) => {
426 - baseHandler('fullContent', e); 391 + baseHandler(HandlerEnum.FULL_CONTENT, e);
427 }, 392 },
428 def: fullContent, 393 def: fullContent,
429 }), 394 }),
430 renderSwitchItem('灰色模式', { 395 renderSwitchItem('灰色模式', {
431 handler: (e) => { 396 handler: (e) => {
432 - baseHandler('grayMode', e); 397 + baseHandler(HandlerEnum.GRAY_MODE, e);
433 }, 398 },
434 def: grayMode, 399 def: grayMode,
435 }), 400 }),
436 renderSwitchItem('色弱模式', { 401 renderSwitchItem('色弱模式', {
437 handler: (e) => { 402 handler: (e) => {
438 - baseHandler('colorWeak', e); 403 + baseHandler(HandlerEnum.COLOR_WEAK, e);
439 }, 404 },
440 def: colorWeak, 405 def: colorWeak,
441 }), 406 }),
442 ]; 407 ];
443 } 408 }
444 - function baseHandler(event: string, value: any) {  
445 - let config: DeepPartial<ProjectConfig> = {};  
446 - if (event === 'layout') {  
447 - const { mode, type, split } = value;  
448 - const splitOpt = split === undefined ? { split } : {};  
449 - let headerSetting = {};  
450 - if (type === MenuTypeEnum.TOP_MENU) {  
451 - headerSetting = {  
452 - theme: MenuThemeEnum.DARK,  
453 - };  
454 - }  
455 - config = {  
456 - menuSetting: {  
457 - mode,  
458 - type,  
459 - collapsed: false,  
460 - show: true,  
461 - ...splitOpt,  
462 - },  
463 - headerSetting,  
464 - };  
465 - }  
466 - if (event === 'hasDrag') {  
467 - config = {  
468 - menuSetting: {  
469 - hasDrag: value,  
470 - },  
471 - };  
472 - }  
473 - if (event === 'menuTrigger') {  
474 - config = {  
475 - menuSetting: {  
476 - trigger: value,  
477 - },  
478 - };  
479 - }  
480 - if (event === 'openPageLoading') {  
481 - config = {  
482 - openPageLoading: value,  
483 - };  
484 - }  
485 - if (event === 'topMenuAlign') {  
486 - config = {  
487 - menuSetting: {  
488 - topMenuAlign: value,  
489 - },  
490 - };  
491 - }  
492 - if (event === 'showBreadCrumb') {  
493 - config = {  
494 - showBreadCrumb: value,  
495 - };  
496 - }  
497 - if (event === 'showBreadCrumbIcon') {  
498 - config = {  
499 - showBreadCrumbIcon: value,  
500 - };  
501 - }  
502 - if (event === 'collapsed') {  
503 - config = {  
504 - menuSetting: {  
505 - collapsed: value,  
506 - },  
507 - };  
508 - }  
509 - if (event === 'menuWidth') {  
510 - config = {  
511 - menuSetting: {  
512 - menuWidth: value,  
513 - },  
514 - };  
515 - }  
516 - if (event === 'collapsedShowTitle') {  
517 - config = {  
518 - menuSetting: {  
519 - collapsedShowTitle: value,  
520 - },  
521 - };  
522 - }  
523 - if (event === 'lockTime') {  
524 - config = {  
525 - lockTime: value,  
526 - };  
527 - }  
528 - if (event === 'showQuick') {  
529 - config = {  
530 - multiTabsSetting: {  
531 - showQuick: value,  
532 - },  
533 - };  
534 - }  
535 - if (event === 'showTabIcon') {  
536 - config = {  
537 - multiTabsSetting: {  
538 - showIcon: value,  
539 - },  
540 - };  
541 - }  
542 - if (event === 'contentMode') {  
543 - config = {  
544 - contentMode: value,  
545 - };  
546 - }  
547 - if (event === 'menuTheme') {  
548 - config = {  
549 - menuSetting: {  
550 - theme: value,  
551 - },  
552 - };  
553 - }  
554 - if (event === 'splitMenu') {  
555 - config = {  
556 - menuSetting: {  
557 - split: value,  
558 - },  
559 - };  
560 - }  
561 - if (event === 'showMultiple') {  
562 - config = {  
563 - multiTabsSetting: {  
564 - show: value,  
565 - },  
566 - };  
567 - }  
568 - if (event === 'headerMenu') {  
569 - config = {  
570 - headerSetting: {  
571 - theme: value,  
572 - },  
573 - };  
574 - }  
575 - if (event === 'grayMode') {  
576 - config = {  
577 - grayMode: value,  
578 - };  
579 - updateGrayMode(value);  
580 - }  
581 - if (event === 'colorWeak') {  
582 - config = {  
583 - colorWeak: value,  
584 - };  
585 - updateColorWeak(value);  
586 - }  
587 - if (event === 'showLogo') {  
588 - config = {  
589 - showLogo: value,  
590 - };  
591 - }  
592 - if (event === 'showSearch') {  
593 - config = {  
594 - menuSetting: {  
595 - showSearch: value,  
596 - },  
597 - };  
598 - }  
599 - if (event === 'showSidebar') {  
600 - config = {  
601 - menuSetting: {  
602 - show: value,  
603 - },  
604 - };  
605 - }  
606 - if (event === 'openRouterTransition') {  
607 - config = {  
608 - openRouterTransition: value,  
609 - };  
610 - }  
611 - if (event === 'routerTransition') {  
612 - config = {  
613 - routerTransition: value,  
614 - };  
615 - }  
616 - if (event === 'headerFixed') {  
617 - config = {  
618 - headerSetting: {  
619 - fixed: value,  
620 - },  
621 - };  
622 - }  
623 - if (event === 'fullContent') {  
624 - config = {  
625 - fullContent: value,  
626 - };  
627 - }  
628 - if (event === 'showHeader') {  
629 - config = {  
630 - headerSetting: {  
631 - show: value,  
632 - },  
633 - };  
634 - }  
635 - appStore.commitProjectConfigState(config);  
636 - }  
637 -  
638 - function handleResetSetting() {  
639 - try {  
640 - appStore.commitProjectConfigState(defaultSetting);  
641 - const { colorWeak, grayMode } = defaultSetting;  
642 - // updateTheme(themeColor);  
643 - updateColorWeak(colorWeak);  
644 - updateGrayMode(grayMode);  
645 - createMessage.success('重置成功!');  
646 - } catch (error) {  
647 - createMessage.error(error);  
648 - }  
649 - }  
650 -  
651 - function handleClearAndRedo() {  
652 - localStorage.clear();  
653 - userStore.resumeAllState();  
654 - location.reload();  
655 - }  
656 409
657 function renderSelectItem(text: string, config?: SelectConfig) { 410 function renderSelectItem(text: string, config?: SelectConfig) {
658 const { handler, def, disabled = false, options } = config || {}; 411 const { handler, def, disabled = false, options } = config || {};
@@ -693,6 +446,7 @@ export default defineComponent({ @@ -693,6 +446,7 @@ export default defineComponent({
693 </div> 446 </div>
694 ); 447 );
695 } 448 }
  449 +
696 return () => ( 450 return () => (
697 <BasicDrawer {...attrs} title="项目配置" width={300} wrapClassName="setting-drawer"> 451 <BasicDrawer {...attrs} title="项目配置" width={300} wrapClassName="setting-drawer">
698 {{ 452 {{
src/layouts/default/setting/const.ts 0 → 100644
  1 +import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
  2 +import { MenuThemeEnum, TopMenuAlignEnum, TriggerEnum } from '/@/enums/menuEnum';
  3 +
  4 +export enum HandlerEnum {
  5 + CHANGE_LAYOUT,
  6 + // menu
  7 + MENU_HAS_DRAG,
  8 + MENU_ACCORDION,
  9 + MENU_TRIGGER,
  10 + MENU_TOP_ALIGN,
  11 + MENU_COLLAPSED,
  12 + MENU_COLLAPSED_SHOW_TITLE,
  13 + MENU_WIDTH,
  14 + MENU_SHOW_SIDEBAR,
  15 + MENU_THEME,
  16 + MENU_SPLIT,
  17 + MENU_SHOW_SEARCH,
  18 +
  19 + // header
  20 + HEADER_SHOW,
  21 + HEADER_THEME,
  22 + HEADER_FIXED,
  23 +
  24 + TABS_SHOW_QUICK,
  25 + TABS_SHOW,
  26 + TABS_SHOW_ICON,
  27 +
  28 + OPEN_PAGE_LOADING,
  29 + OPEN_ROUTE_TRANSITION,
  30 + ROUTER_TRANSITION,
  31 + LOCK_TIME,
  32 + FULL_CONTENT,
  33 + CONTENT_MODE,
  34 + SHOW_BREADCRUMB,
  35 + SHOW_BREADCRUMB_ICON,
  36 + GRAY_MODE,
  37 + COLOR_WEAK,
  38 + SHOW_LOGO,
  39 +}
  40 +
  41 +export const themeOptions = [
  42 + {
  43 + value: MenuThemeEnum.LIGHT,
  44 + label: '亮色',
  45 + },
  46 + {
  47 + value: MenuThemeEnum.DARK,
  48 + label: '暗色',
  49 + },
  50 +];
  51 +
  52 +export const contentModeOptions = [
  53 + {
  54 + value: ContentEnum.FULL,
  55 + label: '流式',
  56 + },
  57 + {
  58 + value: ContentEnum.FIXED,
  59 + label: '定宽',
  60 + },
  61 +];
  62 +
  63 +export const topMenuAlignOptions = [
  64 + {
  65 + value: TopMenuAlignEnum.CENTER,
  66 + label: '居中',
  67 + },
  68 + {
  69 + value: TopMenuAlignEnum.START,
  70 + label: '居左',
  71 + },
  72 + {
  73 + value: TopMenuAlignEnum.END,
  74 + label: '居右',
  75 + },
  76 +];
  77 +
  78 +export const menuTriggerOptions = [
  79 + {
  80 + value: TriggerEnum.NONE,
  81 + label: '不显示',
  82 + },
  83 + {
  84 + value: TriggerEnum.FOOTER,
  85 + label: '底部',
  86 + },
  87 + {
  88 + value: TriggerEnum.HEADER,
  89 + label: '顶部',
  90 + },
  91 +];
  92 +
  93 +export const routerTransitionOptions = [
  94 + RouterTransitionEnum.ZOOM_FADE,
  95 + RouterTransitionEnum.FADE,
  96 + RouterTransitionEnum.ZOOM_OUT,
  97 + RouterTransitionEnum.FADE_SIDE,
  98 + RouterTransitionEnum.FADE_BOTTOM,
  99 +].map((item) => {
  100 + return {
  101 + label: item,
  102 + value: item,
  103 + };
  104 +});
src/layouts/default/setting/handler.ts 0 → 100644
  1 +import { HandlerEnum } from './const';
  2 +import { MenuThemeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
  3 +import { updateColorWeak, updateGrayMode } from '/@/setup/theme';
  4 +import { appStore } from '/@/store/modules/app';
  5 +import { ProjectConfig } from '/@/types/config';
  6 +
  7 +export function baseHandler(event: HandlerEnum, value: any) {
  8 + const config = handler(event, value);
  9 + appStore.commitProjectConfigState(config);
  10 +}
  11 +
  12 +export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> {
  13 + switch (event) {
  14 + case HandlerEnum.CHANGE_LAYOUT:
  15 + const { mode, type, split } = value;
  16 + const splitOpt = split === undefined ? { split } : {};
  17 + let headerSetting = {};
  18 + if (type === MenuTypeEnum.TOP_MENU) {
  19 + headerSetting = {
  20 + theme: MenuThemeEnum.DARK,
  21 + };
  22 + }
  23 + return {
  24 + menuSetting: {
  25 + mode,
  26 + type,
  27 + collapsed: false,
  28 + show: true,
  29 + ...splitOpt,
  30 + },
  31 + headerSetting,
  32 + };
  33 +
  34 + case HandlerEnum.MENU_HAS_DRAG:
  35 + return {
  36 + menuSetting: {
  37 + hasDrag: value,
  38 + },
  39 + };
  40 +
  41 + case HandlerEnum.MENU_ACCORDION:
  42 + return {
  43 + menuSetting: {
  44 + accordion: value,
  45 + },
  46 + };
  47 + case HandlerEnum.MENU_TRIGGER:
  48 + return {
  49 + menuSetting: {
  50 + trigger: value,
  51 + },
  52 + };
  53 + case HandlerEnum.MENU_TOP_ALIGN:
  54 + return {
  55 + menuSetting: {
  56 + topMenuAlign: value,
  57 + },
  58 + };
  59 + case HandlerEnum.MENU_COLLAPSED:
  60 + return {
  61 + menuSetting: {
  62 + collapsed: value,
  63 + },
  64 + };
  65 + case HandlerEnum.MENU_WIDTH:
  66 + return {
  67 + menuSetting: {
  68 + menuWidth: value,
  69 + },
  70 + };
  71 + case HandlerEnum.MENU_COLLAPSED_SHOW_TITLE:
  72 + return {
  73 + menuSetting: {
  74 + collapsedShowTitle: value,
  75 + },
  76 + };
  77 + case HandlerEnum.MENU_SHOW_SIDEBAR:
  78 + return {
  79 + menuSetting: {
  80 + show: value,
  81 + },
  82 + };
  83 + case HandlerEnum.MENU_THEME:
  84 + return {
  85 + menuSetting: {
  86 + theme: value,
  87 + },
  88 + };
  89 + case HandlerEnum.MENU_SPLIT:
  90 + return {
  91 + menuSetting: {
  92 + split: value,
  93 + },
  94 + };
  95 + case HandlerEnum.MENU_SHOW_SEARCH:
  96 + return {
  97 + menuSetting: {
  98 + showSearch: value,
  99 + },
  100 + };
  101 + case HandlerEnum.OPEN_PAGE_LOADING:
  102 + return {
  103 + openPageLoading: value,
  104 + };
  105 + case HandlerEnum.OPEN_ROUTE_TRANSITION:
  106 + return {
  107 + openRouterTransition: value,
  108 + };
  109 + case HandlerEnum.ROUTER_TRANSITION:
  110 + return {
  111 + routerTransition: value,
  112 + };
  113 + case HandlerEnum.LOCK_TIME:
  114 + return {
  115 + lockTime: value,
  116 + };
  117 + case HandlerEnum.FULL_CONTENT:
  118 + return {
  119 + fullContent: value,
  120 + };
  121 + case HandlerEnum.CONTENT_MODE:
  122 + return {
  123 + contentMode: value,
  124 + };
  125 + case HandlerEnum.SHOW_BREADCRUMB:
  126 + return {
  127 + showBreadCrumb: value,
  128 + };
  129 + case HandlerEnum.SHOW_BREADCRUMB_ICON:
  130 + return {
  131 + showBreadCrumbIcon: value,
  132 + };
  133 + case HandlerEnum.GRAY_MODE:
  134 + updateGrayMode(value);
  135 + return {
  136 + grayMode: value,
  137 + };
  138 + case HandlerEnum.COLOR_WEAK:
  139 + updateColorWeak(value);
  140 + return {
  141 + colorWeak: value,
  142 + };
  143 + case HandlerEnum.SHOW_LOGO:
  144 + return {
  145 + showLogo: value,
  146 + };
  147 + case HandlerEnum.TABS_SHOW_QUICK:
  148 + return {
  149 + multiTabsSetting: {
  150 + showQuick: value,
  151 + },
  152 + };
  153 + case HandlerEnum.TABS_SHOW_QUICK:
  154 + return {
  155 + multiTabsSetting: {
  156 + showIcon: value,
  157 + },
  158 + };
  159 + case HandlerEnum.TABS_SHOW:
  160 + return {
  161 + multiTabsSetting: {
  162 + show: value,
  163 + },
  164 + };
  165 + case HandlerEnum.HEADER_THEME:
  166 + return {
  167 + headerSetting: {
  168 + theme: value,
  169 + },
  170 + };
  171 + case HandlerEnum.HEADER_FIXED:
  172 + return {
  173 + headerSetting: {
  174 + fixed: value,
  175 + },
  176 + };
  177 + case HandlerEnum.HEADER_SHOW:
  178 + return {
  179 + headerSetting: {
  180 + show: value,
  181 + },
  182 + };
  183 + default:
  184 + return {};
  185 + }
  186 +}
src/settings/projectSetting.ts
@@ -74,6 +74,8 @@ const setting: ProjectConfig = { @@ -74,6 +74,8 @@ const setting: ProjectConfig = {
74 collapsedShowSearch: false, 74 collapsedShowSearch: false,
75 // 折叠触发器的位置 75 // 折叠触发器的位置
76 trigger: TriggerEnum.HEADER, 76 trigger: TriggerEnum.HEADER,
  77 + // 开启手风琴模式,只显示一个菜单
  78 + accordion: true,
77 }, 79 },
78 // 消息配置 80 // 消息配置
79 messageSetting: { 81 messageSetting: {
src/types/config.d.ts
@@ -24,6 +24,7 @@ export interface MenuSetting { @@ -24,6 +24,7 @@ export interface MenuSetting {
24 topMenuAlign: 'start' | 'center' | 'end'; 24 topMenuAlign: 'start' | 'center' | 'end';
25 collapsedShowSearch: boolean; 25 collapsedShowSearch: boolean;
26 trigger: TriggerEnum; 26 trigger: TriggerEnum;
  27 + accordion: boolean;
27 } 28 }
28 29
29 export interface MultiTabsSetting { 30 export interface MultiTabsSetting {
src/types/global.d.ts
@@ -30,12 +30,16 @@ declare type Indexable&lt;T = any&gt; = { @@ -30,12 +30,16 @@ declare type Indexable&lt;T = any&gt; = {
30 30
31 declare type Hash<T> = Indexable<T>; 31 declare type Hash<T> = Indexable<T>;
32 32
  33 +// declare type DeepPartial<T> = {
  34 +// [P in keyof T]?: T[P] extends (infer U)[]
  35 +// ? RecursivePartial<U>[]
  36 +// : T[P] extends object
  37 +// ? RecursivePartial<T[P]>
  38 +// : T[P];
  39 +// };
  40 +
33 declare type DeepPartial<T> = { 41 declare type DeepPartial<T> = {
34 - [P in keyof T]?: T[P] extends (infer U)[]  
35 - ? RecursivePartial<U>[]  
36 - : T[P] extends object  
37 - ? RecursivePartial<T[P]>  
38 - : T[P]; 42 + [P in keyof T]?: DeepPartial<T[P]>;
39 }; 43 };
40 44
41 declare type SelectOptions = { 45 declare type SelectOptions = {
src/useApp.ts
@@ -42,7 +42,7 @@ export function useThemeMode(mode: ThemeModeEnum) { @@ -42,7 +42,7 @@ export function useThemeMode(mode: ThemeModeEnum) {
42 }; 42 };
43 } 43 }
44 44
45 -// 初始化项目配置 45 +// Initial project configuration
46 export function useInitAppConfigStore() { 46 export function useInitAppConfigStore() {
47 let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig; 47 let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig;
48 if (!projCfg) { 48 if (!projCfg) {
@@ -78,12 +78,12 @@ export function useConfigProvider() { @@ -78,12 +78,12 @@ export function useConfigProvider() {
78 }; 78 };
79 } 79 }
80 80
81 -// 初始化网络监听 81 +// Initialize network monitoring
82 export function useListenerNetWork() { 82 export function useListenerNetWork() {
83 const { listenNetWork } = appStore.getProjectConfig; 83 const { listenNetWork } = appStore.getProjectConfig;
84 if (!listenNetWork) return; 84 if (!listenNetWork) return;
85 const { replace } = useRouter(); 85 const { replace } = useRouter();
86 - // 检测网络状态 86 + // Check network status
87 useNetWork({ 87 useNetWork({
88 onLineFn: () => { 88 onLineFn: () => {
89 replace(PageEnum.BASE_HOME); 89 replace(PageEnum.BASE_HOME);
src/views/dashboard/analysis/index.vue
1 <template> 1 <template>
2 <div class="analysis p-4"> 2 <div class="analysis p-4">
3 - <Row class="pl-2"> 3 + <a-row class="pl-2">
4 <template v-for="item in growCardList" :key="item.title"> 4 <template v-for="item in growCardList" :key="item.title">
5 <ACol :sm="24" :md="12" :lg="6"> 5 <ACol :sm="24" :md="12" :lg="6">
6 <GrowCard :info="item" /> 6 <GrowCard :info="item" />
7 </ACol> 7 </ACol>
8 </template> 8 </template>
9 - </Row> 9 + </a-row>
10 10
11 - <Row>  
12 - <ACol :md="24" :lg="17" class="my-3"> 11 + <a-row>
  12 + <a-col :md="24" :lg="17" class="my-3">
13 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false"> 13 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
14 <AnalysisLine /> 14 <AnalysisLine />
15 </CollapseContainer> 15 </CollapseContainer>
16 - <Row class="mt-3">  
17 - <ACol :md="24" :lg="12" class="product-total"> 16 + <a-row class="mt-3">
  17 + <a-col :md="24" :lg="12" class="product-total">
18 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false"> 18 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
19 <AnalysisPie /> 19 <AnalysisPie />
20 </CollapseContainer> 20 </CollapseContainer>
21 - </ACol>  
22 - <ACol :md="24" :lg="12"> 21 + </a-col>
  22 + <a-col :md="24" :lg="12">
23 <CollapseContainer class="mr-3" title="用户来源" :canExpan="false"> 23 <CollapseContainer class="mr-3" title="用户来源" :canExpan="false">
24 <AnalysisBar /> 24 <AnalysisBar />
25 </CollapseContainer> 25 </CollapseContainer>
26 - </ACol>  
27 - </Row>  
28 - </ACol>  
29 - <ACol :md="24" :lg="7"> 26 + </a-col>
  27 + </a-row>
  28 + </a-col>
  29 + <a-col :md="24" :lg="7">
30 <CollapseContainer class="mt-3" title="项目进度" :canExpan="false"> 30 <CollapseContainer class="mt-3" title="项目进度" :canExpan="false">
31 <template v-for="item in taskList" :key="item.title"> 31 <template v-for="item in taskList" :key="item.title">
32 <TaskCard :info="item" /> 32 <TaskCard :info="item" />
33 </template> 33 </template>
34 </CollapseContainer> 34 </CollapseContainer>
35 - </ACol>  
36 - </Row>  
37 - <Row> 35 + </a-col>
  36 + </a-row>
  37 + <a-row>
38 <FlowAnalysis /> 38 <FlowAnalysis />
39 - </Row> 39 + </a-row>
40 </div> 40 </div>
41 </template> 41 </template>
42 <script lang="ts"> 42 <script lang="ts">
@@ -48,14 +48,11 @@ @@ -48,14 +48,11 @@
48 import AnalysisBar from './components/AnalysisBar.vue'; 48 import AnalysisBar from './components/AnalysisBar.vue';
49 import TaskCard from './components/TaskCard.vue'; 49 import TaskCard from './components/TaskCard.vue';
50 import FlowAnalysis from './components/FlowAnalysis'; 50 import FlowAnalysis from './components/FlowAnalysis';
51 - import { Row, Col } from 'ant-design-vue';  
52 import { CollapseContainer } from '/@/components/Container/index'; 51 import { CollapseContainer } from '/@/components/Container/index';
53 52
54 import { growCardList, taskList } from './data'; 53 import { growCardList, taskList } from './data';
55 export default defineComponent({ 54 export default defineComponent({
56 components: { 55 components: {
57 - Row,  
58 - ACol: Col,  
59 GrowCard, 56 GrowCard,
60 CollapseContainer, 57 CollapseContainer,
61 TrendLine, 58 TrendLine,
src/views/dashboard/workbench/index.vue
1 <template> 1 <template>
2 - <Row class="workbench p-4" :gutter="12">  
3 - <Col :md="24" :lg="17"> 2 + <a-row class="workbench p-4" :gutter="12">
  3 + <a-col :md="24" :lg="17">
4 <ProdTotal class="mb-3" /> 4 <ProdTotal class="mb-3" />
5 <TodoList class="mb-3" /> 5 <TodoList class="mb-3" />
6 <NewsList class="mb-3" /> 6 <NewsList class="mb-3" />
7 - </Col>  
8 - <Col :md="24" :lg="7"> 7 + </a-col>
  8 + <a-col :md="24" :lg="7">
9 <img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" /> 9 <img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" />
10 <ShortCuts class="mb-3" /> 10 <ShortCuts class="mb-3" />
11 <Week class="mb-3" /> 11 <Week class="mb-3" />
12 - </Col>  
13 - </Row> 12 + </a-col>
  13 + </a-row>
14 </template> 14 </template>
15 <script lang="ts"> 15 <script lang="ts">
16 import { defineComponent } from 'vue'; 16 import { defineComponent } from 'vue';
17 - import { Row, Col } from 'ant-design-vue';  
18 import ProdTotal from './components/ProdTotal.vue'; 17 import ProdTotal from './components/ProdTotal.vue';
19 import TodoList from './components/TodoList.vue'; 18 import TodoList from './components/TodoList.vue';
20 import Week from './components/Week.vue'; 19 import Week from './components/Week.vue';
@@ -22,7 +21,7 @@ @@ -22,7 +21,7 @@
22 import ShortCuts from './components/ShortCuts.vue'; 21 import ShortCuts from './components/ShortCuts.vue';
23 22
24 export default defineComponent({ 23 export default defineComponent({
25 - components: { Row, Col, ProdTotal, TodoList, Week, ShortCuts, NewsList }, 24 + components: { ProdTotal, TodoList, Week, ShortCuts, NewsList },
26 setup() { 25 setup() {
27 return {}; 26 return {};
28 }, 27 },
src/views/sys/login/Login.vue
@@ -168,7 +168,7 @@ @@ -168,7 +168,7 @@
168 display: none; 168 display: none;
169 height: 100%; 169 height: 100%;
170 background: url(../../../assets/images/login/login-in.png) no-repeat; 170 background: url(../../../assets/images/login/login-in.png) no-repeat;
171 - background-position: 50% 30%; 171 + background-position: 30% 30%;
172 background-size: 80% 80%; 172 background-size: 80% 80%;
173 173
174 .respond-to(xlarge, { display: block;}); 174 .respond-to(xlarge, { display: block;});
@@ -194,9 +194,9 @@ @@ -194,9 +194,9 @@
194 align-items: center; 194 align-items: center;
195 .respond-to(large, { 195 .respond-to(large, {
196 width: 600px; 196 width: 600px;
197 - right: calc(50% - 300px); 197 + right: calc(50% - 270px);
198 }); 198 });
199 - .respond-to(xlarge, { width: 600px; right:0}); 199 + .respond-to(xlarge, { width: 540px; right:0});
200 } 200 }
201 201
202 &__content { 202 &__content {
vite.config.ts
@@ -34,7 +34,7 @@ const viteConfig: UserConfig = { @@ -34,7 +34,7 @@ const viteConfig: UserConfig = {
34 * @default 'index.html' 34 * @default 'index.html'
35 */ 35 */
36 // TODO build error 36 // TODO build error
37 - // entry: './public/index.html', 37 + // entry: 'public/index.html',
38 /** 38 /**
39 * port 39 * port
40 * @default '3000' 40 * @default '3000'