Commit 4ff6b73c2bb57764db2bcd8212d82f028e25e36d

Authored by vben
1 parent 5832ee66

perf: optimize settingDrawer code

CHANGELOG.zh_CN.md
... ... @@ -4,6 +4,10 @@
4 4  
5 5 - 表单项的`componentsProps`支持函数类型
6 6  
  7 +### ⚡ Performance Improvements
  8 +
  9 +- 优化 settingDrawer 代码
  10 +
7 11 ### 🐛 Bug Fixes
8 12  
9 13 - 修复多个富文本编辑器只显示一个
... ...
index.html
... ... @@ -30,8 +30,7 @@
30 30 .app-loading {
31 31 width: 100%;
32 32 height: 100%;
33   -
34   - /* background: #f0f2f5; */
  33 + background: #f0f2f5;
35 34 }
36 35  
37 36 .app-loading .app-loading-wrap {
... ...
mock/demo/table-demo.ts
... ... @@ -11,7 +11,7 @@ const demoList = (() => {
11 11 address: '@city()',
12 12 name: '@cname()',
13 13 'no|100000-10000000': 100000,
14   - 'status|1': ['正常', '启用', '停用'],
  14 + 'status|1': ['normal', 'enable', 'disable'],
15 15 });
16 16 }
17 17 return result;
... ...
src/api/demo/error.ts
1 1 import { defHttp } from '/@/utils/http/axios';
2 2  
3 3 enum Api {
4   - // 该地址不存在
  4 + // The address does not exist
5 5 Error = '/error',
6 6 }
7 7  
8 8 /**
9   - * @description: 触发ajax错误
  9 + * @description: Trigger ajax error
10 10 */
11 11 export function fireErrorApi() {
12 12 return defHttp.request({
... ...
src/api/demo/model/tableModel.ts
1 1 import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
2 2 /**
3   - * @description: 请求列表接口参数
  3 + * @description: Request list interface parameters
4 4 */
5 5 export type DemoParams = BasicPageParams;
6 6  
... ... @@ -15,6 +15,6 @@ export interface DemoListItem {
15 15 }
16 16  
17 17 /**
18   - * @description: 请求列表返回值
  18 + * @description: Request list return value
19 19 */
20 20 export type DemoListGetResultModel = BasicFetchResult<DemoListItem>;
... ...
src/api/demo/table.ts
... ... @@ -6,7 +6,7 @@ enum Api {
6 6 }
7 7  
8 8 /**
9   - * @description: 获取示例列表值
  9 + * @description: Get sample list value
10 10 */
11 11 export function demoListApi(params: DemoParams) {
12 12 return defHttp.request<DemoListGetResultModel>({
... ...
src/components/Form/src/types/index.ts
... ... @@ -89,7 +89,6 @@ export type ComponentType =
89 89 | 'InputNumber'
90 90 | 'InputCountDown'
91 91 | 'Select'
92   - | 'DictSelect'
93 92 | 'SelectOptGroup'
94 93 | 'SelectOption'
95 94 | 'TreeSelect'
... ...
src/components/Menu/src/BasicMenu.tsx
... ... @@ -52,7 +52,8 @@ export default defineComponent({
52 52 toRef(props, 'items'),
53 53 toRef(props, 'flatItems'),
54 54 toRef(props, 'isAppMenu'),
55   - toRef(props, 'mode')
  55 + toRef(props, 'mode'),
  56 + toRef(props, 'accordion')
56 57 );
57 58  
58 59 const getOpenKeys = computed(() => {
... ...
src/components/Menu/src/props.ts
... ... @@ -58,6 +58,10 @@ export const basicProps = {
58 58 type: Boolean as PropType<boolean>,
59 59 default: false,
60 60 },
  61 + accordion: {
  62 + type: Boolean as PropType<boolean>,
  63 + default: true,
  64 + },
61 65 beforeClickFn: {
62 66 type: Function as PropType<Fn>,
63 67 default: null,
... ...
src/components/Menu/src/useOpenKeys.ts
... ... @@ -6,21 +6,31 @@ import type { Ref } from &#39;vue&#39;;
6 6 import { unref } from 'vue';
7 7 import { menuStore } from '/@/store/modules/menu';
8 8 import { getAllParentPath } from '/@/utils/helper/menuHelper';
  9 +import { es6Unique } from '/@/utils';
9 10  
10 11 export function useOpenKeys(
11 12 menuState: MenuState,
12 13 menus: Ref<MenuType[]>,
13 14 flatMenusRef: Ref<MenuType[]>,
14 15 isAppMenu: Ref<boolean>,
15   - mode: Ref<MenuModeEnum>
  16 + mode: Ref<MenuModeEnum>,
  17 + accordion: Ref<boolean>
16 18 ) {
17 19 /**
18 20 * @description:设置展开
19 21 */
20 22 function setOpenKeys(menu: MenuType) {
21 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 35 * @description: 重置值
26 36 */
... ... @@ -30,7 +40,7 @@ export function useOpenKeys(
30 40 }
31 41  
32 42 function handleOpenChange(openKeys: string[]) {
33   - if (unref(mode) === MenuModeEnum.HORIZONTAL) {
  43 + if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion)) {
34 44 menuState.openKeys = openKeys;
35 45 } else {
36 46 const rootSubMenuKeys: string[] = [];
... ...
src/layouts/default/LayoutContent.tsx
... ... @@ -2,11 +2,8 @@ import { defineComponent } from &#39;vue&#39;;
2 2 import { Layout } from 'ant-design-vue';
3 3 import { RouterView } from 'vue-router';
4 4  
5   -// hooks
6   -
7 5 import { ContentEnum } from '/@/enums/appEnum';
8 6 import { appStore } from '/@/store/modules/app';
9   -// import PageLayout from '/@/layouts/page/index';
10 7 export default defineComponent({
11 8 name: 'DefaultLayoutContent',
12 9 setup() {
... ... @@ -17,7 +14,6 @@ export default defineComponent({
17 14 return (
18 15 <Layout.Content class={`layout-content ${wrapClass} `}>
19 16 {() => <RouterView />}
20   - {/* <PageLayout class={`layout-content ${wrapClass} `} /> */}
21 17 </Layout.Content>
22 18 );
23 19 };
... ...
src/layouts/default/LayoutMenu.tsx
... ... @@ -55,27 +55,25 @@ export default defineComponent({
55 55 },
56 56 },
57 57 setup(props) {
  58 + // Menu array
58 59 const menusRef = ref<Menu[]>([]);
  60 + // flat menu array
59 61 const flatMenusRef = ref<Menu[]>([]);
60 62 const { currentRoute, push } = useRouter();
61   - // const { addTab } = useTabs();
62 63  
  64 + // get app config
63 65 const getProjectConfigRef = computed(() => {
64 66 return appStore.getProjectConfig;
65 67 });
66 68  
  69 + // get is Horizontal
67 70 const getIsHorizontalRef = computed(() => {
68 71 return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
69 72 });
70 73  
71 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 77 watch(
80 78 [() => unref(currentRoute).path, () => props.splitType],
81 79 async ([path, splitType]: [string, MenuSplitTyeEnum]) => {
... ... @@ -88,23 +86,26 @@ export default defineComponent({
88 86 }
89 87 );
90 88  
  89 + // Menu changes
91 90 watch(
92   - [() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState],
  91 + [() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState],
93 92 () => {
94 93 genMenus();
95 94 }
96 95 );
97 96  
  97 + // split Menu changes
98 98 watch([() => appStore.getProjectConfig.menuSetting.split], () => {
99 99 if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return;
100 100 genMenus();
101 101 });
102 102  
  103 + // Handle left menu split
103 104 async function handleSplitLeftMenu(parentPath: string) {
104 105 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
105 106 if (!isSplitMenu) return;
106 107 const { splitType } = props;
107   - // 菜单分割模式-left
  108 + // spilt mode left
108 109 if (splitType === MenuSplitTyeEnum.LEFT) {
109 110 const children = await getChildrenMenus(parentPath);
110 111 if (!children) {
... ... @@ -128,11 +129,11 @@ export default defineComponent({
128 129 }
129 130 }
130 131  
  132 + // get menus
131 133 async function genMenus() {
132 134 const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
133 135  
134   - // 普通模式
135   -
  136 + // normal mode
136 137 const { splitType } = props;
137 138 if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) {
138 139 flatMenusRef.value = await getFlatMenus();
... ... @@ -140,7 +141,7 @@ export default defineComponent({
140 141 return;
141 142 }
142 143  
143   - // 菜单分割模式-top
  144 + // split-top
144 145 if (splitType === MenuSplitTyeEnum.TOP) {
145 146 const parentPath = await getCurrentParentPath(unref(currentRoute).path);
146 147 menuStore.commitCurrentTopSplitMenuPathState(parentPath);
... ... @@ -156,12 +157,11 @@ export default defineComponent({
156 157 const { path } = menu;
157 158 if (path) {
158 159 const { splitType } = props;
159   - // 菜单分割模式-top
  160 + // split mode top
160 161 if (splitType === MenuSplitTyeEnum.TOP) {
161 162 menuStore.commitCurrentTopSplitMenuPathState(path);
162 163 }
163 164 push(path);
164   - // addTab(path as PageEnum, true);
165 165 }
166 166 }
167 167  
... ... @@ -205,6 +205,7 @@ export default defineComponent({
205 205 collapsed,
206 206 collapsedShowTitle,
207 207 collapsedShowSearch,
  208 + accordion,
208 209 },
209 210 } = unref(getProjectConfigRef);
210 211  
... ... @@ -227,6 +228,7 @@ export default defineComponent({
227 228 onClickSearchInput={handleClickSearchInput}
228 229 appendClass={props.splitType === MenuSplitTyeEnum.TOP}
229 230 isTop={props.isTop}
  231 + accordion={accordion}
230 232 >
231 233 {{
232 234 header: () =>
... ...
src/layouts/default/LayoutSideBar.tsx
... ... @@ -4,9 +4,6 @@ import { Layout } from &#39;ant-design-vue&#39;;
4 4 import LayoutTrigger from './LayoutTrigger';
5 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 7 import { appStore } from '/@/store/modules/app';
11 8 import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
12 9 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
... ... @@ -44,7 +41,7 @@ export default defineComponent({
44 41 initRef.value = true;
45 42 }
46 43  
47   - // 菜单区域拖拽 - 鼠标移动
  44 + // Menu area drag and drop-mouse movement
48 45 function handleMouseMove(ele: any, wrap: any, clientX: number) {
49 46 document.onmousemove = function (innerE) {
50 47 let iT = ele.left + ((innerE || event).clientX - clientX);
... ... @@ -98,7 +95,6 @@ export default defineComponent({
98 95 const side = unref(sideRef);
99 96  
100 97 const wrap = (side || {}).$el;
101   - // const eleWidth = 6;
102 98 ele &&
103 99 (ele.onmousedown = (e: any) => {
104 100 menuStore.commitDragStartState(true);
... ...
src/layouts/default/index.tsx
... ... @@ -19,12 +19,11 @@ import &#39;./index.less&#39;;
19 19 export default defineComponent({
20 20 name: 'DefaultLayout',
21 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 25 registerGlobComp();
26 26  
27   - // 获取项目配置
28 27 const { getFullContent } = useFullContent();
29 28  
30 29 const getProjectConfigRef = computed(() => {
... ... @@ -56,8 +55,6 @@ export default defineComponent({
56 55 return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent));
57 56 });
58 57  
59   - // Get project configuration
60   - // const { getFullContent } = useFullContent(currentRoute);
61 58 function getTarget(): any {
62 59 const {
63 60 headerSetting: { fixed },
... ...
src/layouts/default/setting/SettingDrawer.tsx
... ... @@ -2,14 +2,7 @@ import { defineComponent, computed, unref, ref } from &#39;vue&#39;;
2 2 import { BasicDrawer } from '/@/components/Drawer/index';
3 3 import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
4 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 6 import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
14 7 import { appStore } from '/@/store/modules/app';
15 8 import { userStore } from '/@/store/modules/user';
... ... @@ -24,70 +17,15 @@ import mixImg from &#39;/@/assets/images/layout/menu-mix.svg&#39;;
24 17 import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg';
25 18 import menuTopImg from '/@/assets/images/layout/menu-top.svg';
26 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 30 interface SwitchOptions {
93 31 config?: DeepPartial<ProjectConfig>;
... ... @@ -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 99 function renderSidebar() {
143 100 const {
144 101 headerSetting: { theme: headerTheme },
... ... @@ -175,7 +132,7 @@ export default defineComponent({
175 132 {{
176 133 default: () => (
177 134 <div
178   - onClick={baseHandler.bind(null, 'layout', {
  135 + onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
179 136 mode: mode,
180 137 type: ItemType,
181 138 split: unref(getIsHorizontalRef) ? false : undefined,
... ... @@ -192,14 +149,14 @@ export default defineComponent({
192 149 </div>,
193 150 renderSwitchItem('分割菜单', {
194 151 handler: (e) => {
195   - baseHandler('splitMenu', e);
  152 + baseHandler(HandlerEnum.MENU_SPLIT, e);
196 153 },
197 154 def: split,
198 155 disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
199 156 }),
200 157 renderSelectItem('顶栏主题', {
201 158 handler: (e) => {
202   - baseHandler('headerMenu', e);
  159 + baseHandler(HandlerEnum.HEADER_THEME, e);
203 160 },
204 161 def: headerTheme,
205 162 options: themeOptions,
... ... @@ -207,7 +164,7 @@ export default defineComponent({
207 164 }),
208 165 renderSelectItem('菜单主题', {
209 166 handler: (e) => {
210   - baseHandler('menuTheme', e);
  167 + baseHandler(HandlerEnum.MENU_THEME, e);
211 168 },
212 169 def: menuTheme,
213 170 options: themeOptions,
... ... @@ -230,48 +187,49 @@ export default defineComponent({
230 187 topMenuAlign,
231 188 collapsedShowTitle,
232 189 trigger,
  190 + accordion,
233 191 } = {},
234 192 } = appStore.getProjectConfig;
235 193 return [
236 194 renderSwitchItem('侧边菜单拖拽', {
237 195 handler: (e) => {
238   - baseHandler('hasDrag', e);
  196 + baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
239 197 },
240 198 def: hasDrag,
241 199 disabled: !unref(getShowMenuRef),
242 200 }),
243 201 renderSwitchItem('侧边菜单搜索', {
244 202 handler: (e) => {
245   - baseHandler('showSearch', e);
  203 + baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
246 204 },
247 205 def: showSearch,
248 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 215 renderSwitchItem('折叠菜单', {
251 216 handler: (e) => {
252   - baseHandler('collapsed', e);
  217 + baseHandler(HandlerEnum.MENU_COLLAPSED, e);
253 218 },
254 219 def: collapsed,
255 220 disabled: !unref(getShowMenuRef),
256 221 }),
257 222 renderSwitchItem('折叠菜单显示名称', {
258 223 handler: (e) => {
259   - baseHandler('collapsedShowTitle', e);
  224 + baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
260 225 },
261 226 def: collapsedShowTitle,
262 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 230 renderSelectItem('顶部菜单布局', {
273 231 handler: (e) => {
274   - baseHandler('topMenuAlign', e);
  232 + baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
275 233 },
276 234 def: topMenuAlign,
277 235 options: topMenuAlignOptions,
... ... @@ -279,14 +237,21 @@ export default defineComponent({
279 237 }),
280 238 renderSelectItem('菜单折叠按钮', {
281 239 handler: (e) => {
282   - baseHandler('menuTrigger', e);
  240 + baseHandler(HandlerEnum.MENU_TRIGGER, e);
283 241 },
284 242 def: trigger,
285 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 252 renderSelectItem('内容区域宽度', {
288 253 handler: (e) => {
289   - baseHandler('contentMode', e);
  254 + baseHandler(HandlerEnum.CONTENT_MODE, e);
290 255 },
291 256 def: contentMode,
292 257 options: contentModeOptions,
... ... @@ -297,8 +262,8 @@ export default defineComponent({
297 262 style="width:120px"
298 263 size="small"
299 264 min={0}
300   - onChange={(e) => {
301   - baseHandler('lockTime', e);
  265 + onChange={(e: any) => {
  266 + baseHandler(HandlerEnum.LOCK_TIME, e);
302 267 }}
303 268 defaultValue={appStore.getProjectConfig.lockTime}
304 269 formatter={(value: string) => {
... ... @@ -321,7 +286,7 @@ export default defineComponent({
321 286 defaultValue={menuWidth}
322 287 formatter={(value: string) => `${parseInt(value)}px`}
323 288 onChange={(e: any) => {
324   - baseHandler('menuWidth', e);
  289 + baseHandler(HandlerEnum.MENU_WIDTH, e);
325 290 }}
326 291 />
327 292 </div>,
... ... @@ -334,19 +299,19 @@ export default defineComponent({
334 299 <>
335 300 {renderSwitchItem('页面切换loading', {
336 301 handler: (e) => {
337   - baseHandler('openPageLoading', e);
  302 + baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
338 303 },
339 304 def: openPageLoading,
340 305 })}
341 306 {renderSwitchItem('切换动画', {
342 307 handler: (e) => {
343   - baseHandler('openRouterTransition', e);
  308 + baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
344 309 },
345 310 def: openRouterTransition,
346 311 })}
347 312 {renderSelectItem('路由动画', {
348 313 handler: (e) => {
349   - baseHandler('routerTransition', e);
  314 + baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
350 315 },
351 316 def: routerTransition,
352 317 options: routerTransitionOptions,
... ... @@ -370,289 +335,77 @@ export default defineComponent({
370 335 return [
371 336 renderSwitchItem('面包屑', {
372 337 handler: (e) => {
373   - baseHandler('showBreadCrumb', e);
  338 + baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
374 339 },
375 340 def: showBreadCrumb,
376 341 disabled: !unref(getShowHeaderRef),
377 342 }),
378 343 renderSwitchItem('面包屑图标', {
379 344 handler: (e) => {
380   - baseHandler('showBreadCrumbIcon', e);
  345 + baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
381 346 },
382 347 def: showBreadCrumbIcon,
383 348 disabled: !unref(getShowHeaderRef),
384 349 }),
385 350 renderSwitchItem('标签页', {
386 351 handler: (e) => {
387   - baseHandler('showMultiple', e);
  352 + baseHandler(HandlerEnum.TABS_SHOW, e);
388 353 },
389 354 def: showMultiple,
390 355 }),
391 356 renderSwitchItem('标签页快捷按钮', {
392 357 handler: (e) => {
393   - baseHandler('showQuick', e);
  358 + baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
394 359 },
395 360 def: showQuick,
396 361 disabled: !unref(getShowTabsRef),
397 362 }),
398 363 renderSwitchItem('标签页图标', {
399 364 handler: (e) => {
400   - baseHandler('showTabIcon', e);
  365 + baseHandler(HandlerEnum.TABS_SHOW_ICON, e);
401 366 },
402 367 def: showTabIcon,
403 368 disabled: !unref(getShowTabsRef),
404 369 }),
405 370 renderSwitchItem('左侧菜单', {
406 371 handler: (e) => {
407   - baseHandler('showSidebar', e);
  372 + baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
408 373 },
409 374 def: showMenu,
410 375 disabled: unref(getIsHorizontalRef),
411 376 }),
412 377 renderSwitchItem('顶栏', {
413 378 handler: (e) => {
414   - baseHandler('showHeader', e);
  379 + baseHandler(HandlerEnum.HEADER_SHOW, e);
415 380 },
416 381 def: showHeader,
417 382 }),
418 383 renderSwitchItem('Logo', {
419 384 handler: (e) => {
420   - baseHandler('showLogo', e);
  385 + baseHandler(HandlerEnum.SHOW_LOGO, e);
421 386 },
422 387 def: showLogo,
423 388 }),
424 389 renderSwitchItem('全屏内容', {
425 390 handler: (e) => {
426   - baseHandler('fullContent', e);
  391 + baseHandler(HandlerEnum.FULL_CONTENT, e);
427 392 },
428 393 def: fullContent,
429 394 }),
430 395 renderSwitchItem('灰色模式', {
431 396 handler: (e) => {
432   - baseHandler('grayMode', e);
  397 + baseHandler(HandlerEnum.GRAY_MODE, e);
433 398 },
434 399 def: grayMode,
435 400 }),
436 401 renderSwitchItem('色弱模式', {
437 402 handler: (e) => {
438   - baseHandler('colorWeak', e);
  403 + baseHandler(HandlerEnum.COLOR_WEAK, e);
439 404 },
440 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 410 function renderSelectItem(text: string, config?: SelectConfig) {
658 411 const { handler, def, disabled = false, options } = config || {};
... ... @@ -693,6 +446,7 @@ export default defineComponent({
693 446 </div>
694 447 );
695 448 }
  449 +
696 450 return () => (
697 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 74 collapsedShowSearch: false,
75 75 // 折叠触发器的位置
76 76 trigger: TriggerEnum.HEADER,
  77 + // 开启手风琴模式,只显示一个菜单
  78 + accordion: true,
77 79 },
78 80 // 消息配置
79 81 messageSetting: {
... ...
src/types/config.d.ts
... ... @@ -24,6 +24,7 @@ export interface MenuSetting {
24 24 topMenuAlign: 'start' | 'center' | 'end';
25 25 collapsedShowSearch: boolean;
26 26 trigger: TriggerEnum;
  27 + accordion: boolean;
27 28 }
28 29  
29 30 export interface MultiTabsSetting {
... ...
src/types/global.d.ts
... ... @@ -30,12 +30,16 @@ declare type Indexable&lt;T = any&gt; = {
30 30  
31 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 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 45 declare type SelectOptions = {
... ...
src/useApp.ts
... ... @@ -42,7 +42,7 @@ export function useThemeMode(mode: ThemeModeEnum) {
42 42 };
43 43 }
44 44  
45   -// 初始化项目配置
  45 +// Initial project configuration
46 46 export function useInitAppConfigStore() {
47 47 let projCfg: ProjectConfig = getLocal(PROJ_CFG_KEY) as ProjectConfig;
48 48 if (!projCfg) {
... ... @@ -78,12 +78,12 @@ export function useConfigProvider() {
78 78 };
79 79 }
80 80  
81   -// 初始化网络监听
  81 +// Initialize network monitoring
82 82 export function useListenerNetWork() {
83 83 const { listenNetWork } = appStore.getProjectConfig;
84 84 if (!listenNetWork) return;
85 85 const { replace } = useRouter();
86   - // 检测网络状态
  86 + // Check network status
87 87 useNetWork({
88 88 onLineFn: () => {
89 89 replace(PageEnum.BASE_HOME);
... ...
src/views/dashboard/analysis/index.vue
1 1 <template>
2 2 <div class="analysis p-4">
3   - <Row class="pl-2">
  3 + <a-row class="pl-2">
4 4 <template v-for="item in growCardList" :key="item.title">
5 5 <ACol :sm="24" :md="12" :lg="6">
6 6 <GrowCard :info="item" />
7 7 </ACol>
8 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 13 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
14 14 <AnalysisLine />
15 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 18 <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
19 19 <AnalysisPie />
20 20 </CollapseContainer>
21   - </ACol>
22   - <ACol :md="24" :lg="12">
  21 + </a-col>
  22 + <a-col :md="24" :lg="12">
23 23 <CollapseContainer class="mr-3" title="用户来源" :canExpan="false">
24 24 <AnalysisBar />
25 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 30 <CollapseContainer class="mt-3" title="项目进度" :canExpan="false">
31 31 <template v-for="item in taskList" :key="item.title">
32 32 <TaskCard :info="item" />
33 33 </template>
34 34 </CollapseContainer>
35   - </ACol>
36   - </Row>
37   - <Row>
  35 + </a-col>
  36 + </a-row>
  37 + <a-row>
38 38 <FlowAnalysis />
39   - </Row>
  39 + </a-row>
40 40 </div>
41 41 </template>
42 42 <script lang="ts">
... ... @@ -48,14 +48,11 @@
48 48 import AnalysisBar from './components/AnalysisBar.vue';
49 49 import TaskCard from './components/TaskCard.vue';
50 50 import FlowAnalysis from './components/FlowAnalysis';
51   - import { Row, Col } from 'ant-design-vue';
52 51 import { CollapseContainer } from '/@/components/Container/index';
53 52  
54 53 import { growCardList, taskList } from './data';
55 54 export default defineComponent({
56 55 components: {
57   - Row,
58   - ACol: Col,
59 56 GrowCard,
60 57 CollapseContainer,
61 58 TrendLine,
... ...
src/views/dashboard/workbench/index.vue
1 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 4 <ProdTotal class="mb-3" />
5 5 <TodoList class="mb-3" />
6 6 <NewsList class="mb-3" />
7   - </Col>
8   - <Col :md="24" :lg="7">
  7 + </a-col>
  8 + <a-col :md="24" :lg="7">
9 9 <img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" />
10 10 <ShortCuts class="mb-3" />
11 11 <Week class="mb-3" />
12   - </Col>
13   - </Row>
  12 + </a-col>
  13 + </a-row>
14 14 </template>
15 15 <script lang="ts">
16 16 import { defineComponent } from 'vue';
17   - import { Row, Col } from 'ant-design-vue';
18 17 import ProdTotal from './components/ProdTotal.vue';
19 18 import TodoList from './components/TodoList.vue';
20 19 import Week from './components/Week.vue';
... ... @@ -22,7 +21,7 @@
22 21 import ShortCuts from './components/ShortCuts.vue';
23 22  
24 23 export default defineComponent({
25   - components: { Row, Col, ProdTotal, TodoList, Week, ShortCuts, NewsList },
  24 + components: { ProdTotal, TodoList, Week, ShortCuts, NewsList },
26 25 setup() {
27 26 return {};
28 27 },
... ...
src/views/sys/login/Login.vue
... ... @@ -168,7 +168,7 @@
168 168 display: none;
169 169 height: 100%;
170 170 background: url(../../../assets/images/login/login-in.png) no-repeat;
171   - background-position: 50% 30%;
  171 + background-position: 30% 30%;
172 172 background-size: 80% 80%;
173 173  
174 174 .respond-to(xlarge, { display: block;});
... ... @@ -194,9 +194,9 @@
194 194 align-items: center;
195 195 .respond-to(large, {
196 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 202 &__content {
... ...
vite.config.ts
... ... @@ -34,7 +34,7 @@ const viteConfig: UserConfig = {
34 34 * @default 'index.html'
35 35 */
36 36 // TODO build error
37   - // entry: './public/index.html',
  37 + // entry: 'public/index.html',
38 38 /**
39 39 * port
40 40 * @default '3000'
... ...