1
2
3
4
import { defineComponent, computed, unref, ref } from 'vue';
import { BasicDrawer } from '/@/components/Drawer/index';
import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
import Button from '/@/components/Button/index.vue';
vben
authored
5 years ago
5
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
import { appStore } from '/@/store/modules/app';
import { userStore } from '/@/store/modules/user';
import { ProjectConfig } from '/@/types/config';
import { useMessage } from '/@/hooks/web/useMessage';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import defaultSetting from '/@/settings/projectSetting';
import mixImg from '/@/assets/images/layout/menu-mix.svg';
import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg';
import menuTopImg from '/@/assets/images/layout/menu-top.svg';
import { updateColorWeak, updateGrayMode } from '/@/setup/theme';
vben
authored
5 years ago
20
21
22
23
24
25
26
27
import { baseHandler } from './handler';
import {
HandlerEnum,
contentModeOptions,
topMenuAlignOptions,
menuTriggerOptions,
routerTransitionOptions,
} from './const';
vben
authored
5 years ago
28
import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST } from '/@/settings/colorSetting';
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
interface SwitchOptions {
config?: DeepPartial<ProjectConfig>;
def?: any;
disabled?: boolean;
handler?: Fn;
}
interface SelectConfig {
options?: SelectOptions;
def?: any;
disabled?: boolean;
handler?: Fn;
}
vben
authored
5 years ago
44
45
46
47
48
interface ThemeOptions {
def?: string;
handler?: Fn;
}
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
export default defineComponent({
name: 'SettingDrawer',
setup(_, { attrs }) {
const { createSuccessModal, createMessage } = useMessage();
const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig;
});
const getIsHorizontalRef = computed(() => {
return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
});
const getShowHeaderRef = computed(() => {
return unref(getProjectConfigRef).headerSetting.show;
});
const getShowMenuRef = computed(() => {
return unref(getProjectConfigRef).menuSetting.show && !unref(getIsHorizontalRef);
});
const getShowTabsRef = computed(() => {
return unref(getProjectConfigRef).multiTabsSetting.show;
});
function handleCopy() {
const { isSuccessRef } = useCopyToClipboard(
JSON.stringify(unref(getProjectConfigRef), null, 2)
);
unref(isSuccessRef) &&
createSuccessModal({
title: '操作成功',
content: '复制成功,请到 src/settings/projectSetting.ts 中修改配置!',
});
}
vben
authored
5 years ago
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
function handleResetSetting() {
try {
appStore.commitProjectConfigState(defaultSetting);
const { colorWeak, grayMode } = defaultSetting;
// updateTheme(themeColor);
updateColorWeak(colorWeak);
updateGrayMode(grayMode);
createMessage.success('重置成功!');
} catch (error) {
createMessage.error(error);
}
}
function handleClearAndRedo() {
localStorage.clear();
userStore.resumeAllState();
location.reload();
}
104
105
function renderSidebar() {
const {
vben
authored
5 years ago
106
menuSetting: { type, split },
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
} = unref(getProjectConfigRef);
const typeList = ref([
{
title: '左侧菜单模式',
mode: MenuModeEnum.INLINE,
type: MenuTypeEnum.SIDEBAR,
src: sidebarImg,
},
{
title: '混合模式',
mode: MenuModeEnum.INLINE,
type: MenuTypeEnum.MIX,
src: mixImg,
},
{
title: '顶部菜单模式',
mode: MenuModeEnum.HORIZONTAL,
type: MenuTypeEnum.TOP_MENU,
src: menuTopImg,
},
]);
return [
<div class={`setting-drawer__siderbar`}>
{unref(typeList).map((item) => {
const { title, type: ItemType, mode, src } = item;
return (
<Tooltip title={title} placement="bottom" key={title}>
{{
default: () => (
<div
vben
authored
5 years ago
139
onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
mode: mode,
type: ItemType,
split: unref(getIsHorizontalRef) ? false : undefined,
})}
>
<CheckOutlined class={['check-icon', type === ItemType ? 'active' : '']} />
<img src={src} />
</div>
),
}}
</Tooltip>
);
})}
</div>,
renderSwitchItem('分割菜单', {
handler: (e) => {
vben
authored
5 years ago
156
baseHandler(HandlerEnum.MENU_SPLIT, e);
157
158
},
def: split,
vben
authored
5 years ago
159
disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
160
}),
vben
authored
5 years ago
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// renderSelectItem('顶栏主题', {
// handler: (e) => {
// baseHandler(HandlerEnum.HEADER_THEME, e);
// },
// def: headerTheme,
// options: themeOptions,
// disabled: !unref(getShowHeaderRef),
// }),
// renderSelectItem('菜单主题', {
// handler: (e) => {
// baseHandler(HandlerEnum.MENU_THEME, e);
// },
// def: menuTheme,
// options: themeOptions,
// disabled: !unref(getShowMenuRef),
// }),
177
178
179
180
181
182
183
184
185
];
}
/**
* @description:
*/
function renderFeatures() {
const {
contentMode,
headerSetting: { fixed },
vben
authored
5 years ago
186
187
188
189
190
191
192
menuSetting: {
hasDrag,
collapsed,
showSearch,
menuWidth,
topMenuAlign,
collapsedShowTitle,
vben
authored
5 years ago
193
trigger,
vben
authored
5 years ago
194
accordion,
vben
authored
5 years ago
195
} = {},
196
197
198
199
} = appStore.getProjectConfig;
return [
renderSwitchItem('侧边菜单拖拽', {
handler: (e) => {
vben
authored
5 years ago
200
baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
201
202
203
204
205
206
},
def: hasDrag,
disabled: !unref(getShowMenuRef),
}),
renderSwitchItem('侧边菜单搜索', {
handler: (e) => {
vben
authored
5 years ago
207
baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
208
209
210
211
},
def: showSearch,
disabled: !unref(getShowMenuRef),
}),
vben
authored
5 years ago
212
213
214
215
216
217
218
renderSwitchItem('侧边菜单手风琴模式', {
handler: (e) => {
baseHandler(HandlerEnum.MENU_ACCORDION, e);
},
def: accordion,
disabled: !unref(getShowMenuRef),
}),
219
220
renderSwitchItem('折叠菜单', {
handler: (e) => {
vben
authored
5 years ago
221
baseHandler(HandlerEnum.MENU_COLLAPSED, e);
222
223
224
225
},
def: collapsed,
disabled: !unref(getShowMenuRef),
}),
vben
authored
5 years ago
226
227
renderSwitchItem('折叠菜单显示名称', {
handler: (e) => {
vben
authored
5 years ago
228
baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
vben
authored
5 years ago
229
230
231
232
},
def: collapsedShowTitle,
disabled: !unref(getShowMenuRef) || !collapsed,
}),
vben
authored
5 years ago
233
234
235
236
237
238
239
renderSwitchItem('固定header', {
handler: (e) => {
baseHandler(HandlerEnum.HEADER_FIXED, e);
},
def: fixed,
disabled: !unref(getShowHeaderRef),
}),
240
241
renderSelectItem('顶部菜单布局', {
handler: (e) => {
vben
authored
5 years ago
242
baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
243
244
245
246
247
},
def: topMenuAlign,
options: topMenuAlignOptions,
disabled: !unref(getShowHeaderRef),
}),
vben
authored
5 years ago
248
249
renderSelectItem('菜单折叠按钮', {
handler: (e) => {
vben
authored
5 years ago
250
baseHandler(HandlerEnum.MENU_TRIGGER, e);
vben
authored
5 years ago
251
252
253
254
},
def: trigger,
options: menuTriggerOptions,
}),
vben
authored
5 years ago
255
256
257
renderSelectItem('内容区域宽度', {
handler: (e) => {
vben
authored
5 years ago
258
baseHandler(HandlerEnum.CONTENT_MODE, e);
259
260
261
262
263
264
265
266
267
268
},
def: contentMode,
options: contentModeOptions,
}),
<div class={`setting-drawer__cell-item`}>
<span>自动锁屏</span>
<InputNumber
style="width:120px"
size="small"
min={0}
vben
authored
5 years ago
269
270
onChange={(e: any) => {
baseHandler(HandlerEnum.LOCK_TIME, e);
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
}}
defaultValue={appStore.getProjectConfig.lockTime}
formatter={(value: string) => {
if (parseInt(value) === 0) {
return '0(不自动锁屏)';
}
return `${value}分钟`;
}}
/>
</div>,
<div class={`setting-drawer__cell-item`}>
<span>菜单展开宽度</span>
<InputNumber
style="width:120px"
size="small"
max={600}
min={100}
step={10}
disabled={!unref(getShowMenuRef)}
defaultValue={menuWidth}
formatter={(value: string) => `${parseInt(value)}px`}
vben
authored
5 years ago
292
onChange={(e: any) => {
vben
authored
5 years ago
293
baseHandler(HandlerEnum.MENU_WIDTH, e);
294
295
296
297
298
299
300
301
302
303
304
305
}}
/>
</div>,
];
}
function renderTransition() {
const { routerTransition, openRouterTransition, openPageLoading } = appStore.getProjectConfig;
return (
<>
{renderSwitchItem('页面切换loading', {
handler: (e) => {
vben
authored
5 years ago
306
baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
307
308
309
310
311
},
def: openPageLoading,
})}
{renderSwitchItem('切换动画', {
handler: (e) => {
vben
authored
5 years ago
312
baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
313
314
315
316
317
},
def: openRouterTransition,
})}
{renderSelectItem('路由动画', {
handler: (e) => {
vben
authored
5 years ago
318
baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
},
def: routerTransition,
options: routerTransitionOptions,
disabled: !openRouterTransition,
})}
</>
);
}
function renderContent() {
const {
grayMode,
colorWeak,
fullContent,
showLogo,
headerSetting: { show: showHeader },
menuSetting: { show: showMenu },
multiTabsSetting: { show: showMultiple, showQuick, showIcon: showTabIcon },
showBreadCrumb,
337
showBreadCrumbIcon,
338
339
340
341
} = unref(getProjectConfigRef);
return [
renderSwitchItem('面包屑', {
handler: (e) => {
vben
authored
5 years ago
342
baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
343
344
345
346
},
def: showBreadCrumb,
disabled: !unref(getShowHeaderRef),
}),
347
348
renderSwitchItem('面包屑图标', {
handler: (e) => {
vben
authored
5 years ago
349
baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
350
351
352
353
},
def: showBreadCrumbIcon,
disabled: !unref(getShowHeaderRef),
}),
354
355
renderSwitchItem('标签页', {
handler: (e) => {
vben
authored
5 years ago
356
baseHandler(HandlerEnum.TABS_SHOW, e);
357
358
359
360
361
},
def: showMultiple,
}),
renderSwitchItem('标签页快捷按钮', {
handler: (e) => {
vben
authored
5 years ago
362
baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
363
364
365
366
367
368
},
def: showQuick,
disabled: !unref(getShowTabsRef),
}),
renderSwitchItem('标签页图标', {
handler: (e) => {
vben
authored
5 years ago
369
baseHandler(HandlerEnum.TABS_SHOW_ICON, e);
370
371
372
373
374
375
},
def: showTabIcon,
disabled: !unref(getShowTabsRef),
}),
renderSwitchItem('左侧菜单', {
handler: (e) => {
vben
authored
5 years ago
376
baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
377
378
379
380
381
382
},
def: showMenu,
disabled: unref(getIsHorizontalRef),
}),
renderSwitchItem('顶栏', {
handler: (e) => {
vben
authored
5 years ago
383
baseHandler(HandlerEnum.HEADER_SHOW, e);
384
385
386
387
388
},
def: showHeader,
}),
renderSwitchItem('Logo', {
handler: (e) => {
vben
authored
5 years ago
389
baseHandler(HandlerEnum.SHOW_LOGO, e);
390
391
392
393
394
},
def: showLogo,
}),
renderSwitchItem('全屏内容', {
handler: (e) => {
vben
authored
5 years ago
395
baseHandler(HandlerEnum.FULL_CONTENT, e);
396
397
398
399
400
},
def: fullContent,
}),
renderSwitchItem('灰色模式', {
handler: (e) => {
vben
authored
5 years ago
401
baseHandler(HandlerEnum.GRAY_MODE, e);
402
403
404
405
406
},
def: grayMode,
}),
renderSwitchItem('色弱模式', {
handler: (e) => {
vben
authored
5 years ago
407
baseHandler(HandlerEnum.COLOR_WEAK, e);
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
},
def: colorWeak,
}),
];
}
function renderSelectItem(text: string, config?: SelectConfig) {
const { handler, def, disabled = false, options } = config || {};
const opt = def ? { value: def, defaultValue: def } : {};
return (
<div class={`setting-drawer__cell-item`}>
<span>{text}</span>
<Select
{...opt}
disabled={disabled}
size="small"
style={{ width: '120px' }}
onChange={(e) => {
handler && handler(e);
}}
options={options}
/>
</div>
);
}
function renderSwitchItem(text: string, options?: SwitchOptions) {
const { handler, def, disabled = false } = options || {};
const opt = def ? { checked: def } : {};
return (
<div class={`setting-drawer__cell-item`}>
<span>{text}</span>
<Switch
{...opt}
disabled={disabled}
vben
authored
5 years ago
443
onChange={(e: any) => {
444
445
446
447
448
449
450
451
handler && handler(e);
}}
checkedChildren="开"
unCheckedChildren="关"
/>
</div>
);
}
vben
authored
5 years ago
452
vben
authored
5 years ago
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
function renderTheme() {
const { headerBgColor, menuBgColor } = unref(getProjectConfigRef);
return (
<>
<Divider>{() => '顶栏主题'}</Divider>
{renderThemeItem(HEADER_PRESET_BG_COLOR_LIST, {
def: headerBgColor,
handler: (e) => {
baseHandler(HandlerEnum.HEADER_THEME, e);
},
})}
<Divider>{() => '菜单主题'}</Divider>
{renderThemeItem(SIDE_BAR_BG_COLOR_LIST, {
def: menuBgColor,
handler: (e) => {
baseHandler(HandlerEnum.MENU_THEME, e);
},
})}
</>
);
}
function renderThemeItem(colorList: string[], opt: ThemeOptions) {
const { def, handler } = opt;
return (
<div class={`setting-drawer__theme-item`}>
{colorList.map((item) => {
return (
<span
onClick={() => handler && handler(item)}
key={item}
class={[def === item ? 'active' : '']}
style={{
background: item,
}}
>
<CheckOutlined class="icon" />
</span>
);
})}
</div>
);
}
497
498
499
500
501
502
503
return () => (
<BasicDrawer {...attrs} title="项目配置" width={300} wrapClassName="setting-drawer">
{{
default: () => (
<>
<Divider>{() => '导航栏模式'}</Divider>
{renderSidebar()}
vben
authored
5 years ago
504
505
506
{renderTheme()}
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
<Divider>{() => '界面功能'}</Divider>
{renderFeatures()}
<Divider>{() => '界面显示'}</Divider>
{renderContent()}
<Divider>{() => '切换动画'}</Divider>
{renderTransition()}
<Divider />
<div class="setting-drawer__footer">
<Button type="primary" block onClick={handleCopy}>
{() => (
<>
<CopyOutlined class="mr-2" />
拷贝
</>
)}
</Button>
<Button block class="mt-2" onClick={handleResetSetting} color="warning">
{() => (
<>
<RedoOutlined class="mr-2" />
重置
</>
)}
</Button>
<Button block class="mt-2" onClick={handleClearAndRedo} color="error">
{() => (
<>
<RedoOutlined class="mr-2" />
清空缓存并返回登录页
</>
)}
</Button>
</div>
</>
),
}}
</BasicDrawer>
);
},
});