SettingDrawer.tsx 14.9 KB
Newer Older
陈文彬 已提交
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';
V
vben 已提交
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';
V
vben 已提交
20 21 22 23 24 25 26 27 28
import { baseHandler } from './handler';
import {
  HandlerEnum,
  themeOptions,
  contentModeOptions,
  topMenuAlignOptions,
  menuTriggerOptions,
  routerTransitionOptions,
} from './const';
陈文彬 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 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

interface SwitchOptions {
  config?: DeepPartial<ProjectConfig>;
  def?: any;
  disabled?: boolean;
  handler?: Fn;
}

interface SelectConfig {
  options?: SelectOptions;
  def?: any;
  disabled?: boolean;
  handler?: Fn;
}

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 中修改配置!',
        });
    }

V
vben 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    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();
    }

陈文彬 已提交
99 100 101 102 103 104 105 106 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
    function renderSidebar() {
      const {
        headerSetting: { theme: headerTheme },
        menuSetting: { type, theme: menuTheme, split },
      } = 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
V
vben 已提交
135
                      onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
陈文彬 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
                        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) => {
V
vben 已提交
152
            baseHandler(HandlerEnum.MENU_SPLIT, e);
陈文彬 已提交
153 154
          },
          def: split,
V
vben 已提交
155
          disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
陈文彬 已提交
156 157 158
        }),
        renderSelectItem('顶栏主题', {
          handler: (e) => {
V
vben 已提交
159
            baseHandler(HandlerEnum.HEADER_THEME, e);
陈文彬 已提交
160 161 162 163 164 165 166
          },
          def: headerTheme,
          options: themeOptions,
          disabled: !unref(getShowHeaderRef),
        }),
        renderSelectItem('菜单主题', {
          handler: (e) => {
V
vben 已提交
167
            baseHandler(HandlerEnum.MENU_THEME, e);
陈文彬 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181
          },
          def: menuTheme,
          options: themeOptions,
          disabled: !unref(getShowMenuRef),
        }),
      ];
    }
    /**
     * @description:
     */
    function renderFeatures() {
      const {
        contentMode,
        headerSetting: { fixed },
V
vben 已提交
182 183 184 185 186 187 188
        menuSetting: {
          hasDrag,
          collapsed,
          showSearch,
          menuWidth,
          topMenuAlign,
          collapsedShowTitle,
V
vben 已提交
189
          trigger,
V
vben 已提交
190
          accordion,
V
vben 已提交
191
        } = {},
陈文彬 已提交
192 193 194 195
      } = appStore.getProjectConfig;
      return [
        renderSwitchItem('侧边菜单拖拽', {
          handler: (e) => {
V
vben 已提交
196
            baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
陈文彬 已提交
197 198 199 200 201 202
          },
          def: hasDrag,
          disabled: !unref(getShowMenuRef),
        }),
        renderSwitchItem('侧边菜单搜索', {
          handler: (e) => {
V
vben 已提交
203
            baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
陈文彬 已提交
204 205 206 207
          },
          def: showSearch,
          disabled: !unref(getShowMenuRef),
        }),
V
vben 已提交
208 209 210 211 212 213 214
        renderSwitchItem('侧边菜单手风琴模式', {
          handler: (e) => {
            baseHandler(HandlerEnum.MENU_ACCORDION, e);
          },
          def: accordion,
          disabled: !unref(getShowMenuRef),
        }),
陈文彬 已提交
215 216
        renderSwitchItem('折叠菜单', {
          handler: (e) => {
V
vben 已提交
217
            baseHandler(HandlerEnum.MENU_COLLAPSED, e);
陈文彬 已提交
218 219 220 221
          },
          def: collapsed,
          disabled: !unref(getShowMenuRef),
        }),
V
vben 已提交
222 223
        renderSwitchItem('折叠菜单显示名称', {
          handler: (e) => {
V
vben 已提交
224
            baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
V
vben 已提交
225 226 227 228
          },
          def: collapsedShowTitle,
          disabled: !unref(getShowMenuRef) || !collapsed,
        }),
V
vben 已提交
229 230 231 232 233 234 235
        renderSwitchItem('固定header', {
          handler: (e) => {
            baseHandler(HandlerEnum.HEADER_FIXED, e);
          },
          def: fixed,
          disabled: !unref(getShowHeaderRef),
        }),
陈文彬 已提交
236 237
        renderSelectItem('顶部菜单布局', {
          handler: (e) => {
V
vben 已提交
238
            baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
陈文彬 已提交
239 240 241 242 243
          },
          def: topMenuAlign,
          options: topMenuAlignOptions,
          disabled: !unref(getShowHeaderRef),
        }),
V
vben 已提交
244 245
        renderSelectItem('菜单折叠按钮', {
          handler: (e) => {
V
vben 已提交
246
            baseHandler(HandlerEnum.MENU_TRIGGER, e);
V
vben 已提交
247 248 249 250
          },
          def: trigger,
          options: menuTriggerOptions,
        }),
V
vben 已提交
251

陈文彬 已提交
252 253
        renderSelectItem('内容区域宽度', {
          handler: (e) => {
V
vben 已提交
254
            baseHandler(HandlerEnum.CONTENT_MODE, e);
陈文彬 已提交
255 256 257 258 259 260 261 262 263 264
          },
          def: contentMode,
          options: contentModeOptions,
        }),
        <div class={`setting-drawer__cell-item`}>
          <span>自动锁屏</span>
          <InputNumber
            style="width:120px"
            size="small"
            min={0}
V
vben 已提交
265 266
            onChange={(e: any) => {
              baseHandler(HandlerEnum.LOCK_TIME, e);
陈文彬 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
            }}
            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`}
V
vben 已提交
288
            onChange={(e: any) => {
V
vben 已提交
289
              baseHandler(HandlerEnum.MENU_WIDTH, e);
陈文彬 已提交
290 291 292 293 294 295 296 297 298 299 300 301
            }}
          />
        </div>,
      ];
    }
    function renderTransition() {
      const { routerTransition, openRouterTransition, openPageLoading } = appStore.getProjectConfig;

      return (
        <>
          {renderSwitchItem('页面切换loading', {
            handler: (e) => {
V
vben 已提交
302
              baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
陈文彬 已提交
303 304 305 306 307
            },
            def: openPageLoading,
          })}
          {renderSwitchItem('切换动画', {
            handler: (e) => {
V
vben 已提交
308
              baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
陈文彬 已提交
309 310 311 312 313
            },
            def: openRouterTransition,
          })}
          {renderSelectItem('路由动画', {
            handler: (e) => {
V
vben 已提交
314
              baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
陈文彬 已提交
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
            },
            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,
Z
ZhaoBin 已提交
333
        showBreadCrumbIcon,
陈文彬 已提交
334 335 336 337
      } = unref(getProjectConfigRef);
      return [
        renderSwitchItem('面包屑', {
          handler: (e) => {
V
vben 已提交
338
            baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
陈文彬 已提交
339 340 341 342
          },
          def: showBreadCrumb,
          disabled: !unref(getShowHeaderRef),
        }),
Z
ZhaoBin 已提交
343 344
        renderSwitchItem('面包屑图标', {
          handler: (e) => {
V
vben 已提交
345
            baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
Z
ZhaoBin 已提交
346 347 348 349
          },
          def: showBreadCrumbIcon,
          disabled: !unref(getShowHeaderRef),
        }),
陈文彬 已提交
350 351
        renderSwitchItem('标签页', {
          handler: (e) => {
V
vben 已提交
352
            baseHandler(HandlerEnum.TABS_SHOW, e);
陈文彬 已提交
353 354 355 356 357
          },
          def: showMultiple,
        }),
        renderSwitchItem('标签页快捷按钮', {
          handler: (e) => {
V
vben 已提交
358
            baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
陈文彬 已提交
359 360 361 362 363 364
          },
          def: showQuick,
          disabled: !unref(getShowTabsRef),
        }),
        renderSwitchItem('标签页图标', {
          handler: (e) => {
V
vben 已提交
365
            baseHandler(HandlerEnum.TABS_SHOW_ICON, e);
陈文彬 已提交
366 367 368 369 370 371
          },
          def: showTabIcon,
          disabled: !unref(getShowTabsRef),
        }),
        renderSwitchItem('左侧菜单', {
          handler: (e) => {
V
vben 已提交
372
            baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
陈文彬 已提交
373 374 375 376 377 378
          },
          def: showMenu,
          disabled: unref(getIsHorizontalRef),
        }),
        renderSwitchItem('顶栏', {
          handler: (e) => {
V
vben 已提交
379
            baseHandler(HandlerEnum.HEADER_SHOW, e);
陈文彬 已提交
380 381 382 383 384
          },
          def: showHeader,
        }),
        renderSwitchItem('Logo', {
          handler: (e) => {
V
vben 已提交
385
            baseHandler(HandlerEnum.SHOW_LOGO, e);
陈文彬 已提交
386 387 388 389 390
          },
          def: showLogo,
        }),
        renderSwitchItem('全屏内容', {
          handler: (e) => {
V
vben 已提交
391
            baseHandler(HandlerEnum.FULL_CONTENT, e);
陈文彬 已提交
392 393 394 395 396
          },
          def: fullContent,
        }),
        renderSwitchItem('灰色模式', {
          handler: (e) => {
V
vben 已提交
397
            baseHandler(HandlerEnum.GRAY_MODE, e);
陈文彬 已提交
398 399 400 401 402
          },
          def: grayMode,
        }),
        renderSwitchItem('色弱模式', {
          handler: (e) => {
V
vben 已提交
403
            baseHandler(HandlerEnum.COLOR_WEAK, e);
陈文彬 已提交
404 405 406 407 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
          },
          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>
          {/* @ts-ignore */}
          <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}
V
vben 已提交
440
            onChange={(e: any) => {
陈文彬 已提交
441 442 443 444 445 446 447 448
              handler && handler(e);
            }}
            checkedChildren="开"
            unCheckedChildren="关"
          />
        </div>
      );
    }
V
vben 已提交
449

陈文彬 已提交
450 451 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
    return () => (
      <BasicDrawer {...attrs} title="项目配置" width={300} wrapClassName="setting-drawer">
        {{
          default: () => (
            <>
              <Divider>{() => '导航栏模式'}</Divider>
              {renderSidebar()}
              <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>
    );
  },
});