From a12742756697b1d1d4b1d137421745d463b1c5f8 Mon Sep 17 00:00:00 2001 From: chuan_wuhao <443547225@qq.com> Date: Tue, 22 Nov 2022 15:54:07 +0800 Subject: [PATCH] ray template3.0 --- .vscode/settings.json | 8 +- auto-imports.d.ts | 4 + locales/en-US.json | 20 ++- locales/zh-CN.json | 20 ++- package.json | 3 +- src/App.tsx | 48 ++---- src/components/RayGlobalProvider/index.tsx | 49 ++++++ src/components/RayIcon/index.tsx | 4 +- src/icons/dark.svg | 3 + src/icons/dashboard.svg | 4 + src/icons/language.svg | 3 + src/icons/light.svg | 6 + src/icons/lock.svg | 5 + src/icons/reload.svg | 3 + src/icons/rely.svg | 6 + src/icons/setting.svg | 4 + src/language/index.ts | 11 ++ src/layout/Menu/index.tsx | 46 ++++++ .../SiderBar/Components/SettingDrawer/hook.ts | 9 ++ .../Components/SettingDrawer/index.scss | 3 + .../Components/SettingDrawer/index.tsx | 129 +++++++++++++++ src/layout/SiderBar/index.scss | 16 ++ src/layout/SiderBar/index.tsx | 144 +++++++++++++++++ src/layout/SiderBar/type.ts | 5 + src/layout/index.scss | 12 ++ src/layout/index.tsx | 41 +++++ src/main.ts | 14 +- src/router/index.ts | 8 + src/router/modules/dashboard.ts | 9 ++ src/router/modules/demo.ts | 5 - src/router/modules/index.ts | 5 +- src/router/modules/rely.ts | 19 +++ src/router/routes.ts | 9 +- src/store/index.ts | 1 + src/store/modules/menu.ts | 99 ++++++++++++ src/store/modules/setting.ts | 35 ++++- src/styles/setting.scss | 2 + src/types/index.d.ts | 21 ++- src/views/dashboard/index.tsx | 13 ++ src/views/rely/index.tsx | 13 ++ src/views/rely/views/rely-about/index.scss | 9 ++ src/views/rely/views/rely-about/index.tsx | 126 +++++++++++++++ src/vite-env.d.ts | 19 +++ vite.config.ts | 28 +++- yarn.lock | 147 ++++++++++++++++++ 45 files changed, 1124 insertions(+), 64 deletions(-) create mode 100644 src/components/RayGlobalProvider/index.tsx create mode 100644 src/icons/dark.svg create mode 100644 src/icons/dashboard.svg create mode 100644 src/icons/language.svg create mode 100644 src/icons/light.svg create mode 100644 src/icons/lock.svg create mode 100644 src/icons/reload.svg create mode 100644 src/icons/rely.svg create mode 100644 src/icons/setting.svg create mode 100644 src/layout/Menu/index.tsx create mode 100644 src/layout/SiderBar/Components/SettingDrawer/hook.ts create mode 100644 src/layout/SiderBar/Components/SettingDrawer/index.scss create mode 100644 src/layout/SiderBar/Components/SettingDrawer/index.tsx create mode 100644 src/layout/SiderBar/index.scss create mode 100644 src/layout/SiderBar/index.tsx create mode 100644 src/layout/SiderBar/type.ts create mode 100644 src/layout/index.scss create mode 100644 src/layout/index.tsx create mode 100644 src/router/modules/dashboard.ts delete mode 100644 src/router/modules/demo.ts create mode 100644 src/router/modules/rely.ts create mode 100644 src/store/modules/menu.ts create mode 100644 src/styles/setting.scss create mode 100644 src/views/dashboard/index.tsx create mode 100644 src/views/rely/index.tsx create mode 100644 src/views/rely/views/rely-about/index.scss create mode 100644 src/views/rely/views/rely-about/index.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index b45a78f4..054ef4e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,4 @@ { - "i18n-ally.localesPaths": [ - "locales", - "src/language" - ] -} \ No newline at end of file + "i18n-ally.localesPaths": ["locales", "src/language"], + "i18n-ally.keystyle": "nested" +} diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 46fa1680..58e06e8c 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -144,6 +144,7 @@ declare global { const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] + const useDialog: typeof import('naive-ui')['useDialog'] const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] const useDraggable: typeof import('@vueuse/core')['useDraggable'] @@ -176,6 +177,7 @@ declare global { const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] + const useLoadingBar: typeof import('naive-ui')['useLoadingBar'] const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] @@ -183,6 +185,7 @@ declare global { const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] const useMemoize: typeof import('@vueuse/core')['useMemoize'] const useMemory: typeof import('@vueuse/core')['useMemory'] + const useMessage: typeof import('naive-ui')['useMessage'] const useMounted: typeof import('@vueuse/core')['useMounted'] const useMouse: typeof import('@vueuse/core')['useMouse'] const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] @@ -190,6 +193,7 @@ declare global { const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] const useNetwork: typeof import('@vueuse/core')['useNetwork'] + const useNotification: typeof import('naive-ui')['useNotification'] const useNow: typeof import('@vueuse/core')['useNow'] const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] diff --git a/locales/en-US.json b/locales/en-US.json index 4ee7cd68..d05ffa64 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -1,3 +1,21 @@ { - "Test": "Test" + "GlobalMenuOptions": { + "Dashboard": "Home", + "Rely": "Rely", + "RelyAbout": "Rely About" + }, + "LayoutHeaderTooltipOptions": { + "Reload": "Reload Current Page", + "Lock": "Lock", + "Setting": "Setting" + }, + "LayoutHeaderSettingOptions": { + "Title": "Configuration", + "ThemeOptions": { + "Title": "Theme", + "Dark": "Dark", + "Light": "Light", + "PrimaryColorConfig": "Primary Color" + } + } } diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 98c4adfa..2a59a9e8 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -1,3 +1,21 @@ { - "Test": "测试" + "GlobalMenuOptions": { + "Dashboard": "首页", + "Rely": "依赖项", + "RelyAbout": "关于" + }, + "LayoutHeaderTooltipOptions": { + "Reload": "刷新当前页面", + "Lock": "锁屏", + "Setting": "设置" + }, + "LayoutHeaderSettingOptions": { + "Title": "项目配置", + "ThemeOptions": { + "Title": "主题", + "Dark": "暗色", + "Light": "明亮", + "PrimaryColorConfig": "主题色" + } + } } diff --git a/package.json b/package.json index b6d6dbb5..cbf19721 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "vue3-ts-template", + "name": "ray-template", "private": true, "version": "0.0.0", "type": "module", @@ -15,6 +15,7 @@ "amfe-flexible": "^2.2.1", "axios": "^0.27.2", "crypto-js": "^4.1.1", + "naive-ui": "^2.34.0", "pinia": "^2.0.17", "sass": "^1.54.3", "scrollreveal": "^4.0.9", diff --git a/src/App.tsx b/src/App.tsx index 4671f559..3365e51b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,50 +1,28 @@ -import { defineComponent } from 'vue' -import RayTransitionComponent from '@/components/RayTransitionComponent/index.vue' // 动画路由组件 -import DraggableComponent from '@/components/DraggableComponent/index.vue' -import RayScrollReveal from '@/components/RayScrollReveal/index' -import R from '@/icons/ray.svg' // 使用 `vite-svg-loader` 作为 `svg` 使用插件, 故而不需要使用 `RayIcon` 作为组件引入 -import RayIcon from '@/components/RayIcon/index' // `svg` 图标组件 +import RayGlobalProvider from '@/components/RayGlobalProvider/index' +import { useSetting } from '@/store' +import { RouterView } from 'vue-router' const App = defineComponent({ name: 'App', setup() { - const { x, y } = useMouse() + const settingStore = useSetting() const { height: windowHeight } = useWindowSize() - const { t } = useI18n() + const { settingState } = $(storeToRefs(settingStore)) + + // const naiveTheme = computed(() => + // settingState.themeValue ? darkTheme : undefined, + // ) return { - x, - y, windowHeight, - ray: t, + // naiveTheme, } }, render() { return ( -
- 组件形式使用 svg: -
- icon componet 形式使用 svg: -
- hello! Welcome to this template! -

- 当前鼠标位置: x: {this.x}, y: {this.y} -

-

测试 i18n {this.ray('Test')}

- - {Array.from({ length: 10 }, (_, i) => i).map((_, idx) => ( - -
- {idx} -
-
- ))} -
+ + + ) }, }) diff --git a/src/components/RayGlobalProvider/index.tsx b/src/components/RayGlobalProvider/index.tsx new file mode 100644 index 00000000..670a94de --- /dev/null +++ b/src/components/RayGlobalProvider/index.tsx @@ -0,0 +1,49 @@ +import { + NDialogProvider, + NLoadingBarProvider, + NMessageProvider, + NNotificationProvider, + NConfigProvider, + NGlobalStyle, + darkTheme, +} from 'naive-ui' +import { useSetting } from '@/store' + +const GlobalProvider = defineComponent({ + name: 'GlobalProvider', + setup() { + const settingStore = useSetting() + + const modelPrimaryColorOverride = computed( + () => settingStore.primaryColorOverride, + ) + const modelThemeValue = computed(() => + settingStore.themeValue ? darkTheme : null, + ) + + return { + modelPrimaryColorOverride, + modelThemeValue, + } + }, + render() { + return ( + + + + + + {this.$slots.default?.()} + + + + + + ) + }, +}) + +export default GlobalProvider diff --git a/src/components/RayIcon/index.tsx b/src/components/RayIcon/index.tsx index 83a9dc76..efea8596 100644 --- a/src/components/RayIcon/index.tsx +++ b/src/components/RayIcon/index.tsx @@ -21,11 +21,11 @@ const RayIcon = defineComponent({ }, width: { type: [Number, String], - default: 14, + default: 0, }, height: { type: [Number, String], - default: 14, + default: 0, }, customClassName: { type: String, diff --git a/src/icons/dark.svg b/src/icons/dark.svg new file mode 100644 index 00000000..9c69a797 --- /dev/null +++ b/src/icons/dark.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/icons/dashboard.svg b/src/icons/dashboard.svg new file mode 100644 index 00000000..f680d2a8 --- /dev/null +++ b/src/icons/dashboard.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/icons/language.svg b/src/icons/language.svg new file mode 100644 index 00000000..cd6e9aa9 --- /dev/null +++ b/src/icons/language.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/icons/light.svg b/src/icons/light.svg new file mode 100644 index 00000000..2df0d3e2 --- /dev/null +++ b/src/icons/light.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/icons/lock.svg b/src/icons/lock.svg new file mode 100644 index 00000000..12e8dcf5 --- /dev/null +++ b/src/icons/lock.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/icons/reload.svg b/src/icons/reload.svg new file mode 100644 index 00000000..ac935338 --- /dev/null +++ b/src/icons/reload.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/icons/rely.svg b/src/icons/rely.svg new file mode 100644 index 00000000..3bb8d53d --- /dev/null +++ b/src/icons/rely.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/icons/setting.svg b/src/icons/setting.svg new file mode 100644 index 00000000..c3de195b --- /dev/null +++ b/src/icons/setting.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/language/index.ts b/src/language/index.ts index 062e4ed6..960407b8 100644 --- a/src/language/index.ts +++ b/src/language/index.ts @@ -20,6 +20,17 @@ export const setupI18n = (app: App) => { app.use(i18n) } +export const useLanguageOptions = () => [ + { + key: 'zh-CN', + label: '中文(简体)', + }, + { + key: 'en-US', + label: 'English(US)', + }, +] + /** * * 注册 `vue-i18n` diff --git a/src/layout/Menu/index.tsx b/src/layout/Menu/index.tsx new file mode 100644 index 00000000..27231754 --- /dev/null +++ b/src/layout/Menu/index.tsx @@ -0,0 +1,46 @@ +import { NMenu, NLayoutSider } from 'naive-ui' +import { useMenu } from '@/store' + +const LayoutMenu = defineComponent({ + name: 'LayoutMenu', + setup() { + const menuStore = useMenu() + const { menuModelValueChange, setupAppRoutes, collapsedMenu } = menuStore + const modelMenuKey = ref(menuStore.menuKey) + const modelMenuOptions = computed(() => menuStore.options) + const modelCollapsed = computed(() => menuStore.collapsed) + + setupAppRoutes() + + return { + modelMenuKey, + menuModelValueChange, + modelMenuOptions, + modelCollapsed, + collapsedMenu, + } + }, + render() { + return ( + + + + ) + }, +}) + +export default LayoutMenu diff --git a/src/layout/SiderBar/Components/SettingDrawer/hook.ts b/src/layout/SiderBar/Components/SettingDrawer/hook.ts new file mode 100644 index 00000000..6c7bba2b --- /dev/null +++ b/src/layout/SiderBar/Components/SettingDrawer/hook.ts @@ -0,0 +1,9 @@ +import { getCache } from '@/utils/cache' + +export const useSwatchesColorOptions = () => [ + '#FFFFFF', + '#18A058', + '#2080F0', + '#F0A020', + 'rgba(208, 48, 80, 1)', +] diff --git a/src/layout/SiderBar/Components/SettingDrawer/index.scss b/src/layout/SiderBar/Components/SettingDrawer/index.scss new file mode 100644 index 00000000..56effcc9 --- /dev/null +++ b/src/layout/SiderBar/Components/SettingDrawer/index.scss @@ -0,0 +1,3 @@ +.setting-drawer__space { + width: 100%; +} diff --git a/src/layout/SiderBar/Components/SettingDrawer/index.tsx b/src/layout/SiderBar/Components/SettingDrawer/index.tsx new file mode 100644 index 00000000..a9bfcaf6 --- /dev/null +++ b/src/layout/SiderBar/Components/SettingDrawer/index.tsx @@ -0,0 +1,129 @@ +import './index.scss' +import { + NDrawer, + NDrawerContent, + NDivider, + NSpace, + NSwitch, + NColorPicker, + NTooltip, +} from 'naive-ui' +import RayIcon from '@/components/RayIcon/index' +import { useSwatchesColorOptions } from './hook' +import { useSetting } from '@/store' + +import type { PropType } from 'vue' + +const SettingDrawer = defineComponent({ + name: 'SettingDrawer', + props: { + show: { + type: Boolean, + default: false, + }, + placement: { + type: String as PropType, + default: 'right', + }, + width: { + type: Number, + default: 280, + }, + }, + emits: ['update:show'], + setup(props, { emit }) { + const { t } = useI18n() + const settingStore = useSetting() + + const { changeTheme, changePrimaryColor } = settingStore + const { themeValue, primaryColorOverride } = storeToRefs(settingStore) + + const modelShow = computed({ + get: () => props.show, + set: (bool) => { + emit('update:show', bool) + }, + }) + + const handleRailStyle = () => ({ + backgroundColor: '#000000', + }) + + return { + modelShow, + ray: t, + handleRailStyle, + changePrimaryColor, + changeTheme, + themeValue, + primaryColorOverride, + } + }, + render() { + return ( + + + + + {this.ray('LayoutHeaderSettingOptions.ThemeOptions.Title')} + + + + {{ + trigger: () => ( + + {{ + 'checked-icon': () => + h( + RayIcon, + { + name: 'dark', + }, + {}, + ), + 'unchecked-icon': () => + h( + RayIcon, + { + name: 'light', + }, + {}, + ), + }} + + ), + default: () => + this.themeValue + ? this.ray('LayoutHeaderSettingOptions.ThemeOptions.Dark') + : this.ray( + 'LayoutHeaderSettingOptions.ThemeOptions.Light', + ), + }} + + + + {this.ray( + 'LayoutHeaderSettingOptions.ThemeOptions.PrimaryColorConfig', + )} + + + + + + ) + }, +}) + +export default SettingDrawer diff --git a/src/layout/SiderBar/index.scss b/src/layout/SiderBar/index.scss new file mode 100644 index 00000000..83c39953 --- /dev/null +++ b/src/layout/SiderBar/index.scss @@ -0,0 +1,16 @@ +.layout-header { + height: $layoutHeaderHeight; + padding: 0 $layoutRouterViewContainer; + display: flex; + align-items: center; + + > .layout-header__method { + width: 100%; + + & .layout-header__method--icon { + cursor: pointer; + outline: none; + border: none; + } + } +} diff --git a/src/layout/SiderBar/index.tsx b/src/layout/SiderBar/index.tsx new file mode 100644 index 00000000..9f41482d --- /dev/null +++ b/src/layout/SiderBar/index.tsx @@ -0,0 +1,144 @@ +import './index.scss' +import { NLayoutHeader, NSpace, NTooltip, NDropdown } from 'naive-ui' +import RayIcon from '@/components/RayIcon/index' +import { useMenu, useSetting } from '@/store' +import { useLanguageOptions } from '@/language/index' +import SettingDrawer from './Components/SettingDrawer/index' + +import type { IconEventMapOptions, IconEventMap } from './type' + +const SiderBar = defineComponent({ + name: 'SiderBar', + setup() { + const menuStore = useMenu() + const settingStore = useSetting() + + const { t } = useI18n() + const { changeReloadLog } = menuStore + const { updateLocale } = settingStore + const modelDrawerPlacement = ref(settingStore.drawerPlacement) + const showSettings = ref(false) + + const leftIconOptions = [ + { + name: 'reload', + size: 18, + tooltip: 'LayoutHeaderTooltipOptions.Reload', + }, + ] + const rightIconOptions = [ + { + name: 'language', + size: 18, + tooltip: '', + dropdown: { + methodName: 'handleSelect', // 默认为 `handleSelect` + switch: true, + options: useLanguageOptions(), + handleSelect: (key: string | number) => updateLocale(String(key)), + }, + }, + // { + // name: 'lock', + // size: 18, + // tooltip: 'LayoutHeaderTooltipOptions.Lock', + // }, + { + name: 'setting', + size: 18, + tooltip: 'LayoutHeaderTooltipOptions.Setting', + }, + ] + const iconEventMap: IconEventMapOptions = { + reload: () => { + changeReloadLog(false) + + setTimeout(() => changeReloadLog(true)) + }, + // lock: () => {}, + setting: () => { + showSettings.value = true + }, + } + + const handleIconClick = (key: IconEventMap) => { + iconEventMap[key]?.() + } + + return { + leftIconOptions, + rightIconOptions, + t, + handleIconClick, + modelDrawerPlacement, + showSettings, + } + }, + render() { + return ( + + + + {this.leftIconOptions.map((curr) => ( + + {{ + trigger: () => ( + + ), + default: () => this.t(curr.tooltip), + }} + + ))} + + + {this.rightIconOptions.map((curr) => + curr.dropdown?.switch ? ( + + + + ) : ( + + {{ + trigger: () => ( + + ), + default: () => this.t(curr.tooltip), + }} + + ), + )} + + + + + ) + }, +}) + +export default SiderBar diff --git a/src/layout/SiderBar/type.ts b/src/layout/SiderBar/type.ts new file mode 100644 index 00000000..daf5ba5b --- /dev/null +++ b/src/layout/SiderBar/type.ts @@ -0,0 +1,5 @@ +export interface IconEventMapOptions { + [propName: string]: (...args: unknown[]) => unknown +} + +export type IconEventMap = keyof IconEventMapOptions diff --git a/src/layout/index.scss b/src/layout/index.scss new file mode 100644 index 00000000..c2dd7908 --- /dev/null +++ b/src/layout/index.scss @@ -0,0 +1,12 @@ +.layout { + box-sizing: border-box; + + > .layout-full { + height: 100%; + } + + & .layout-content__router-view { + height: calc(100% - $layoutHeaderHeight); + padding: $layoutRouterViewContainer; + } +} diff --git a/src/layout/index.tsx b/src/layout/index.tsx new file mode 100644 index 00000000..6d0d86bf --- /dev/null +++ b/src/layout/index.tsx @@ -0,0 +1,41 @@ +import './index.scss' +import { NLayout, NLayoutContent } from 'naive-ui' +import RayTransitionComponent from '@/components/RayTransitionComponent/index.vue' +import LayoutMenu from './Menu/index' +import SiderBar from './SiderBar/index' +import { useMenu } from '@/store' + +const Layout = defineComponent({ + name: 'Layout', + props: {}, + setup() { + const menuStore = useMenu() + const { height: windowHeight } = useWindowSize() + const modelReloadRoute = computed(() => menuStore.reloadRouteLog) + + return { + windowHeight, + modelReloadRoute, + } + }, + render() { + return ( +
+ + + + + + {this.modelReloadRoute ? : ''} + + + +
+ ) + }, +}) + +export default Layout diff --git a/src/main.ts b/src/main.ts index d8073988..ac36d808 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,11 @@ import 'virtual:svg-icons-register' // `vite-plugin-svg-icons` 脚本, 如果不 import App from './App' -import { setupRouter, setupRouterLoadingBar } from './router/index' +import { + setupRouter, + setupRouterLoadingBar, + permissionRouter, +} from './router/index' import { setupStore } from './store/index' import { setupI18n } from './language/index' @@ -20,11 +24,13 @@ import { setupI18n } from './language/index' const setupTemplate = () => { const app = createApp(App) + setupStore(app) + setupRouter(app) setupRouterLoadingBar() - setupStore(app) + permissionRouter() setupI18n(app) @@ -42,11 +48,13 @@ const setupWujieTemplate = () => { window.__WUJIE_MOUNT = () => { instance = createApp(App) + setupStore(instance) + setupRouter(instance) setupRouterLoadingBar() - setupStore(instance) + permissionRouter() setupI18n(instance) diff --git a/src/router/index.ts b/src/router/index.ts index 3b78ef80..9cce3b77 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -31,3 +31,11 @@ export const setupRouterLoadingBar = () => { window?.$loadingBar?.error() }) } + +/** + * + * 路由权限守卫 + */ +export const permissionRouter = () => { + // router.beforeEach() +} diff --git a/src/router/modules/dashboard.ts b/src/router/modules/dashboard.ts new file mode 100644 index 00000000..3394a8f2 --- /dev/null +++ b/src/router/modules/dashboard.ts @@ -0,0 +1,9 @@ +export default { + path: '/dashboard', + name: 'dashboard', + component: () => import('@/views/dashboard/index'), + meta: { + i18nKey: 'Dashboard', + icon: 'dashboard', + }, +} diff --git a/src/router/modules/demo.ts b/src/router/modules/demo.ts deleted file mode 100644 index ab4e9ab1..00000000 --- a/src/router/modules/demo.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - path: '/', - name: 'dmeo', - component: () => import('@/App'), -} diff --git a/src/router/modules/index.ts b/src/router/modules/index.ts index 7f87099b..4ad7e60b 100644 --- a/src/router/modules/index.ts +++ b/src/router/modules/index.ts @@ -1,6 +1,7 @@ -import demo from './demo' +import dashboard from './dashboard' +import reyl from './rely' -const routes = [demo] +const routes = [dashboard, reyl] export default routes diff --git a/src/router/modules/rely.ts b/src/router/modules/rely.ts new file mode 100644 index 00000000..bba82e47 --- /dev/null +++ b/src/router/modules/rely.ts @@ -0,0 +1,19 @@ +export default { + path: '/rely', + name: 'rely', + component: () => import('@/views/rely/index'), + meta: { + i18nKey: 'Rely', + icon: 'rely', + }, + children: [ + { + path: '/rely-about', + name: 'rely-about', + component: () => import('@/views/rely/views/rely-about/index'), + meta: { + i18nKey: 'RelyAbout', + }, + }, + ], +} diff --git a/src/router/routes.ts b/src/router/routes.ts index 21d258ce..cd08032b 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -1,8 +1,13 @@ +import Layout from '@/layout/index' +import childrenRoutes from './modules/index' + export const constantRoutes = [ { path: '/', - name: 'demo-active', - component: () => import('@/App'), + name: 'layout', + redirect: '/dashboard', + component: Layout, + children: childrenRoutes, }, ] diff --git a/src/store/index.ts b/src/store/index.ts index 85659a90..6f394921 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,6 +1,7 @@ import type { App } from 'vue' export { useSetting } from './modules/setting' // import { useSetting } from '@/store' 即可使用 +export { useMenu } from './modules/menu' const store = createPinia() diff --git a/src/store/modules/menu.ts b/src/store/modules/menu.ts new file mode 100644 index 00000000..9850bead --- /dev/null +++ b/src/store/modules/menu.ts @@ -0,0 +1,99 @@ +import { getCache, setCache } from '@/utils/cache' +import { NEllipsis } from 'naive-ui' +import RayIcon from '@/components/RayIcon/index' + +import type { MenuOption } from 'naive-ui' +import type { RouteRecordRaw } from 'vue-router' + +export const useMenu = defineStore('menu', () => { + const router = useRouter() + const { t } = useI18n() + + const cacheMenuKey = getCache('menuKey') === 'no' ? '' : getCache('menuKey') + + const menuState = reactive({ + menuKey: cacheMenuKey as string | null, // 当前菜单 `key` + options: [] as RouteRecordRaw[], // 菜单列表 + collapsed: false, // 是否折叠菜单 + reloadRouteLog: true, // 刷新路由开关 + }) + + /** + * + * @param key 菜单更新后的 `key` + * @param item 菜单当前 `item` + * + * 修改 `menu key` 后的回调函数 + */ + const menuModelValueChange = (key: string, item: MenuOption) => { + menuState.menuKey = key + + router.push(`${item.path}`) + setCache('menuKey', key) + } + + /** + * + * 获取菜单列表 + * 缓存菜单 + */ + const setupAppRoutes = () => { + const layout = router.getRoutes().find((route) => route.name === 'layout') + + const resolveRoutes = (routes: RouteRecordRaw[], index: number) => { + return routes.map((curr) => { + if (curr.children?.length) { + curr.children = resolveRoutes( + curr.children as RouteRecordRaw[], + index++, + ) + } + + const route = { + ...curr, + key: curr.path, + label: () => + h(NEllipsis, null, { + default: () => t(`GlobalMenuOptions.${curr!.meta!.i18nKey}`), + }), + } + const expandIcon = { + icon: () => + h( + RayIcon, + { + name: curr?.meta?.icon as string, + size: 20, + }, + {}, + ), + } + + return curr.meta?.icon ? Object.assign(route, expandIcon) : route + }) + } + + menuState.options = resolveRoutes(layout?.children as RouteRecordRaw[], 0) + } + + /** + * + * @param collapsed 折叠菜单开关 + */ + const collapsedMenu = (collapsed: boolean) => + (menuState.collapsed = collapsed) + + /** + * + * @param bool 刷新页面开关 + */ + const changeReloadLog = (bool: boolean) => (menuState.reloadRouteLog = bool) + + return { + ...toRefs(menuState), + menuModelValueChange, + setupAppRoutes, + collapsedMenu, + changeReloadLog, + } +}) diff --git a/src/store/modules/setting.ts b/src/store/modules/setting.ts index 6b438a1b..ad5399bd 100644 --- a/src/store/modules/setting.ts +++ b/src/store/modules/setting.ts @@ -1,15 +1,44 @@ -import { setCache } from '@/utils/cache' +import { setCache, getCache } from '@/utils/cache' export const useSetting = defineStore('setting', () => { - const settingState = reactive({}) + const cachePrimaryColor: string = + getCache('primaryColor') === 'no' ? '#18A058' : getCache('primaryColor') + const cacheTheme = getCache('theme') === 'no' ? false : getCache('theme') + + const settingState = reactive({ + drawerPlacement: 'right' as NaiveDrawerPlacement, + primaryColorOverride: { + common: { + primaryColor: cachePrimaryColor, // 主题色 + }, + }, + themeValue: cacheTheme, // `true` 为黑夜主题, `false` 为白色主题 + }) + const { locale } = useI18n() const updateLocale = (key: string) => { // TODO: 修改语言 + locale.value = key + setCache('localeLanguage', key, 'localStorage') } + const changeTheme = (bool: boolean) => { + settingState.themeValue = bool + + setCache('theme', bool) + } + + const changePrimaryColor = (value: string) => { + settingState.primaryColorOverride.common.primaryColor = value + + setCache('primaryColor', value) + } + return { - settingState, + ...toRefs(settingState), updateLocale, + changeTheme, + changePrimaryColor, } }) diff --git a/src/styles/setting.scss b/src/styles/setting.scss new file mode 100644 index 00000000..d7aeb144 --- /dev/null +++ b/src/styles/setting.scss @@ -0,0 +1,2 @@ +$layoutRouterViewContainer: 18px; +$layoutHeaderHeight: 64px; diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 7ae75d5b..81fc77e7 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -6,10 +6,27 @@ import type { DialogApi, LoadingBarApi, NotificationApi, + MenuOption, + MenuDividerOption, + MenuGroupOption, } from 'naive-ui' export global { - interface Window { + const __APP_INFO__: { + pkg: { + name: string + version: string + dependencies: Recordable + devDependencies: Recordable + } + } + + declare type NaiveMenuOptions = + | MenuOption + | MenuDividerOption + | MenuGroupOption + + declare interface Window { // 是否存在无界 __POWERED_BY_WUJIE__?: boolean // 子应用公共加载路径 @@ -69,4 +86,6 @@ export global { declare type CipherParams = CryptoJS.lib.CipherParams declare type VoidFunc = (...args: unknown[]) => void + + declare type NaiveDrawerPlacement = 'top' | 'right' | 'bottom' | 'left' } diff --git a/src/views/dashboard/index.tsx b/src/views/dashboard/index.tsx new file mode 100644 index 00000000..42f76f7b --- /dev/null +++ b/src/views/dashboard/index.tsx @@ -0,0 +1,13 @@ +import { defineComponent } from 'vue' + +const Dashboard = defineComponent({ + name: 'Dashboard', + setup() { + return {} + }, + render() { + return
Dashboard
+ }, +}) + +export default Dashboard diff --git a/src/views/rely/index.tsx b/src/views/rely/index.tsx new file mode 100644 index 00000000..9f64f577 --- /dev/null +++ b/src/views/rely/index.tsx @@ -0,0 +1,13 @@ +import RayTransitionComponent from '@/components/RayTransitionComponent/index.vue' + +const Rely = defineComponent({ + name: 'Rely', + setup() { + return {} + }, + render() { + return + }, +}) + +export default Rely diff --git a/src/views/rely/views/rely-about/index.scss b/src/views/rely/views/rely-about/index.scss new file mode 100644 index 00000000..cd64631a --- /dev/null +++ b/src/views/rely/views/rely-about/index.scss @@ -0,0 +1,9 @@ +.rely-about { + & .n-card { + margin-top: 18px; + + &:first-child { + margin-top: 0; + } + } +} diff --git a/src/views/rely/views/rely-about/index.tsx b/src/views/rely/views/rely-about/index.tsx new file mode 100644 index 00000000..c2f2589b --- /dev/null +++ b/src/views/rely/views/rely-about/index.tsx @@ -0,0 +1,126 @@ +import './index.scss' +import { NCard, NDescriptions, NDescriptionsItem, NTag } from 'naive-ui' + +interface RelyDataOptions { + name: string + relyVersion: string + relyAddress: string +} + +interface TemplateOptions { + name: string + label: string + url?: string +} + +const RelyAbout = defineComponent({ + name: 'RelyAbout', + setup() { + const { pkg } = __APP_INFO__ + const { dependencies, devDependencies, name, version } = pkg + + const columns = [ + { + title: '依赖名称', + key: 'name', + }, + { + title: '依赖版本', + key: 'relyVersion', + }, + { + title: '依赖地址', + key: 'relyAddress', + }, + ] + const relyData = ref([]) + const templateOptions = [ + { + name: '项目名称', + label: name, + }, + { + name: '版本信息', + label: version, + }, + { + name: '项目地址', + label: 'GitHub', + url: 'https://github.com/XiaoDaiGua-Ray/ray-template', + }, + ] + + const handleGetRelyData = () => { + const _arrayFrom = (obj: object) => + Object.keys(obj).reduce((pre, curr) => { + pre.push({ + name: curr, + relyVersion: obj[curr], + relyAddress: '', + }) + + return pre + }, [] as RelyDataOptions[]) + + const arrDependencies = _arrayFrom(dependencies) + const arrDevDependencies = _arrayFrom(devDependencies) + + relyData.value = [...arrDependencies, ...arrDevDependencies] + } + + const handleTagClick = (item: TemplateOptions) => { + if (item.url) { + window.open(item.url) + } + } + + onBeforeMount(() => { + handleGetRelyData() + }) + + return { + columns, + relyData, + templateOptions, + handleTagClick, + } + }, + render() { + return ( +
+ + ray-template 是一个基于 vue3、vite3、TypeScript 的中后台解决方案, + 它可以帮助你快速搭建企业级中后台项目, + 相信不管是从新技术使用还是其他方面, 都能帮助到你,持续更新中. + + + + {this.templateOptions.map((curr) => ( + + + {curr.label} + + + ))} + + + + + {this.relyData.map((curr) => ( + + {curr.relyVersion} + + ))} + + +
+ ) + }, +}) + +export default RelyAbout diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index a179b8fb..c6578016 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -3,8 +3,27 @@ /// /// +import 'vue-router' + declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component } + +declare module 'vue-router' { + interface RouteMeta { + i18nKey: string + icon?: string + } +} + +declare module '*.json' { + const jsonValue: any + export default jsonValue +} + +declare module 'virtual:*' { + const result: any + export default result +} diff --git a/vite.config.ts b/vite.config.ts index 01ef0581..fe22ee56 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,12 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' +const pkg = require('./package.json') + +const { dependencies, devDependencies, name, version } = pkg + +const __APP_INFO__ = { + pkg: { dependencies, devDependencies, name, version }, +} import { useAliasOptions, @@ -19,11 +26,16 @@ import ViteInspect from 'vite-plugin-inspect' import viteSvgLoader from 'vite-svg-loader' import viteEslintPlugin from 'vite-plugin-eslint' +import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' + // https://vitejs.dev/config/ export default defineConfig(async ({ mode }) => { const { buildOptions } = useEnvBuildOutput(mode) return { + define: { + __APP_INFO__: JSON.stringify(__APP_INFO__), + }, resolve: { alias: useAliasOptions(), }, @@ -32,8 +44,17 @@ export default defineConfig(async ({ mode }) => { vueJsx(), ViteInspect(), // 仅适用于开发模式(检查 `Vite` 插件的中间状态) VueI18nPlugin(), - await useAutoImport(), - await useViteComponents(), + await useAutoImport([ + { + 'naive-ui': [ + 'useDialog', + 'useMessage', + 'useNotification', + 'useLoadingBar', + ], + }, + ]), + await useViteComponents([NaiveUiResolver()]), useViteCompression(), useVueI18nPlugin(), useHTMLTitlePlugin(), @@ -62,7 +83,8 @@ export default defineConfig(async ({ mode }) => { css: { preprocessorOptions: { scss: { - additionalData: '@import "./src/styles/mixins.scss";', // 全局 `mixin` + additionalData: + '@import "./src/styles/mixins.scss"; @import "./src/styles/setting.scss";', // 全局 `mixin` }, }, }, diff --git a/yarn.lock b/yarn.lock index 8320d79d..f3dbd889 100644 --- a/yarn.lock +++ b/yarn.lock @@ -406,6 +406,21 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@css-render/plugin-bem@^0.15.10": + version "0.15.11" + resolved "https://registry.yarnpkg.com/@css-render/plugin-bem/-/plugin-bem-0.15.11.tgz#250b853704af1fbb935b8fcd987839dcc9c95ce2" + integrity sha512-Bn8qadYPIz5DhZ4obTGHOJzeziQH6kY0+Fk5AEvwuuy378SLwwvXuuoechLjBHcgKkPCM03Oo4dDSGP/6NMdyw== + +"@css-render/vue3-ssr@^0.15.10": + version "0.15.11" + resolved "https://registry.yarnpkg.com/@css-render/vue3-ssr/-/vue3-ssr-0.15.11.tgz#d6646f69c7bd4b54485a40441ac60102822cd492" + integrity sha512-n+SuqLPbY30FUTM8slX75OaEG+c8XlTOFrAklekX2XQGvBbz9XdBE6hTEgGlV5kPcTMqTJeCG7Vzhs9/29VC7w== + +"@emotion/hash@~0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + "@esbuild/android-arm@0.15.14": version "0.15.14" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.14.tgz#5d0027f920eeeac313c01fd6ecb8af50c306a466" @@ -570,6 +585,11 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@juggle/resize-observer@^3.3.1": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" + integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== + "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" @@ -644,11 +664,33 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/katex@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.14.0.tgz#b84c0afc3218069a5ad64fe2a95321881021b5fe" + integrity sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA== + +"@types/lodash-es@^4.17.6": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.6.tgz#c2ed4c8320ffa6f11b43eb89e9eaeec65966a0a0" + integrity sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*", "@types/lodash@^4.14.181": + version "4.14.189" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.189.tgz#975ff8c38da5ae58b751127b19ad5e44b5b7f6d2" + integrity sha512-kb9/98N6X8gyME9Cf7YaqIMvYGnBSWqEci6tiettE6iJWH1XdJz/PO8LB0GtLCG7x8dU3KWhZT+lA1a35127tA== + "@types/node@*": version "18.11.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.7.tgz#8ccef136f240770c1379d50100796a6952f01f94" integrity sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ== +"@types/node@~17.0.5": + version "17.0.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== + "@types/scrollreveal@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/scrollreveal/-/scrollreveal-0.0.8.tgz#d0313ac67b57a32b3beb224e20af63ab13cd2696" @@ -1149,6 +1191,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== +async-validator@^4.0.7: + version "4.2.5" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339" + integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1461,6 +1508,15 @@ crypto-js@^4.1.1: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== +css-render@^0.15.10: + version "0.15.11" + resolved "https://registry.yarnpkg.com/css-render/-/css-render-0.15.11.tgz#52a77cd8335394485be2417675121c2efe954bb5" + integrity sha512-hnLrHPUndVUTF5nmNPRey6hpixK02IPUGdEsm2xRjvJuewToyrVFx9Nmai8rgfVzhTFo5SJVh2PHAtzaIV8JKw== + dependencies: + "@emotion/hash" "~0.8.0" + "@types/node" "~17.0.5" + csstype "~3.0.5" + css-select@^4.1.3: version "4.3.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" @@ -1502,6 +1558,21 @@ csstype@^2.6.8: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== +csstype@~3.0.5: + version "3.0.11" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" + integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== + +date-fns-tz@^1.3.3: + version "1.3.7" + resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-1.3.7.tgz#e8e9d2aaceba5f1cc0e677631563081fdcb0e69a" + integrity sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g== + +date-fns@^2.28.0: + version "2.29.3" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" + integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== + de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" @@ -2142,6 +2213,11 @@ etag@^1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +evtd@^0.2.2, evtd@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/evtd/-/evtd-0.2.4.tgz#0aac39ba44d6926e6668948ac27618e0795b9d07" + integrity sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw== + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2524,6 +2600,11 @@ he@^1.1.1, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +highlight.js@^11.5.0: + version "11.6.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.6.0.tgz#a50e9da05763f1bb0c1322c8f4f755242cff3f5a" + integrity sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw== + html-tags@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" @@ -2970,6 +3051,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -3152,6 +3238,30 @@ muggle-string@^0.1.0: resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.1.0.tgz#1fda8a281c8b27bb8b70466dbc9f27586a8baa6c" integrity sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg== +naive-ui@^2.34.0: + version "2.34.0" + resolved "https://registry.yarnpkg.com/naive-ui/-/naive-ui-2.34.0.tgz#115cf42d4217019bd7322f2da1b0cac15e006f8f" + integrity sha512-WJtGRc0BHMbCBYCbTYGlEtG3TC3yTyAK5rTQdsIAm6ZYGFbnA6KVDtNXx2Ucd5dyH9V+iwaBXTO3oPRs7PiPoQ== + dependencies: + "@css-render/plugin-bem" "^0.15.10" + "@css-render/vue3-ssr" "^0.15.10" + "@types/katex" "^0.14.0" + "@types/lodash" "^4.14.181" + "@types/lodash-es" "^4.17.6" + async-validator "^4.0.7" + css-render "^0.15.10" + date-fns "^2.28.0" + date-fns-tz "^1.3.3" + evtd "^0.2.4" + highlight.js "^11.5.0" + lodash "^4.17.21" + lodash-es "^4.17.21" + seemly "^0.3.6" + treemate "^0.3.11" + vdirs "^0.1.8" + vooks "^0.2.12" + vueuc "^0.4.47" + nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" @@ -3709,6 +3819,11 @@ scule@^0.3.2: resolved "https://registry.yarnpkg.com/scule/-/scule-0.3.2.tgz#472445cecd8357165a94a067f78cee40e700b596" integrity sha512-zIvPdjOH8fv8CgrPT5eqtxHQXmPNnV/vHJYffZhE43KZkvULvpCTvOt1HPlFaCZx287INL9qaqrZg34e8NgI4g== +seemly@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/seemly/-/seemly-0.3.6.tgz#7ef97e8083dea00804965e2662f572a5df9cb18e" + integrity sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw== + semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -4078,6 +4193,11 @@ traverse@^0.6.6: resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" integrity sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw== +treemate@^0.3.11: + version "0.3.11" + resolved "https://registry.yarnpkg.com/treemate/-/treemate-0.3.11.tgz#7d52f8f69ab9ce326f8d139e0a3d1ffb25e48222" + integrity sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg== + tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" @@ -4256,6 +4376,13 @@ vary@^1: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vdirs@^0.1.4, vdirs@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/vdirs/-/vdirs-0.1.8.tgz#a103bc43baca738f8dea912a7e9737154a19dbc2" + integrity sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw== + dependencies: + evtd "^0.2.2" + vite-plugin-compression@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz#a75b0d8f48357ebb377b65016da9f20885ef39b6" @@ -4319,6 +4446,13 @@ vite@^3.2.4: optionalDependencies: fsevents "~2.3.2" +vooks@^0.2.12, vooks@^0.2.4: + version "0.2.12" + resolved "https://registry.yarnpkg.com/vooks/-/vooks-0.2.12.tgz#2b6e23330b77bac81c7f7a344c4ca3e9f4f6c373" + integrity sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q== + dependencies: + evtd "^0.2.2" + vue-demi@*: version "0.13.6" resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.6.tgz#f9433cbd75e68a970dec066647f4ba6c08ced48f" @@ -4381,6 +4515,19 @@ vue@^3.2.37: "@vue/server-renderer" "3.2.37" "@vue/shared" "3.2.37" +vueuc@^0.4.47: + version "0.4.49" + resolved "https://registry.yarnpkg.com/vueuc/-/vueuc-0.4.49.tgz#913e6fd629bdfd5bbed79bf108aec605720af2db" + integrity sha512-WarAC44a/Yx78CxkAgROYLq+LkAeCGA/6wHidVoFmHLbzyF3SiP2nzRNGD/8zJeJInXv18EnWK6A//eGgMMq8w== + dependencies: + "@css-render/vue3-ssr" "^0.15.10" + "@juggle/resize-observer" "^3.3.1" + css-render "^0.15.10" + evtd "^0.2.4" + seemly "^0.3.6" + vdirs "^0.1.4" + vooks "^0.2.4" + webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"