Blame view

src/layouts/default/setting/SettingDrawer.tsx 16.3 KB
陈文彬 authored
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';
5
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
陈文彬 authored
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';
20
21
22
23
24
25
26
27
import { baseHandler } from './handler';
import {
  HandlerEnum,
  contentModeOptions,
  topMenuAlignOptions,
  menuTriggerOptions,
  routerTransitionOptions,
} from './const';
28
import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST } from '/@/settings/colorSetting';
陈文彬 authored
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;
}
44
45
46
47
48
interface ThemeOptions {
  def?: string;
  handler?: Fn;
}
陈文彬 authored
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 中修改配置!',
        });
    }
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();
    }
陈文彬 authored
104
105
    function renderSidebar() {
      const {
106
        menuSetting: { type, split },
陈文彬 authored
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
139
                      onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
陈文彬 authored
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) => {
156
            baseHandler(HandlerEnum.MENU_SPLIT, e);
陈文彬 authored
157
158
          },
          def: split,
159
          disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
陈文彬 authored
160
        }),
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),
        // }),
陈文彬 authored
177
178
179
180
181
182
183
184
185
      ];
    }
    /**
     * @description:
     */
    function renderFeatures() {
      const {
        contentMode,
        headerSetting: { fixed },
186
187
188
189
190
191
192
        menuSetting: {
          hasDrag,
          collapsed,
          showSearch,
          menuWidth,
          topMenuAlign,
          collapsedShowTitle,
193
          trigger,
194
          accordion,
195
        } = {},
陈文彬 authored
196
197
198
199
      } = appStore.getProjectConfig;
      return [
        renderSwitchItem('侧边菜单拖拽', {
          handler: (e) => {
200
            baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
陈文彬 authored
201
202
203
204
205
206
          },
          def: hasDrag,
          disabled: !unref(getShowMenuRef),
        }),
        renderSwitchItem('侧边菜单搜索', {
          handler: (e) => {
207
            baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
陈文彬 authored
208
209
210
211
          },
          def: showSearch,
          disabled: !unref(getShowMenuRef),
        }),
212
213
214
215
216
217
218
        renderSwitchItem('侧边菜单手风琴模式', {
          handler: (e) => {
            baseHandler(HandlerEnum.MENU_ACCORDION, e);
          },
          def: accordion,
          disabled: !unref(getShowMenuRef),
        }),
陈文彬 authored
219
220
        renderSwitchItem('折叠菜单', {
          handler: (e) => {
221
            baseHandler(HandlerEnum.MENU_COLLAPSED, e);
陈文彬 authored
222
223
224
225
          },
          def: collapsed,
          disabled: !unref(getShowMenuRef),
        }),
226
227
        renderSwitchItem('折叠菜单显示名称', {
          handler: (e) => {
228
            baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
229
230
231
232
          },
          def: collapsedShowTitle,
          disabled: !unref(getShowMenuRef) || !collapsed,
        }),
vben authored
233
234
235
236
237
238
239
        renderSwitchItem('固定header', {
          handler: (e) => {
            baseHandler(HandlerEnum.HEADER_FIXED, e);
          },
          def: fixed,
          disabled: !unref(getShowHeaderRef),
        }),
陈文彬 authored
240
241
        renderSelectItem('顶部菜单布局', {
          handler: (e) => {
242
            baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
陈文彬 authored
243
244
245
246
247
          },
          def: topMenuAlign,
          options: topMenuAlignOptions,
          disabled: !unref(getShowHeaderRef),
        }),
248
249
        renderSelectItem('菜单折叠按钮', {
          handler: (e) => {
250
            baseHandler(HandlerEnum.MENU_TRIGGER, e);
251
252
253
254
          },
          def: trigger,
          options: menuTriggerOptions,
        }),
vben authored
255
陈文彬 authored
256
257
        renderSelectItem('内容区域宽度', {
          handler: (e) => {
258
            baseHandler(HandlerEnum.CONTENT_MODE, e);
陈文彬 authored
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}
269
270
            onChange={(e: any) => {
              baseHandler(HandlerEnum.LOCK_TIME, e);
陈文彬 authored
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`}
292
            onChange={(e: any) => {
293
              baseHandler(HandlerEnum.MENU_WIDTH, e);
陈文彬 authored
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) => {
306
              baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
陈文彬 authored
307
308
309
310
311
            },
            def: openPageLoading,
          })}
          {renderSwitchItem('切换动画', {
            handler: (e) => {
312
              baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
陈文彬 authored
313
314
315
316
317
            },
            def: openRouterTransition,
          })}
          {renderSelectItem('路由动画', {
            handler: (e) => {
318
              baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
陈文彬 authored
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,
陈文彬 authored
338
339
340
341
      } = unref(getProjectConfigRef);
      return [
        renderSwitchItem('面包屑', {
          handler: (e) => {
342
            baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
陈文彬 authored
343
344
345
346
          },
          def: showBreadCrumb,
          disabled: !unref(getShowHeaderRef),
        }),
347
348
        renderSwitchItem('面包屑图标', {
          handler: (e) => {
349
            baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
350
351
352
353
          },
          def: showBreadCrumbIcon,
          disabled: !unref(getShowHeaderRef),
        }),
陈文彬 authored
354
355
        renderSwitchItem('标签页', {
          handler: (e) => {
356
            baseHandler(HandlerEnum.TABS_SHOW, e);
陈文彬 authored
357
358
359
360
361
          },
          def: showMultiple,
        }),
        renderSwitchItem('标签页快捷按钮', {
          handler: (e) => {
362
            baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
陈文彬 authored
363
364
365
366
367
368
          },
          def: showQuick,
          disabled: !unref(getShowTabsRef),
        }),
        renderSwitchItem('标签页图标', {
          handler: (e) => {
369
            baseHandler(HandlerEnum.TABS_SHOW_ICON, e);
陈文彬 authored
370
371
372
373
374
375
          },
          def: showTabIcon,
          disabled: !unref(getShowTabsRef),
        }),
        renderSwitchItem('左侧菜单', {
          handler: (e) => {
376
            baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
陈文彬 authored
377
378
379
380
381
382
          },
          def: showMenu,
          disabled: unref(getIsHorizontalRef),
        }),
        renderSwitchItem('顶栏', {
          handler: (e) => {
383
            baseHandler(HandlerEnum.HEADER_SHOW, e);
陈文彬 authored
384
385
386
387
388
          },
          def: showHeader,
        }),
        renderSwitchItem('Logo', {
          handler: (e) => {
389
            baseHandler(HandlerEnum.SHOW_LOGO, e);
陈文彬 authored
390
391
392
393
394
          },
          def: showLogo,
        }),
        renderSwitchItem('全屏内容', {
          handler: (e) => {
395
            baseHandler(HandlerEnum.FULL_CONTENT, e);
陈文彬 authored
396
397
398
399
400
          },
          def: fullContent,
        }),
        renderSwitchItem('灰色模式', {
          handler: (e) => {
401
            baseHandler(HandlerEnum.GRAY_MODE, e);
陈文彬 authored
402
403
404
405
406
          },
          def: grayMode,
        }),
        renderSwitchItem('色弱模式', {
          handler: (e) => {
407
            baseHandler(HandlerEnum.COLOR_WEAK, e);
陈文彬 authored
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}
443
            onChange={(e: any) => {
陈文彬 authored
444
445
446
447
448
449
450
451
              handler && handler(e);
            }}
            checkedChildren="开"
            unCheckedChildren="关"
          />
        </div>
      );
    }
452
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>
      );
    }
陈文彬 authored
497
498
499
500
501
502
503
    return () => (
      <BasicDrawer {...attrs} title="项目配置" width={300} wrapClassName="setting-drawer">
        {{
          default: () => (
            <>
              <Divider>{() => '导航栏模式'}</Divider>
              {renderSidebar()}
504
505
506

              {renderTheme()}
陈文彬 authored
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>
    );
  },
});