diff --git a/apps/admin/package.json b/apps/admin/package.json index a2ade95f..59ba8657 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -29,6 +29,7 @@ "@vben/constants": "workspace:*", "@vben/demo": "workspace:*", "@vben/directives": "workspace:*", + "@vben/grid-layouts": "workspace:*", "@vben/hooks": "workspace:*", "@vben/layouts": "workspace:*", "@vben/locale": "workspace:*", diff --git a/apps/admin/src/layout/index.vue b/apps/admin/src/layout/index.vue index 5c799f0f..7bd5fc2d 100644 --- a/apps/admin/src/layout/index.vue +++ b/apps/admin/src/layout/index.vue @@ -1,6 +1,8 @@ diff --git a/apps/admin/src/pages/demo/editor/monaco-editor.vue b/apps/admin/src/pages/demo/editor/monaco-editor.vue index c66a9f90..bfefdf8d 100644 --- a/apps/admin/src/pages/demo/editor/monaco-editor.vue +++ b/apps/admin/src/pages/demo/editor/monaco-editor.vue @@ -1,13 +1,13 @@ - analysis + 业务逻辑测试页面 diff --git a/apps/admin/src/router/guard.ts b/apps/admin/src/router/guard.ts index b480f2a5..44c8bd2e 100644 --- a/apps/admin/src/router/guard.ts +++ b/apps/admin/src/router/guard.ts @@ -7,7 +7,7 @@ import { createTabsGuard, createParamMenuGuard, } from '@vben/router' -import { setRouteChange } from '@/logics/mitt/routeChange' +import { setRouteChange } from '@vben/router' import { useLockStore } from '@/store/lock' async function setupRouteGuard() { diff --git a/apps/admin/src/router/routes/modules/test/test.ts b/apps/admin/src/router/routes/modules/test/test.ts index 487d7217..9fed1bb3 100644 --- a/apps/admin/src/router/routes/modules/test/test.ts +++ b/apps/admin/src/router/routes/modules/test/test.ts @@ -7,17 +7,19 @@ const test: RouteRecordItem = { redirect: '/test/test', meta: { orderNo: 1, - icon: 'mdi:monitor-dashboard', + icon: 'ph:code-bold', title: '测试', + root: true, }, children: [ { path: 'test', - name: 'TTTT', - component: () => import('@/pages/dashboard/analysis/index.vue'), + name: 'ttest', + component: () => import('@/pages/test/test.vue'), meta: { icon: 'mdi:monitor-dashboard', title: 'Test', + collapsedShowTitle: true, }, }, ], diff --git a/apps/admin/src/store/test.ts b/apps/admin/src/store/test.ts deleted file mode 100644 index 6b6e0c3b..00000000 --- a/apps/admin/src/store/test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineStore } from 'pinia' - -export const useTest = defineStore({ - id: 'use--test', - state: () => ({ - test: '人孔盖福利卡', - }), - persist: true, -}) diff --git a/apps/grid-admin/.env b/apps/grid-admin/.env deleted file mode 100644 index 41883baa..00000000 --- a/apps/grid-admin/.env +++ /dev/null @@ -1,5 +0,0 @@ -# spa title -VITE_GLOB_APP_TITLE = Vben Admin - -# spa shortname -VITE_GLOB_APP_SHORT_NAME = vben_admin diff --git a/apps/grid-admin/.env.development b/apps/grid-admin/.env.development deleted file mode 100644 index cbc16168..00000000 --- a/apps/grid-admin/.env.development +++ /dev/null @@ -1,21 +0,0 @@ -# Whether to open mock -VITE_USE_MOCK = true - -# public path -VITE_PUBLIC_PATH = / - -# Cross-domain proxy, you can configure multiple -# Please note that no line breaks -VITE_PROXY = [["/basic-api","http://localhost:3000"]] -# VITE_PROXY=[["/api","https://vvbin.cn/test"]] - -# Whether to enable https and http2 in the development environment -# it will greatly optimize the loading speed at the first startup -# 是否在开发环境开启 https 和 http2(开启后将大幅优化首次启动时加载速度) -VITE_USE_HTTPS = true - -# Delete console -VITE_DROP_CONSOLE = false - -# Basic interface address SPA -VITE_GLOB_API_URL=/basic-api diff --git a/apps/grid-admin/.env.production b/apps/grid-admin/.env.production deleted file mode 100644 index ac329c9c..00000000 --- a/apps/grid-admin/.env.production +++ /dev/null @@ -1,28 +0,0 @@ -# Whether to open mock -VITE_USE_MOCK = true - -# public path -VITE_PUBLIC_PATH = / - -# Delete console -VITE_DROP_CONSOLE = true - -# Whether to enable gzip or brotli compression -# Optional: gzip | brotli | none -# If you need multiple forms, you can use `,` to separate -VITE_BUILD_COMPRESS = 'none' - -# Whether to delete origin files when using compress, default false -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false - -# Basic interface address SPA -VITE_GLOB_API_URL=/basic-api - -# Whether to enable image compression -VITE_USE_IMAGEMIN= true - -# use pwa -VITE_USE_PWA = false - -# Is it compatible with older browsers -VITE_LEGACY = false diff --git a/apps/grid-admin/index.html b/apps/grid-admin/index.html deleted file mode 100644 index 9b193a7f..00000000 --- a/apps/grid-admin/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - <%= title %> - - - - - - - - - - - - - <%= title %> - - - - - - diff --git a/apps/grid-admin/init-components.ts b/apps/grid-admin/init-components.ts deleted file mode 100644 index cf3fa770..00000000 --- a/apps/grid-admin/init-components.ts +++ /dev/null @@ -1,194 +0,0 @@ -// 按需导入组件 -import naive, { - darkTheme, - NTag, - NCard, - NDivider, - NSpace, - NPopover, - NButton, - NAvatar, - NStatistic, - NSelect, - NInput, - NThing, - NPopconfirm, - NIcon, - NIconWrapper, - NCheckbox, - NCheckboxGroup, - NButtonGroup, - NModal, - NEmpty, - NUpload, - NUploadDragger, - NTabs, - NTabPane, - NGrid, - NGridItem, - NEllipsis, - NImage, - NMessageProvider, - useMessage, - NPagination, - NRadio, - NRadioButton, - NRadioGroup, - NText, - NConfigProvider, - NDynamicTags, - NColorPicker, - NDescriptions, - NDescriptionsItem, - useNotification, - NNotificationProvider, - NSwitch, - NMenu, - // dateZhCN, - zhCN, - // darkTheme, - NBreadcrumb, - NBreadcrumbItem, - NLayout, - NLayoutSider, - NLayoutFooter, - NLayoutContent, - NLayoutHeader, - NForm, - NFormItem, - NDropdown, - NInputNumber, - NTreeSelect, - NBadge, - NListItem, - NList, - NAutoComplete, - NCascader, - NDatePicker, - NTimePicker, - NRate, - NSlider, - NTransfer, - NMention, - NFormItemGi, - NTree, - NH1, - NH2, - NH3, - NH4, - NH5, - NH6, - NInputGroupLabel, - NInputGroup, - NDrawer, - NDrawerContent, - NDynamicInput, - NPopselect, - NTime, - NScrollbar, - NElement, - NSkeleton, - NTooltip, - NTab, - NResult, - NAffix, NGradientText -} from 'naive-ui' - -import { initVbenComponent, setNotice, setMessage } from '@vben/vbencomponents' - -export async function registerComponents(app) { - initVbenComponent(app, { - Drawer: NDrawer, - DrawerContent: NDrawerContent, - Tag: NTag, - Card: NCard, - Menu: NMenu, - Divider: NDivider, - Space: NSpace, - Popover: NPopover, - Button: NButton, - ButtonGroup: NButtonGroup, - Avatar: NAvatar, - Statistic: NStatistic, - Select: NSelect, - Input: NInput, - InputGroup: NInputGroup, - InputGroupLabel: NInputGroupLabel, - InputNumber: NInputNumber, - Form: NForm, - FormItem: NFormItem, - Thing: NThing, - Popconfirm: NPopconfirm, - Icon: NIcon, - IconWrapper: NIconWrapper, - Checkbox: NCheckbox, - CheckboxGroup: NCheckboxGroup, - Breadcrumb: NBreadcrumb, - BreadcrumbItem: NBreadcrumbItem, - Modal: NModal, - Empty: NEmpty, - Upload: NUpload, - UploadDragger: NUploadDragger, - Tabs: NTabs, - Tab: NTab, - TabPane: NTabPane, - Grid: NGrid, - GridItem: NGridItem, - Ellipsis: NEllipsis, - Image: NImage, - MessageProvider: NMessageProvider, - Pagination: NPagination, - Radio: NRadio, - RadioButton: NRadioButton, - RadioGroup: NRadioGroup, - Text: NText, - Config: NConfigProvider, - DynamicTags: NDynamicTags, - ColorPicker: NColorPicker, - Descriptions: NDescriptions, - DescriptionsItem: NDescriptionsItem, - NotificationProvider: NNotificationProvider, - Switch: NSwitch, - Layout: NLayout, - LayoutHeader: NLayoutHeader, - LayoutFooter: NLayoutFooter, - LayoutSider: NLayoutSider, - LayoutContent: NLayoutContent, - Dropdown: NDropdown, - TreeSelect: NTreeSelect, - Badge: NBadge, - ListItem: NListItem, - List: NList, - AutoComplete: NAutoComplete, - Cascader: NCascader, - DatePicker: NDatePicker, - TimePicker: NTimePicker, - Rate: NRate, - Slider: NSlider, - Transfer: NTransfer, - Mention: NMention, - FormItemGi: NFormItemGi, - Tree: NTree, - H1: NH1, - H2: NH2, - H3: NH3, - H4: NH4, - H5: NH5, - H6: NH6, - DynamicInput: NDynamicInput, - PopSelect: NPopselect, - Time: NTime, - Scrollbar: NScrollbar, - DarkTheme: darkTheme, - Element: NElement, - Skeleton: NSkeleton, - Tooltip: NTooltip, - Result: NResult, - Affix: NAffix, - GradientText: NGradientText - }) - setMessage(useMessage) - setNotice(useNotification) - // @ts-ignore - // app.use(naive) -} diff --git a/apps/grid-admin/mock/_mock-server.ts b/apps/grid-admin/mock/_mock-server.ts deleted file mode 100644 index ff06484a..00000000 --- a/apps/grid-admin/mock/_mock-server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer' - -const modules = import.meta.globEager('./**/*.ts') - -const mockModules: any[] = [] -Object.keys(modules).forEach((key) => { - if (key.includes('/_')) { - return - } - mockModules.push(...modules[key].default) -}) - -/** - * Used in a production environment. Need to manually import all modules - */ -export const setupProdMockServer = () => createProdMockServer(mockModules) diff --git a/apps/grid-admin/mock/auth.ts b/apps/grid-admin/mock/auth.ts deleted file mode 100644 index 2a6505f0..00000000 --- a/apps/grid-admin/mock/auth.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { MockMethod } from 'vite-plugin-mock' -import { - resultError, - resultSuccess, - getRequestToken, - requestParams, -} from '@vben/utils/mock-util' - -export function createFakeUserList() { - return [ - { - userId: '1', - username: 'vben', - realname: 'Vben Admin', - avatar: 'https://q1.qlogo.cn/g?b=qq&nk=190848757&s=640', - desc: 'manager', - password: '123456', - accessToken: 'fakeToken1', - roles: [ - { - name: 'Super Admin', - value: 'super', - }, - ], - }, - { - userId: '2', - username: 'test', - password: '123456', - realname: 'test user', - avatar: 'https://q1.qlogo.cn/g?b=qq&nk=339449197&s=640', - desc: 'tester', - accessToken: 'fakeToken2', - roles: [ - { - name: 'Tester', - value: 'test', - }, - ], - }, - ] -} - -const fakeCodeList: any = { - '1': ['1000', '3000', '5000'], - - '2': ['2000', '4000', '6000'], -} -export default [ - // mock user login - { - url: '/basic-api/login', - timeout: 200, - method: 'post', - response: ({ body }) => { - const { username, password } = body - - const checkUser = createFakeUserList().find( - (item) => item.username === username && password === item.password, - ) - - if (!checkUser) { - return resultError('Incorrect account or password!') - } - - return resultSuccess(checkUser) - }, - }, - { - url: '/basic-api/getUserInfo', - method: 'get', - response: (request: requestParams) => { - const accessToken = getRequestToken(request) - - if (!accessToken) return resultError('Invalid accessToken.') - const checkUser = createFakeUserList().find( - (item) => item.accessToken === accessToken, - ) - if (!checkUser) { - return resultError( - 'The corresponding user information was not obtained!', - ) - } - return resultSuccess(checkUser) - }, - }, - { - url: '/basic-api/getPermCode', - timeout: 200, - method: 'get', - response: (request: requestParams) => { - const accessToken = getRequestToken(request) - if (!accessToken) return resultError('Invalid accessToken.') - const checkUser = createFakeUserList().find( - (item) => item.accessToken === accessToken, - ) - if (!checkUser) { - return resultError('Invalid accessToken.') - } - const codeList = fakeCodeList[checkUser.userId] - - return resultSuccess(codeList) - }, - }, - { - url: '/basic-api/logout', - timeout: 200, - method: 'get', - response: (request: requestParams) => { - const accessToken = getRequestToken(request) - if (!accessToken) return resultError('Invalid accessToken.') - const checkUser = createFakeUserList().find( - (item) => item.accessToken === accessToken, - ) - if (!checkUser) { - return resultError('Invalid accessToken.') - } - return resultSuccess(undefined, { message: 'Token has been destroyed' }) - }, - }, -] as MockMethod[] diff --git a/apps/grid-admin/mock/demo/form.ts b/apps/grid-admin/mock/demo/form.ts deleted file mode 100644 index f3f33948..00000000 --- a/apps/grid-admin/mock/demo/form.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { MockMethod } from 'vite-plugin-mock' -import { resultError, resultSuccess } from '@vben/utils/mock-util' - -export function createSelectData() { - return { - options: [ - { - label: "Everybody's Got Something to Hide Except Me and My Monkey", - value: 'song0', - disabled: true, - }, - { - label: 'Drive My Car', - value: 'song1', - }, - { - label: 'Norwegian Wood', - value: 'song2', - }, - { - label: "You Won't See", - value: 'song3', - disabled: true, - }, - { - label: 'Nowhere Man', - value: 'song4', - }, - { - label: 'Think For Yourself', - value: 'song5', - }, - { - label: 'The Word', - value: 'song6', - }, - { - label: 'Michelle', - value: 'song7', - disabled: true, - }, - { - label: 'What goes on', - value: 'song8', - }, - { - label: 'Girl', - value: 'song9', - }, - { - label: "I'm looking through you", - value: 'song10', - }, - { - label: 'In My Life', - value: 'song11', - }, - { - label: 'Wait', - value: 'song12', - }, - ], - } -} - -export function createTreeSelectData() { - return { - options: [ - { - label: 'Rubber Soul', - key: 'Rubber Soul', - children: [ - { - label: "Everybody's Got Something to Hide Except Me and My Monkey", - key: "Everybody's Got Something to Hide Except Me and My Monkey", - }, - { - label: 'Drive My Car', - key: 'Drive My Car', - disabled: true, - }, - { - label: 'Norwegian Wood', - key: 'Norwegian Wood', - }, - { - label: "You Won't See", - key: "You Won't See", - disabled: true, - }, - { - label: 'Nowhere Man', - key: 'Nowhere Man', - }, - { - label: 'Think For Yourself', - key: 'Think For Yourself', - }, - { - label: 'The Word', - key: 'The Word', - }, - { - label: 'Michelle', - key: 'Michelle', - disabled: true, - }, - { - label: 'What goes on', - key: 'What goes on', - }, - { - label: 'Girl', - key: 'Girl', - }, - { - label: "I'm looking through you", - key: "I'm looking through you", - }, - { - label: 'In My Life', - key: 'In My Life', - }, - { - label: 'Wait', - key: 'Wait', - }, - ], - }, - { - label: 'Let It Be', - key: 'Let It Be Album', - children: [ - { - label: 'Two Of Us', - key: 'Two Of Us', - }, - { - label: 'Dig A Pony', - key: 'Dig A Pony', - }, - { - label: 'Across The Universe', - key: 'Across The Universe', - }, - { - label: 'I Me Mine', - key: 'I Me Mine', - }, - { - label: 'Dig It', - key: 'Dig It', - }, - { - label: 'Let It Be', - key: 'Let It Be', - }, - { - label: 'Maggie Mae', - key: 'Maggie Mae', - }, - { - label: "I've Got A Feeling", - key: "I've Got A Feeling", - }, - { - label: 'One After 909', - key: 'One After 909', - }, - { - label: 'The Long And Winding Road', - key: 'The Long And Winding Road', - }, - { - label: 'For You Blue', - key: 'For You Blue', - }, - { - label: 'Get Back', - key: 'Get Back', - }, - ], - }, - ], - } -} - -export function createRadioData() { - return { - options: [ - { - label: '选项1', - value: '1', - }, - { - label: '选项2', - value: '2', - }, - { - label: '选项3', - value: '3', - disabled: true, - }, - ], - } -} - -export function createCascaderOptions(depth = 3, iterator = 1, prefix = '') { - const length = 12 - const options = [] - for (let i = 1; i <= length; ++i) { - if (iterator === 1) { - options.push({ - value: `v-${i}`, - label: `l-${i}`, - disabled: i % 5 === 0, - children: createCascaderOptions(depth, iterator + 1, '' + String(i)), - }) - } else if (iterator === depth) { - options.push({ - value: `v-${prefix}-${i}`, - label: `l-${prefix}-${i}`, - disabled: i % 5 === 0, - }) - } else { - options.push({ - value: `v-${prefix}-${i}`, - label: `l-${prefix}-${i}`, - disabled: i % 5 === 0, - children: createCascaderOptions(depth, iterator + 1, `${prefix}-${i}`), - }) - } - } - return options -} - -export default [ - // mock user login - { - url: '/basic-api/demo/form/select', - timeout: 200, - method: 'post', - response: ({ body }) => { - return resultSuccess(createSelectData()) - }, - }, - { - url: '/basic-api/demo/form/treeSelect', - timeout: 200, - method: 'post', - response: ({ body }) => { - return resultSuccess(createTreeSelectData()) - }, - }, - { - url: '/basic-api/demo/form/radio', - timeout: 200, - method: 'post', - response: ({ body }) => { - return resultSuccess(createRadioData()) - }, - }, - { - url: '/basic-api/demo/form/cascader', - timeout: 200, - method: 'post', - response: ({ body }) => { - return resultSuccess({ options: createCascaderOptions() }) - }, - }, -] as MockMethod[] diff --git a/apps/grid-admin/mock/demo/table.ts b/apps/grid-admin/mock/demo/table.ts deleted file mode 100644 index 1afafa42..00000000 --- a/apps/grid-admin/mock/demo/table.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { MockMethod } from 'vite-plugin-mock' -import { resultError, resultSuccess } from '@vben/utils/mock-util' - -export function createFakeTableData() { - return { - items: [ - { - userId: '1', - username: 'vben', - realname: 'Vben Admin', - avatar: 'https://q1.qlogo.cn/g?b=qq&nk=190848757&s=640', - desc: 'manager', - password: '123456', - accessToken: 'fakeToken1', - roles: [ - { - name: 'Super Admin', - value: 'super', - }, - ], - }, - { - userId: '2', - username: 'test', - password: '123456', - realname: 'test user', - avatar: 'https://q1.qlogo.cn/g?b=qq&nk=339449197&s=640', - desc: 'tester', - accessToken: 'fakeToken2', - roles: [ - { - name: 'Tester', - value: 'test', - }, - ], - }, - ], - total: 2, - } -} - -export default [ - // mock user login - { - url: '/basic-api/demo/table', - timeout: 200, - method: 'post', - response: ({ body }) => { - return resultSuccess(createFakeTableData()) - }, - }, -] as MockMethod[] diff --git a/apps/grid-admin/mock/menu.ts b/apps/grid-admin/mock/menu.ts deleted file mode 100644 index d20aebd1..00000000 --- a/apps/grid-admin/mock/menu.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { - resultSuccess, - resultError, - getRequestToken, - requestParams, -} from '@vben/utils/mock-util' -import { MockMethod } from 'vite-plugin-mock' -import { createFakeUserList } from './auth' - -// single -const dashboardRoute = { - path: '/dashboard', - name: 'Dashboard', - component: 'LAYOUT', - redirect: '/dashboard/analysis', - meta: { - title: 'routes.dashboard.dashboard', - icon: 'bx:bx-home', - }, - children: [ - { - path: 'analysis', - name: 'Analysis', - component: '/dashboard/analysis/index', - meta: { - title: 'routes.dashboard.analysis', - icon: 'bx:bx-home', - }, - }, - { - path: 'workbench', - name: 'Workbench', - component: '/dashboard/workbench/index', - meta: { - title: 'routes.dashboard.workbench', - icon: 'bx:bx-home', - }, - }, - ], -} - -const backRoute = { - path: 'back', - name: 'PermissionBackDemo', - meta: { - title: 'routes.demo.permission.back', - }, - - children: [ - { - path: 'page', - name: 'BackAuthPage', - component: '/demo/permission/back/index', - meta: { - title: 'routes.demo.permission.backPage', - }, - }, - { - path: 'btn', - name: 'BackAuthBtn', - component: '/demo/permission/back/Btn', - meta: { - title: 'routes.demo.permission.backBtn', - }, - }, - ], -} - -const authRoute = { - path: '/permission', - name: 'Permission', - component: 'LAYOUT', - redirect: '/permission/front/page', - meta: { - icon: 'carbon:user-role', - title: 'routes.demo.permission.permission', - }, - children: [backRoute], -} - -const levelRoute = { - path: '/level', - name: 'Level', - component: 'LAYOUT', - redirect: '/level/menu1/menu1-1', - meta: { - icon: 'carbon:user-role', - title: 'routes.demo.level.level', - }, - - children: [ - { - path: 'menu1', - name: 'Menu1Demo', - meta: { - title: 'Menu1', - }, - children: [ - { - path: 'menu1-1', - name: 'Menu11Demo', - meta: { - title: 'Menu1-1', - }, - children: [ - { - path: 'menu1-1-1', - name: 'Menu111Demo', - component: '/demo/level/Menu111', - meta: { - title: 'Menu111', - }, - }, - ], - }, - { - path: 'menu1-2', - name: 'Menu12Demo', - component: '/demo/level/Menu12', - meta: { - title: 'Menu1-2', - }, - }, - ], - }, - { - path: 'menu2', - name: 'Menu2Demo', - component: '/demo/level/Menu2', - meta: { - title: 'Menu2', - }, - }, - ], -} - -const sysRoute = { - path: '/system', - name: 'System', - component: 'LAYOUT', - redirect: '/system/account', - meta: { - icon: 'ion:settings-outline', - title: 'routes.demo.system.moduleName', - }, - children: [ - { - path: 'account', - name: 'AccountManagement', - meta: { - title: 'routes.demo.system.account', - ignoreKeepAlive: true, - }, - component: '/demo/system/account/index', - }, - { - path: 'account_detail/:id', - name: 'AccountDetail', - meta: { - title: 'routes.demo.system.account_detail', - ignoreKeepAlive: true, - showMenu: false, - }, - component: '/demo/system/account/AccountDetail', - }, - { - path: 'role', - name: 'RoleManagement', - meta: { - title: 'routes.demo.system.role', - ignoreKeepAlive: true, - }, - component: '/demo/system/role/index', - }, - - { - path: 'menu', - name: 'MenuManagement', - meta: { - title: 'routes.demo.system.menu', - ignoreKeepAlive: true, - }, - component: '/demo/system/menu/index', - }, - { - path: 'dept', - name: 'DeptManagement', - meta: { - title: 'routes.demo.system.dept', - ignoreKeepAlive: true, - }, - component: '/demo/system/dept/index', - }, - { - path: 'changePassword', - name: 'ChangePassword', - meta: { - title: 'routes.demo.system.password', - ignoreKeepAlive: true, - }, - component: '/demo/system/password/index', - }, - ], -} - -const linkRoute = { - path: '/link', - name: 'Link', - component: 'LAYOUT', - meta: { - icon: 'ion:tv-outline', - title: 'routes.demo.iframe.frame', - }, - children: [ - { - path: 'doc', - name: 'Doc', - meta: { - title: 'routes.demo.iframe.doc', - }, - }, - { - path: 'https://vvbin.cn/doc-next/', - name: 'DocExternal', - component: 'LAYOUT', - meta: { - title: 'routes.demo.iframe.docExternal', - }, - }, - ], -} - -export default [ - { - url: '/basic-api/getMenuList', - timeout: 1000, - method: 'get', - response: (request: requestParams) => { - const token = getRequestToken(request) - if (!token) { - return resultError('Invalid token!') - } - const checkUser = createFakeUserList().find( - (item) => item.token === token, - ) - if (!checkUser) { - return resultError('Invalid user token!') - } - const id = checkUser.userId - let menu: Object[] - switch (id) { - case '1': - dashboardRoute.redirect = - dashboardRoute.path + '/' + dashboardRoute.children[0].path - menu = [dashboardRoute, authRoute, levelRoute, sysRoute, linkRoute] - break - case '2': - dashboardRoute.redirect = - dashboardRoute.path + '/' + dashboardRoute.children[1].path - menu = [dashboardRoute, authRoute, levelRoute, linkRoute] - break - default: - menu = [] - } - - return resultSuccess(menu) - }, - }, -] as MockMethod[] diff --git a/apps/grid-admin/package.json b/apps/grid-admin/package.json deleted file mode 100644 index 6fb2a7c3..00000000 --- a/apps/grid-admin/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@apps/grid-admin", - "version": "3.0.0-bata.1", - "repository": { - "type": "git", - "url": "git+https://github.com/vbenjs/vue-vben-admin.git", - "directory": "apps/ant-app" - }, - "author": { - "name": "vben", - "email": "anncwb@126.com", - "url": "https://github.com/anncwb" - }, - "scripts": { - "build": "pnpm cross-env NODE_ENV=production vite build", - "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo", - "dev": "vite", - "preview": "npm run build && vite preview", - "preview:dist": "vite preview", - "report": "pnpm cross-env REPORT=true npm run build", - "server:br": "pnpx http-server dist --cors --brotli -c-1", - "server:gzip": "pnpx http-server dist --cors --gzip -c-1", - "type:check": "vue-tsc --noEmit --skipLibCheck" - }, - "dependencies": { - "@ant-design/icons-vue": "^6.1.0", - "@iconify/iconify": "^3.1.0", - "@vben/components": "workspace:*", - "@vben/constants": "workspace:*", - "@vben/demo": "workspace:*", - "@vben/directives": "workspace:*", - "@vben/grid-layouts": "workspace:*", - "@vben/hooks": "workspace:*", - "@vben/locale": "workspace:*", - "@vben/request": "workspace:*", - "@vben/stores": "workspace:*", - "@vben/styles": "workspace:*", - "@vben/utils": "workspace:*", - "@vben/vbencomponents": "workspace:*", - "@vben/router": "workspace:*", - "dayjs": "^1.11.7", - "mockjs": "^1.1.0", - "monaco-editor": "^0.34.1", - "path-to-regexp": "^6.2.1", - "pinia": "2.0.30", - "vue": "3.2.47", - "vue-demi": "^0.13.11", - "vue-router": "^4.1.6" - }, - "devDependencies": { - "@config/css-preprocess": "workspace:*", - "@config/vite": "workspace:*", - "@types/mockjs": "^1.0.7", - "@types/nprogress": "^0.2.0", - "@vben/types": "workspace:*", - "@vue/compiler-sfc": "3.2.47", - "@vue/test-utils": "^2.2.9", - "naive-ui": "^2.34.3", - "typescript": "^4.9.5", - "vite": "4.0.4", - "vue-tsc": "^1.0.24" - } -} diff --git a/apps/grid-admin/postcss.config.js b/apps/grid-admin/postcss.config.js deleted file mode 100644 index db0f61f9..00000000 --- a/apps/grid-admin/postcss.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@config/css-preprocess/postcss') diff --git a/apps/grid-admin/public/favicon.ico b/apps/grid-admin/public/favicon.ico deleted file mode 100644 index d92e0b8c..00000000 Binary files a/apps/grid-admin/public/favicon.ico and /dev/null differ diff --git a/apps/grid-admin/public/logo.png b/apps/grid-admin/public/logo.png deleted file mode 100644 index cd4c33d8..00000000 Binary files a/apps/grid-admin/public/logo.png and /dev/null differ diff --git a/apps/grid-admin/src/apis/auth.ts b/apps/grid-admin/src/apis/auth.ts deleted file mode 100644 index d144e2b6..00000000 --- a/apps/grid-admin/src/apis/auth.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { ErrorMessageMode } from '@vben/types' -import { request } from '@vben/request' - -export interface RoleInfo { - name: string - value: string -} - -export interface LoginParams { - username: string - password: string -} - -export interface LoginResultModel { - userId: string | number - accessToken: string - role: RoleInfo -} - -export interface UserInfoModel { - roles: RoleInfo[] - userId: string | number - username: string - realName?: string - avatar: string - desc?: string -} - -export function doLoginApi( - params: LoginParams, - mode: ErrorMessageMode = 'modal', -) { - return request.post( - { - url: '/login', - params, - }, - { - errorMessageMode: mode, - }, - ) -} - -export function getUserInfoApi() { - return request.get( - { url: '/getUserInfo' }, - { errorMessageMode: 'none' }, - ) -} - -export function getPermCode() { - return request.get({ url: '/getPermCode' }) -} - -export function doLogoutApi() { - return request.get({ url: '/logout' }) -} diff --git a/apps/grid-admin/src/apis/menu.ts b/apps/grid-admin/src/apis/menu.ts deleted file mode 100644 index 1ba0ccd0..00000000 --- a/apps/grid-admin/src/apis/menu.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { request } from '@vben/request' - -export interface RouteItem { - path: string - component: any - meta: any - name?: string - alias?: string | string[] - redirect?: string - caseSensitive?: boolean - children?: RouteItem[] -} - -/** - * @description: Get menu return value - */ -export type GetMenuListResultModel = RouteItem[] - -enum Api { - GetMenuList = '/getMenuList', -} - -/** - * @description: Get user menu based on id - */ - -export const getMenuList = () => { - return request.get({ url: Api.GetMenuList }) -} diff --git a/apps/grid-admin/src/apis/sys/index.ts b/apps/grid-admin/src/apis/sys/index.ts deleted file mode 100644 index d35d236a..00000000 --- a/apps/grid-admin/src/apis/sys/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './menu' -export * from './user' diff --git a/apps/grid-admin/src/apis/sys/menu.ts b/apps/grid-admin/src/apis/sys/menu.ts deleted file mode 100644 index 1ba0ccd0..00000000 --- a/apps/grid-admin/src/apis/sys/menu.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { request } from '@vben/request' - -export interface RouteItem { - path: string - component: any - meta: any - name?: string - alias?: string | string[] - redirect?: string - caseSensitive?: boolean - children?: RouteItem[] -} - -/** - * @description: Get menu return value - */ -export type GetMenuListResultModel = RouteItem[] - -enum Api { - GetMenuList = '/getMenuList', -} - -/** - * @description: Get user menu based on id - */ - -export const getMenuList = () => { - return request.get({ url: Api.GetMenuList }) -} diff --git a/apps/grid-admin/src/apis/sys/user.ts b/apps/grid-admin/src/apis/sys/user.ts deleted file mode 100644 index d18a0e04..00000000 --- a/apps/grid-admin/src/apis/sys/user.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { ErrorMessageMode } from '@vben/types' -import { request } from '@vben/request' - -/** - * @description: Login interface parameters - */ -export interface LoginParams { - username: string - password: string -} - -export interface RoleInfo { - roleName: string - value: string -} - -/** - * @description: Login interface return value - */ -export interface LoginResultModel { - userId: string | number - token: string - role: RoleInfo -} - -/** - * @description: Get user information return value - */ -export interface GetUserInfoModel { - roles: RoleInfo[] - // 用户id - userId: string | number - // 用户名 - username: string - // 真实名字 - realName: string - // 头像 - avatar: string - // 介绍 - desc?: string -} - -enum Api { - Login = '/login', - Logout = '/logout', - GetUserInfo = '/getUserInfo', - GetPermCode = '/getPermCode', -} - -/** - * @description: user login api - */ -export function loginApi( - params: LoginParams, - mode: ErrorMessageMode = 'modal', -) { - return request.post( - { - url: Api.Login, - params, - }, - { - errorMessageMode: mode, - }, - ) -} - -/** - * @description: getUserInfo - */ -export function getUserInfo() { - return request.get( - { url: Api.GetUserInfo }, - { errorMessageMode: 'none' }, - ) -} - -export function getPermCode() { - return request.get({ url: Api.GetPermCode }) -} - -export function doLogout() { - return request.get({ url: Api.Logout }) -} diff --git a/apps/grid-admin/src/apis/system/model/useModel.ts b/apps/grid-admin/src/apis/system/model/useModel.ts deleted file mode 100644 index 2415c911..00000000 --- a/apps/grid-admin/src/apis/system/model/useModel.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @description: Login interface parameters - */ -export interface LoginParams { - username: string; - password: string; -} - -export interface RoleInfo { - roleName: string; - value: string; -} - -/** - * @description: Login interface return value - */ -export interface LoginResultModel { - userId: string | number; - token: string; - role: RoleInfo; -} - -/** - * @description: Get user information return value - */ -export interface GetUserInfoModel { - roles: RoleInfo[]; - // 用户id - userId: string | number; - // 用户名 - username: string; - // 真实名字 - realName: string; - // 头像 - avatar: string; - // 介绍 - desc?: string; -} diff --git a/apps/grid-admin/src/app.vue b/apps/grid-admin/src/app.vue deleted file mode 100644 index cb506a9e..00000000 --- a/apps/grid-admin/src/app.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - diff --git a/apps/grid-admin/src/assets/icons/download-count.svg b/apps/grid-admin/src/assets/icons/download-count.svg deleted file mode 100644 index 1c951958..00000000 --- a/apps/grid-admin/src/assets/icons/download-count.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 91 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-1.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-1.svg deleted file mode 100644 index e1553e50..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-1.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 15 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-2.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-2.svg deleted file mode 100644 index c4c17223..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-2.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 16 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-3.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-3.svg deleted file mode 100644 index 81145f9b..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-3.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 17 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-4.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-4.svg deleted file mode 100644 index e586ed4e..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-4.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 120 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-5.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-5.svg deleted file mode 100644 index 746e4b88..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-5.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 110 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/dynamic-avatar-6.svg b/apps/grid-admin/src/assets/icons/dynamic-avatar-6.svg deleted file mode 100644 index b2432f22..00000000 --- a/apps/grid-admin/src/assets/icons/dynamic-avatar-6.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 100 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/moon.svg b/apps/grid-admin/src/assets/icons/moon.svg deleted file mode 100644 index e6667f0d..00000000 --- a/apps/grid-admin/src/assets/icons/moon.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - diff --git a/apps/grid-admin/src/assets/icons/sun.svg b/apps/grid-admin/src/assets/icons/sun.svg deleted file mode 100644 index a3997cbf..00000000 --- a/apps/grid-admin/src/assets/icons/sun.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/grid-admin/src/assets/icons/total-sales.svg b/apps/grid-admin/src/assets/icons/total-sales.svg deleted file mode 100644 index eff79640..00000000 --- a/apps/grid-admin/src/assets/icons/total-sales.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 500 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/transaction.svg b/apps/grid-admin/src/assets/icons/transaction.svg deleted file mode 100644 index 7ba9e2f0..00000000 --- a/apps/grid-admin/src/assets/icons/transaction.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 480% \ No newline at end of file diff --git a/apps/grid-admin/src/assets/icons/visit-count.svg b/apps/grid-admin/src/assets/icons/visit-count.svg deleted file mode 100644 index ba2a3061..00000000 --- a/apps/grid-admin/src/assets/icons/visit-count.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 510 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/images/header.jpg b/apps/grid-admin/src/assets/images/header.jpg deleted file mode 100644 index 977584b6..00000000 Binary files a/apps/grid-admin/src/assets/images/header.jpg and /dev/null differ diff --git a/apps/grid-admin/src/assets/images/logo.png b/apps/grid-admin/src/assets/images/logo.png deleted file mode 100644 index 16f2e7ab..00000000 Binary files a/apps/grid-admin/src/assets/images/logo.png and /dev/null differ diff --git a/apps/grid-admin/src/assets/svg/illustration.svg b/apps/grid-admin/src/assets/svg/illustration.svg deleted file mode 100644 index b45215b0..00000000 --- a/apps/grid-admin/src/assets/svg/illustration.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 336 \ No newline at end of file diff --git a/apps/grid-admin/src/assets/svg/login-bg-dark.svg b/apps/grid-admin/src/assets/svg/login-bg-dark.svg deleted file mode 100644 index 888da7af..00000000 --- a/apps/grid-admin/src/assets/svg/login-bg-dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/grid-admin/src/assets/svg/login-bg.svg b/apps/grid-admin/src/assets/svg/login-bg.svg deleted file mode 100644 index 7b66bafc..00000000 --- a/apps/grid-admin/src/assets/svg/login-bg.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/apps/grid-admin/src/assets/svg/login-box-bg.svg b/apps/grid-admin/src/assets/svg/login-box-bg.svg deleted file mode 100644 index ee7dbdc2..00000000 --- a/apps/grid-admin/src/assets/svg/login-box-bg.svg +++ /dev/null @@ -1 +0,0 @@ -responsive \ No newline at end of file diff --git a/apps/grid-admin/src/assets/svg/net-error.svg b/apps/grid-admin/src/assets/svg/net-error.svg deleted file mode 100644 index 81f20044..00000000 --- a/apps/grid-admin/src/assets/svg/net-error.svg +++ /dev/null @@ -1 +0,0 @@ -personal settings \ No newline at end of file diff --git a/apps/grid-admin/src/assets/svg/no-data.svg b/apps/grid-admin/src/assets/svg/no-data.svg deleted file mode 100644 index 2b9f2570..00000000 --- a/apps/grid-admin/src/assets/svg/no-data.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/grid-admin/src/config.ts b/apps/grid-admin/src/config.ts deleted file mode 100644 index c73c4148..00000000 --- a/apps/grid-admin/src/config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { StaticConfig, DynamicConfig } from '@vben/types' - -// github repo url -export const GITHUB_URL = 'https://github.com/vbenjs/vben3' - -// vue-vben-admin-next-doc -export const DOC_URL = 'https://vbenjs.github.io/vben3-doc/' - -// site url -export const SITE_URL = 'http://vben.mufei88.com/' - -const dynamicConfig: DynamicConfig = { - __: '', -} - -// ! You need to clear the browser cache after the change -const staticConfig: StaticConfig = { - authType: 'frontend', - - // enable - enableProgress: true, -} - -export const config = { ...staticConfig, ...dynamicConfig } - -export const siteSetting = {GITHUB_URL, DOC_URL, SITE_URL} diff --git a/apps/grid-admin/src/init-application.ts b/apps/grid-admin/src/init-application.ts deleted file mode 100644 index e4e198eb..00000000 --- a/apps/grid-admin/src/init-application.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { initRequest } from '@vben/request' -import { useUserStoreWithout } from '@/store/user' -import { useI18n, useLocale } from '@vben/locale' -import { getGlobalConfig } from '@vben/utils' -import { useConfigStore } from '@/store/config' -import { initComp } from '@vben/vbencomponents' -import { localeList } from '@vben/locale/src/config' -import { useAppStore } from '@/store/modules/app' -// To decouple the modules below `packages/*`, they no longer depend on each other -// If the modules are heavily dependent on each other, you need to provide a decoupling method, and the caller will pass the parameters -// Each module needs to provide `bridge` file as a decoupling method - -// 为了解耦 `packages/*` 下面各模块,不再相互依赖 -// 如果模块相互依赖严重,则需要对外提供解耦方式,由调用方去进行参数传递 -// 各个模块需要提供 `bridge` 文件作为解耦方式 -async function initPackages() { - const _initRequest = async () => { - const { apiUrl } = getGlobalConfig(import.meta.env) - const { t } = useI18n() - await initRequest(() => { - return { - apiUrl, - getTokenFunction: () => { - const userStore = useUserStoreWithout() - return userStore.getAccessToken - }, - errorFunction: null, - noticeFunction: null, - errorModalFunction: null, - timeoutFunction: () => { - const userStore = useUserStoreWithout() - userStore.setAccessToken(undefined) - userStore.logout(true) - }, - unauthorizedFunction: (msg?: string) => { - const userStore = useUserStoreWithout() - userStore.setAccessToken(undefined) - userStore.logout(true) - return msg || t('sys.api.errMsg401') - }, - handleErrorFunction: (msg, mode) => { - if (mode === 'modal') { - Modal.error({ title: t('sys.api.errorTip'), content: msg }) - } else if (mode === 'message') { - message.error(msg) - } - }, - } - }) - } - - const _initComp = async () => { - await initComp(() => { - return { - useLocale, - localeList, - useAppStore, - useConfigStore, - } - }) - - await Promise.all([_initRequest(), _initComp()]) - } -} - -export async function initApplication() { - // ! Need to pay attention to the timing of execution - // ! 需要注意调用时机 - await initPackages() -} diff --git a/apps/grid-admin/src/layout/components/app/AppProvider.tsx b/apps/grid-admin/src/layout/components/app/AppProvider.tsx deleted file mode 100644 index a6f328ff..00000000 --- a/apps/grid-admin/src/layout/components/app/AppProvider.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { - createMediaPrefersColorSchemeListen, - createBreakpointListen, -} from '@vben/hooks' -import { namespace } from '@/setting' -import { defineComponent, toRefs, ref } from 'vue' -import { createAppProviderContext } from '@vben/hooks' -import { useMsg, useNotice } from '@vben/vbencomponents' -import { setMsg, setNoice } from '@vben/request' - -const props = { - /** - * class style prefix - */ - prefixCls: { type: String, default: namespace }, -} - -export default defineComponent({ - name: 'AppProvider', - inheritAttrs: false, - props, - setup(props, { slots }) { - const isMobile = ref(false) - //注册msg以及notice,方便全局使用 - const msg = useMsg() - const notice = useNotice() - setMsg(msg) - setNoice(notice) - // Monitor screen breakpoint information changes - createBreakpointListen(({ screenMap, sizeEnum, width }) => { - const lgWidth = screenMap.get(sizeEnum.LG) - if (lgWidth) { - isMobile.value = width.value - 1 < lgWidth - } - }) - // Listen for system theme changes - createMediaPrefersColorSchemeListen() - - const { prefixCls } = toRefs(props) - - // Inject variables into the global - createAppProviderContext({ prefixCls, isMobile }) - - return () => slots.default?.() - }, -}) diff --git a/apps/grid-admin/src/layout/components/logo.vue b/apps/grid-admin/src/layout/components/logo.vue deleted file mode 100644 index d27bc974..00000000 --- a/apps/grid-admin/src/layout/components/logo.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - {{ title }} - - - - - diff --git a/apps/grid-admin/src/layout/components/useLockPage.ts b/apps/grid-admin/src/layout/components/useLockPage.ts deleted file mode 100644 index 2d7ed1e5..00000000 --- a/apps/grid-admin/src/layout/components/useLockPage.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { computed, onUnmounted, watchEffect } from 'vue' -import { useThrottleFn } from '@vben/utils' -import { useLockStore } from '@/store/lock' -import { useUserStore } from '@/store/user' - -export function useLockPage() { - const lockStore = useLockStore() - const userStore = useUserStore() - - let timeId: TimeoutHandle - - function clear(): void { - window.clearTimeout(timeId) - } - - function resetCalcLockTimeout(): void { - // not login - if (!userStore.getToken) { - clear() - return - } - const lockTime = 0 - if (!lockTime || lockTime < 1) { - clear() - return - } - clear() - - timeId = setTimeout(() => { - lockPage() - }, lockTime * 60 * 1000) - } - - function lockPage(): void { - lockStore.setLockInfo({ - isLock: true, - pwd: undefined, - }) - } - - watchEffect((onClean) => { - if (userStore.getToken) { - resetCalcLockTimeout() - } else { - clear() - } - onClean(() => { - clear() - }) - }) - - onUnmounted(() => { - clear() - }) - - const keyupFn = useThrottleFn(resetCalcLockTimeout, 2000) - - return computed(() => { - if (0) { - return { onKeyup: keyupFn, onMousemove: keyupFn } - } else { - clear() - return {} - } - }) -} diff --git a/apps/grid-admin/src/layout/feature/index.vue b/apps/grid-admin/src/layout/feature/index.vue deleted file mode 100644 index 528bc88b..00000000 --- a/apps/grid-admin/src/layout/feature/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/apps/grid-admin/src/layout/index.vue b/apps/grid-admin/src/layout/index.vue deleted file mode 100644 index d460f8f5..00000000 --- a/apps/grid-admin/src/layout/index.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/apps/grid-admin/src/main.ts b/apps/grid-admin/src/main.ts deleted file mode 100644 index 40aa53e7..00000000 --- a/apps/grid-admin/src/main.ts +++ /dev/null @@ -1,36 +0,0 @@ -import '@vben/styles' -// import 'ant-design-vue/dist/antd.variable.css' -import 'virtual:svg-icons-register' -import App from './app.vue' -import { createApp } from 'vue' -import { router } from '@/router' -import { setupRouteGuard } from '@/router/guard' -import { setupI18n } from '@vben/locale' -import { setupPinia } from '@vben/stores' -import { initApplication } from './init-application' -import { registerComponents } from '../init-components' -;(async () => { - const app = createApp(App) - - setupPinia(app) - - await registerComponents(app) - - await initApplication() - // Register Global Components - - // Multilingual configuration - // Asynchronous case: language files may be obtained from the server side - await setupI18n(app) - // Init Router - app.use(router) - await setupRouteGuard(router) - await router.isReady() - app.mount('#app') - // When Closing mock, Tree Shaking `mockjs` dep - if (__VITE_USE_MOCK__) { - import('../mock/_mock-server').then(({ setupProdMockServer }) => - setupProdMockServer(), - ) - } -})() diff --git a/apps/grid-admin/src/pages/dashboard/workbench/index.vue b/apps/grid-admin/src/pages/dashboard/workbench/index.vue deleted file mode 100644 index 96ac82c0..00000000 --- a/apps/grid-admin/src/pages/dashboard/workbench/index.vue +++ /dev/null @@ -1 +0,0 @@ -workbench diff --git a/apps/grid-admin/src/pages/demo/Card.vue b/apps/grid-admin/src/pages/demo/Card.vue deleted file mode 100644 index 2a70d82a..00000000 --- a/apps/grid-admin/src/pages/demo/Card.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/apps/grid-admin/src/pages/demo/Draggable.vue b/apps/grid-admin/src/pages/demo/Draggable.vue deleted file mode 100644 index 28be7eb1..00000000 --- a/apps/grid-admin/src/pages/demo/Draggable.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - 拖拽 - - diff --git a/apps/grid-admin/src/pages/demo/Form.vue b/apps/grid-admin/src/pages/demo/Form.vue deleted file mode 100644 index 229db5c3..00000000 --- a/apps/grid-admin/src/pages/demo/Form.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/apps/grid-admin/src/pages/demo/Table.vue b/apps/grid-admin/src/pages/demo/Table.vue deleted file mode 100644 index 81dde2a3..00000000 --- a/apps/grid-admin/src/pages/demo/Table.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/apps/grid-admin/src/pages/demo/editor/monaco-editor.vue b/apps/grid-admin/src/pages/demo/editor/monaco-editor.vue deleted file mode 100644 index c66a9f90..00000000 --- a/apps/grid-admin/src/pages/demo/editor/monaco-editor.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/apps/grid-admin/src/pages/demo/page/index.vue b/apps/grid-admin/src/pages/demo/page/index.vue deleted file mode 100644 index 5db5b320..00000000 --- a/apps/grid-admin/src/pages/demo/page/index.vue +++ /dev/null @@ -1,4 +0,0 @@ - -PageTest - - diff --git a/apps/grid-admin/src/pages/demo/table/BasicTable.vue b/apps/grid-admin/src/pages/demo/table/BasicTable.vue deleted file mode 100644 index 2ce0dfc9..00000000 --- a/apps/grid-admin/src/pages/demo/table/BasicTable.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/apps/grid-admin/src/pages/sys/exception/index.vue b/apps/grid-admin/src/pages/sys/exception/index.vue deleted file mode 100644 index 8085eb6c..00000000 --- a/apps/grid-admin/src/pages/sys/exception/index.vue +++ /dev/null @@ -1,167 +0,0 @@ - - diff --git a/apps/grid-admin/src/pages/sys/iframe/FrameBlank.vue b/apps/grid-admin/src/pages/sys/iframe/FrameBlank.vue deleted file mode 100644 index 7b8b46cb..00000000 --- a/apps/grid-admin/src/pages/sys/iframe/FrameBlank.vue +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/grid-admin/src/pages/sys/lock/index.vue b/apps/grid-admin/src/pages/sys/lock/index.vue deleted file mode 100644 index 5195a055..00000000 --- a/apps/grid-admin/src/pages/sys/lock/index.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/apps/grid-admin/src/pages/sys/lock/lock-page.vue b/apps/grid-admin/src/pages/sys/lock/lock-page.vue deleted file mode 100644 index 65679232..00000000 --- a/apps/grid-admin/src/pages/sys/lock/lock-page.vue +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - {{ t('sys.lock.unlock') }} - - - - - {{ hour }} - - {{ meridiem }} - - - - {{ minute }} - - - - - - - - - {{ userInfo.realName }} - - - - - {{ t('sys.lock.alert') }} - - - - {{ t('common.back') }} - - - {{ t('sys.lock.backToLogin') }} - - - {{ t('sys.lock.entry') }} - - - - - - - - - {{ hour }}:{{ minute }} {{ meridiem }} - - {{ year }}/{{ month }}/{{ day }} {{ week }} - - - - - diff --git a/apps/grid-admin/src/pages/sys/lock/use-now.ts b/apps/grid-admin/src/pages/sys/lock/use-now.ts deleted file mode 100644 index ce04b7cb..00000000 --- a/apps/grid-admin/src/pages/sys/lock/use-now.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { dateUtil } from '@vben/utils' -import { tryOnMounted, tryOnUnmounted } from '@vben/utils' -import { reactive, toRefs } from 'vue' - -export function useNow(immediate = true) { - let timer: IntervalHandle - - const state = reactive({ - year: 0, - month: 0, - week: '', - day: 0, - hour: '', - minute: '', - second: 0, - meridiem: '', - }) - - const update = () => { - const now = dateUtil() - - const h = now.format('HH') - const m = now.format('mm') - const s = now.get('s') - - state.year = now.get('y') - state.month = now.get('M') + 1 - state.week = '星期' + ['日', '一', '二', '三', '四', '五', '六'][now.day()] - state.day = now.get('date') - state.hour = h - state.minute = m - state.second = s - - state.meridiem = now.format('A') - } - - function start() { - update() - clearInterval(timer) - timer = setInterval(() => update(), 1000) - } - - function stop() { - clearInterval(timer) - } - - tryOnMounted(() => { - immediate && start() - }) - - tryOnUnmounted(() => { - stop() - }) - - return { - ...toRefs(state), - start, - stop, - } -} diff --git a/apps/grid-admin/src/pages/sys/login/forget-password-form.vue b/apps/grid-admin/src/pages/sys/login/forget-password-form.vue deleted file mode 100644 index c5dc5637..00000000 --- a/apps/grid-admin/src/pages/sys/login/forget-password-form.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - {{ t('common.resetText') }} - - - {{ t('sys.login.backSignIn') }} - - - - - diff --git a/apps/grid-admin/src/pages/sys/login/login-form-title.vue b/apps/grid-admin/src/pages/sys/login/login-form-title.vue deleted file mode 100644 index cf793d38..00000000 --- a/apps/grid-admin/src/pages/sys/login/login-form-title.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - - {{ formTitle }} - - diff --git a/apps/grid-admin/src/pages/sys/login/login-form.vue b/apps/grid-admin/src/pages/sys/login/login-form.vue deleted file mode 100644 index b81002d1..00000000 --- a/apps/grid-admin/src/pages/sys/login/login-form.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - {{t('sys.login.rememberMe')}} - - - - - - - - {{t('sys.login.forgetPassword')}} - - - - - - - - {{t('sys.login.loginButton')}} - - - - - - - {{t('sys.login.mobileSignInFormTitle')}} - - - - - {{t('sys.login.qrSignInFormTitle')}} - - - - - {{t('sys.login.registerButton')}} - - - - - {{t('sys.login.otherSignIn')}} - - - - - - - - - - diff --git a/apps/grid-admin/src/pages/sys/login/login.vue b/apps/grid-admin/src/pages/sys/login/login.vue deleted file mode 100644 index cf837c4b..00000000 --- a/apps/grid-admin/src/pages/sys/login/login.vue +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - {{ title }} - - - - - - - {{ t('sys.login.signInTitle') }} - - - {{ t('sys.login.signInDesc') }} - - - - - - - - - - - - - - - - - - - diff --git a/apps/grid-admin/src/pages/sys/login/mobile-form.vue b/apps/grid-admin/src/pages/sys/login/mobile-form.vue deleted file mode 100644 index 92dfec74..00000000 --- a/apps/grid-admin/src/pages/sys/login/mobile-form.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - {{ t('sys.login.loginButton') }} - - - {{ t('sys.login.backSignIn') }} - - - - - diff --git a/apps/grid-admin/src/pages/sys/login/qrcode-form.vue b/apps/grid-admin/src/pages/sys/login/qrcode-form.vue deleted file mode 100644 index 7d36f9bd..00000000 --- a/apps/grid-admin/src/pages/sys/login/qrcode-form.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - {{ t('sys.login.scanSign') }} - - {{ t('sys.login.backSignIn') }} - - - - diff --git a/apps/grid-admin/src/pages/sys/login/register-form.vue b/apps/grid-admin/src/pages/sys/login/register-form.vue deleted file mode 100644 index 702b6fdf..00000000 --- a/apps/grid-admin/src/pages/sys/login/register-form.vue +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - {{ t('sys.login.policy') }} - - - - - {{ t('sys.login.registerButton') }} - - - {{ t('sys.login.backSignIn') }} - - - - diff --git a/apps/grid-admin/src/pages/sys/login/use-login.ts b/apps/grid-admin/src/pages/sys/login/use-login.ts deleted file mode 100644 index 8e443cb8..00000000 --- a/apps/grid-admin/src/pages/sys/login/use-login.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { ref, computed, unref, Ref } from 'vue' -import { useI18n } from '@vben/locale' - -export enum LoginStateEnum { - LOGIN, - REGISTER, - RESET_PASSWORD, - MOBILE, - QR_CODE, -} - -const currentState = ref(LoginStateEnum.LOGIN) - -export function useLoginState() { - function setLoginState(state: LoginStateEnum) { - currentState.value = state - } - - const getLoginState = computed(() => currentState.value) - - function handleBackLogin() { - setLoginState(LoginStateEnum.LOGIN) - } - - return { setLoginState, getLoginState, handleBackLogin } -} - -export function useFormValid(formRef: Ref) { - async function validForm() { - const form = unref(formRef) - if (!form) return - const data = await form.validate() - return data as T - } - - return { validForm } -} - -export function useFormRules(formData?: Recordable) { - const { t } = useI18n() - - const getAccountFormRule = computed(() => - createRule(t('sys.login.accountPlaceholder')), - ) - const getPasswordFormRule = computed(() => - createRule(t('sys.login.passwordPlaceholder')), - ) - const getSmsFormRule = computed(() => - createRule(t('sys.login.smsPlaceholder')), - ) - const getMobileFormRule = computed(() => - createRule(t('sys.login.mobilePlaceholder')), - ) - - const validatePolicy = async (_: any, value: boolean) => { - return !value - ? Promise.reject(t('sys.login.policyPlaceholder')) - : Promise.resolve() - } - - const validateConfirmPassword = (password: string) => { - return async (_: any, value: string) => { - if (!value) { - return Promise.reject(t('sys.login.passwordPlaceholder')) - } - if (value !== password) { - return Promise.reject(t('sys.login.diffPwd')) - } - return Promise.resolve() - } - } - - const getFormRules = computed((): { [k: string]: any | any[] } => { - const accountFormRule = unref(getAccountFormRule) - const passwordFormRule = unref(getPasswordFormRule) - const smsFormRule = unref(getSmsFormRule) - const mobileFormRule = unref(getMobileFormRule) - - const mobileRule = { - sms: smsFormRule, - mobile: mobileFormRule, - } - switch (unref(currentState)) { - // register form rules - case LoginStateEnum.REGISTER: - return { - account: accountFormRule, - password: passwordFormRule, - confirmPassword: [ - { - validator: validateConfirmPassword(formData?.password), - trigger: 'change', - }, - ], - policy: [{ validator: validatePolicy, trigger: 'change' }], - ...mobileRule, - } - - // reset password form rules - case LoginStateEnum.RESET_PASSWORD: - return { - account: accountFormRule, - ...mobileRule, - } - - // mobile form rules - case LoginStateEnum.MOBILE: - return mobileRule - - // login form rules - default: - return { - account: accountFormRule, - password: passwordFormRule, - } - } - }) - return { getFormRules } -} - -function createRule(message: string): any[] { - return [ - { - required: true, - message, - trigger: 'change', - }, - ] -} diff --git a/apps/grid-admin/src/router/guard.ts b/apps/grid-admin/src/router/guard.ts deleted file mode 100644 index 9ebe7128..00000000 --- a/apps/grid-admin/src/router/guard.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { Router } from 'vue-router' -import { useUserStoreWithout } from '@/store/user' -import { useAuthStoreWithout } from '@/store/auth' -import { - initGuard, - createBasicGuard, - createAuthGuard, - createTabsGuard, - createParamMenuGuard, -} from '@vben/router' -import { setRouteChange } from '@/logics/mitt/routeChange' -import { useLockStore } from '@/store/lock' - -async function setupRouteGuard(router: Router) { - const userStore = useUserStoreWithout() - const permissionStore = useAuthStoreWithout() - const lockStore = useLockStore() - const authStore = useAuthStoreWithout() - const stores = { - userStore, - permissionStore, - lockStore, - authStore, - } - initGuard(stores) - createBasicGuard(router) - createAuthGuard(router) - createTabsGuard(router, setRouteChange) - // must after createPermissionGuard (menu has been built.) - createParamMenuGuard(router) -} - -export { setupRouteGuard } diff --git a/apps/grid-admin/src/router/helper/index.ts b/apps/grid-admin/src/router/helper/index.ts deleted file mode 100644 index 4637bce6..00000000 --- a/apps/grid-admin/src/router/helper/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './menu' -export * from './route' diff --git a/apps/grid-admin/src/router/helper/menu.ts b/apps/grid-admin/src/router/helper/menu.ts deleted file mode 100644 index 485ca352..00000000 --- a/apps/grid-admin/src/router/helper/menu.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { isUrl, cloneDeep, findParentPath, mapTree } from '@vben/utils' -import { RouteParams } from 'vue-router' -import { toRaw } from 'vue' -import { Menu, MenuModule } from '@vben/types' - -export function getAllParentPath>( - treeData: T[], - path: string, -) { - const menuList = findParentPath(treeData, (n) => n.path === path) as Menu[] - return (menuList || []).map((item) => item.path) -} - -function joinParentPath(menus: RouteRecordItem[], parentPath = '') { - for (let index = 0; index < menus.length; index++) { - const menu = menus[index] - // https://next.router.vuejs.org/guide/essentials/nested-routes.html - // Note that nested paths that start with / will be treated as a root path. - // This allows you to leverage the component nesting without having to use a nested URL. - if (!(menu.path.startsWith('/') || isUrl(menu.path))) { - // path doesn't start with /, nor is it a url, join parent path - menu.path = `${parentPath}/${menu.path}` - } - if (menu?.children?.length) { - joinParentPath( - menu.children, - menu.meta?.hidePathForChildren ? parentPath : menu.path, - ) - } - } -} - -// Parsing the menu module -export function transformMenuModule(menuModule: MenuModule): Menu { - const { menu } = menuModule - - const menuList = [menu] - - joinParentPath(menuList) - return menuList[0] -} - -export function transformRouteToMenu( - routeModList: RouteRecordItem[], - routerMapping = false, -) { - const cloneRouteModList = cloneDeep(routeModList) - const routeList: RouteRecordItem[] = [] - - cloneRouteModList.forEach((item) => { - if ( - routerMapping && - item.meta?.hideChildrenInMenu && - typeof item.redirect === 'string' - ) { - item.path = item.redirect - } - if (item.meta?.single) { - const realItem = item?.children?.[0] - realItem && routeList.push(realItem) - } else { - routeList.push(item) - } - }) - const list = mapTree(routeList, { - conversion: (node: RouteRecordItem) => { - const { meta: { hideMenu = false } = {} } = node - - return { - ...(node.meta || {}), - meta: node.meta, - name: node.name, - hideMenu, - path: node.path, - ...(node.redirect ? { redirect: node.redirect } : {}), - } - }, - }) - joinParentPath(list) - return cloneDeep(list) -} - -/** - * config menu with given params - */ -const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g -export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) { - const { path, paramPath } = toRaw(menu) - let realPath = paramPath ? paramPath : path - const matchArr = realPath.match(menuParamRegex) - - matchArr?.forEach((it) => { - const realIt = it.substr(1) - if (params[realIt]) { - realPath = realPath.replace(`:${realIt}`, params[realIt] as string) - } - }) - // save original param path. - if (!paramPath && matchArr && matchArr.length > 0) { - menu.paramPath = path - } - menu.path = realPath - // children - menu.children?.forEach((item) => configureDynamicParamsMenu(item, params)) -} diff --git a/apps/grid-admin/src/router/helper/route.ts b/apps/grid-admin/src/router/helper/route.ts deleted file mode 100644 index 719a2b91..00000000 --- a/apps/grid-admin/src/router/helper/route.ts +++ /dev/null @@ -1,182 +0,0 @@ -import type { RouteMeta, Router, RouteRecordNormalized } from 'vue-router' - -import { omit, cloneDeep } from '@vben/utils' -import { createRouter, createWebHashHistory } from 'vue-router' -import { LAYOUT, PARENT_LAYOUT } from '../routes' - -export type LayoutMapKey = 'LAYOUT' - -const IFRAME = () => import('@/pages/sys/iframe/FrameBlank.vue') -export const EXCEPTION_COMPONENT = () => - import('@/pages/sys/exception/index.vue') - -const LayoutMap = new Map Promise>() - -LayoutMap.set('LAYOUT', LAYOUT) -LayoutMap.set('IFRAME', IFRAME) - -let dynamicViewsModules: Record Promise>> - -// Dynamic introduction -function asyncImportRoute(routes: RouteRecordItem[] | undefined) { - dynamicViewsModules = - dynamicViewsModules || import.meta.glob('../../pages/**/*.{vue,tsx}') - - if (!routes) return - routes.forEach((item: any) => { - if (!item.component && item.meta?.frameSrc) { - item.component = 'IFRAME' - } - const { component, name } = item - const { children } = item - if (component) { - const layoutFound = LayoutMap.get(component.toUpperCase()) - if (layoutFound) { - item.component = layoutFound - } else { - item.component = dynamicImport(dynamicViewsModules, component as string) - } - } else if (name) { - item.component = PARENT_LAYOUT() - } - children && asyncImportRoute(children) - }) -} - -function dynamicImport( - dynamicViewsModules: Record Promise>>, - component: string, -) { - const keys = Object.keys(dynamicViewsModules) - const matchKeys = keys.filter((key) => { - const k = key.replace('../../pages', '') - const startFlag = component.startsWith('/') - const endFlag = component.endsWith('.vue') || component.endsWith('.tsx') - const startIndex = startFlag ? 0 : 1 - const lastIndex = endFlag ? k.length : k.lastIndexOf('.') - return k.substring(startIndex, lastIndex) === component - }) - if (matchKeys?.length === 1) { - const matchKey = matchKeys[0] - return dynamicViewsModules[matchKey] - } else if (matchKeys?.length > 1) { - console.warn( - 'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure', - ) - return - } else { - console.warn( - '在src/views/下找不到`' + - component + - '.vue` 或 `' + - component + - '.tsx`, 请自行创建!', - ) - return EXCEPTION_COMPONENT - } -} - -// Turn background objects into routing objects -export function transformObjToRoute( - routeList: RouteRecordItem[], -): T[] { - routeList.forEach((route) => { - const _route: any = route - const component = _route.component as string - if (component) { - console.log(component) - if (component.toUpperCase() === 'LAYOUT') { - route.component = LayoutMap.get(component.toUpperCase()) - } else { - route.children = [cloneDeep(route)] - route.component = LAYOUT - route.name = `${_route.name}Parent` - route.path = '' - const meta = route.meta || ({} as RouteMeta) - meta.single = true - meta.affix = false - route.meta = meta - } - } else { - console.warn('请正确配置路由:' + _route?.name + '的component属性') - } - route.children && asyncImportRoute(route.children) - }) - return routeList as unknown as T[] -} - -/** - * Convert multi-level routing to level 2 routing - */ -export function flatMultiLevelRoutes(routeModules: RouteRecordItem[]) { - const modules: RouteRecordItem[] = cloneDeep(routeModules) - for (let index = 0; index < modules.length; index++) { - const routeModule = modules[index] - if (!isMultipleRoute(routeModule)) { - continue - } - promoteRouteLevel(routeModule) - } - return modules -} - -// Routing level upgrade -function promoteRouteLevel(routeModule: RouteRecordItem) { - // Use vue-router to splice menus - let router: Router | null = createRouter({ - routes: [routeModule as unknown as RouteRecordNormalized], - history: createWebHashHistory(), - }) - - const routes = router.getRoutes() - addToChildren(routes, routeModule.children || [], routeModule) - router = null - routeModule.children = routeModule.children?.map((item): any => - omit(item, 'children'), - ) -} - -// Add all sub-routes to the secondary route -function addToChildren( - routes: RouteRecordNormalized[], - children: RouteRecordItem[], - routeModule: RouteRecordItem, -) { - for (let index = 0; index < children.length; index++) { - const child = children[index] - const route = routes.find((item) => item.name === child.name) - if (!route) { - continue - } - routeModule.children = routeModule.children || [] - if (!routeModule.children.find((item) => item.name === route.name)) { - routeModule.children?.push(route as unknown as RouteRecordItem) - } - if (child.children?.length) { - addToChildren(routes, child.children, routeModule) - } - } -} - -// Determine whether the level exceeds 2 levels -function isMultipleRoute(routeModule: RouteRecordItem) { - if ( - !routeModule || - !Reflect.has(routeModule, 'children') || - !routeModule.children?.length - ) { - return false - } - - const children = routeModule.children - - let flag = false - for (let index = 0; index < children.length; index++) { - const child = children[index] - if (child.children?.length) { - flag = true - break - } - } - return flag -} diff --git a/apps/grid-admin/src/router/index.ts b/apps/grid-admin/src/router/index.ts deleted file mode 100644 index 6b9d96fa..00000000 --- a/apps/grid-admin/src/router/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createRouter, createWebHashHistory } from 'vue-router' -import { routes } from './routes' - -export * from './menus' -export * from './helper' - -// The whitelist should contain basic static routes -const WHITE_NAME_LIST: string[] = [] -;(() => { - const getRouteNames = (routeRecords: RouteRecordItem[]) => - routeRecords.forEach((item) => { - WHITE_NAME_LIST.push(item.name) - if (item?.children?.length) { - getRouteNames(item.children) - } - }) - - getRouteNames(routes) -})() - -// app router -export const router = createRouter({ - history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH), - routes, - strict: true, - scrollBehavior: () => ({ left: 0, top: 0 }), -}) - -// reset router -export function resetRouter() { - router.getRoutes().forEach((route) => { - const { name } = route - if (name && !WHITE_NAME_LIST.includes(name as string)) { - router.hasRoute(name) && router.removeRoute(name) - } - }) -} diff --git a/apps/grid-admin/src/router/menus/index.ts b/apps/grid-admin/src/router/menus/index.ts deleted file mode 100644 index f06ffa34..00000000 --- a/apps/grid-admin/src/router/menus/index.ts +++ /dev/null @@ -1,106 +0,0 @@ -import type { RouteRecordNormalized } from 'vue-router' - -import { useAuthStoreWithout } from '@/store/auth' -import { getAllParentPath } from '@/router/helper/menu' -import { isUrl, filterTree } from '@vben/utils' -import { router } from '@/router' -import { PermissionModeEnum } from '@vben/constants' -import { pathToRegexp } from 'path-to-regexp' -import { useConfigStoreWithOut } from '@/store/config' -import { Menu } from '@vben/types' - -// =========================== -// ==========Helper=========== -// =========================== - -const getPermissionMode = () => { - const appStore = useConfigStoreWithOut() - return appStore.getProjectConfig.permissionMode -} -const isBackMode = () => { - return getPermissionMode() === PermissionModeEnum.BACK -} - -const isRoleMode = () => { - return getPermissionMode() === PermissionModeEnum.ROLE -} - -async function getAsyncMenus() { - const permissionStore = useAuthStoreWithout() - if (isBackMode()) { - return permissionStore.getBackMenuList.filter( - (item) => !item.meta?.hideMenu && !item.hideMenu, - ) - } - - return permissionStore.getFrontMenuList.filter( - (item) => !item.hideMenu && !item.meta?.hideMenu, - ) -} - -export const getMenus = async (): Promise => { - const menus = await getAsyncMenus() - - if (isRoleMode()) { - const routes = router.getRoutes() - return filterTree(menus, basicFilter(routes)) - } - return menus -} - -export async function getCurrentParentPath(currentPath: string) { - const menus = await getAsyncMenus() - const allParentPath = await getAllParentPath(menus, currentPath) - return allParentPath?.[0] -} - -// Get the level 1 menu, delete children -export async function getShallowMenus(): Promise { - const menus = await getAsyncMenus() - const shallowMenuList = menus.map((item) => ({ - ...item, - children: undefined, - })) - if (isRoleMode()) { - const routes = router.getRoutes() - return shallowMenuList.filter(basicFilter(routes)) - } - return shallowMenuList -} - -// Get the children of the menu -export async function getChildrenMenus(parentPath: string) { - const menus = await getMenus() - const parent = menus.find((item) => item.path === parentPath) - if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) { - return [] as Menu[] - } - if (isRoleMode()) { - const routes = router.getRoutes() - return filterTree(parent.children, basicFilter(routes)) - } - return parent.children -} - -function basicFilter(routes: RouteRecordNormalized[]) { - return (menu: Menu) => { - const matchRoute = routes.find((route) => { - if (isUrl(menu.path)) return true - - if (route.meta?.carryParam) { - return pathToRegexp(route.path).test(menu.path) - } - const isSame = route.path === menu.path - if (!isSame) return false - - if (route.meta?.ignoreAuth) return true - - return isSame || pathToRegexp(route.path).test(menu.path) - }) - - if (!matchRoute) return false - menu.icon = (menu.icon || matchRoute.meta.icon) as string - menu.meta = matchRoute.meta - return true - } -} diff --git a/apps/grid-admin/src/router/routes/basic.ts b/apps/grid-admin/src/router/routes/basic.ts deleted file mode 100644 index d084d2ab..00000000 --- a/apps/grid-admin/src/router/routes/basic.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - REDIRECT_NAME, - PAGE_NOT_FOUND_NAME, - BASIC_HOME_PATH, -} from '@vben/constants' -import { Redirect } from '@vben/components' -import { t } from '@vben/locale' - -const LAYOUT = () => import('@/layout/index.vue') - -const PARENT_LAYOUT = () => () => - new Promise((resolve) => { - resolve({ name: 'ParentLayout' }) - }) - -const PAGE_NOT_FOUND_ROUTE: RouteRecordItem = { - path: '/:path(.*)*', - name: PAGE_NOT_FOUND_NAME, - component: LAYOUT, - meta: { - title: 'ErrorPage', - key: 333, - }, - children: [ - { - path: '/:path(.*)*', - name: PAGE_NOT_FOUND_NAME, - component: () => import('@/pages/sys/exception/index.vue'), - meta: { - title: 'ErrorPage', - key: 3333, - }, - }, - ], -} - -// 404 on a page -const REDIRECT_ROUTE: RouteRecordItem = { - path: '/redirect', - component: LAYOUT, - name: 'RedirectTo', - meta: { - title: REDIRECT_NAME, - hideBreadcrumb: true, - hideMenu: true, - }, - children: [ - { - path: '/redirect/:path(.*)', - name: REDIRECT_NAME, - component: Redirect, - meta: { - title: REDIRECT_NAME, - hideBreadcrumb: true, - }, - }, - ], -} - -const ROOT_ROUTE: RouteRecordItem = { - path: '/', - name: 'Root', - redirect: BASIC_HOME_PATH, - meta: { - title: 'Root', - }, -} - -const LOGIN_ROUTE: RouteRecordItem = { - path: '/login', - name: 'Login', - component: () => import('@/pages/sys/login/login.vue'), - meta: { - title: t('routes.basic.login'), - }, -} - -const LOCK_SCREEN_ROUTE: RouteRecordItem = { - path: '/lock', - name: 'Lock', - component: () => import('@/pages/sys/lock/index.vue'), - meta: { - title: t('routes.basic.lock'), - }, -} - -export { - LAYOUT, - PARENT_LAYOUT, - PAGE_NOT_FOUND_ROUTE, - REDIRECT_ROUTE, - ROOT_ROUTE, - LOGIN_ROUTE, - LOCK_SCREEN_ROUTE -} diff --git a/apps/grid-admin/src/router/routes/index.ts b/apps/grid-admin/src/router/routes/index.ts deleted file mode 100644 index 4e8cdff6..00000000 --- a/apps/grid-admin/src/router/routes/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { - LOGIN_ROUTE, - PAGE_NOT_FOUND_ROUTE, - REDIRECT_ROUTE, - ROOT_ROUTE, - LOCK_SCREEN_ROUTE -} from './basic' - -export * from './basic' - -const routeModuleRecord = import.meta.globEager('./modules/**/*.ts') as any - -const routeModules: RouteRecordItem[] = [] - -Object.keys(routeModuleRecord).forEach((key) => { - const routeModule = routeModuleRecord[key].default || {} - routeModules.push( - ...(Array.isArray(routeModule) ? [...routeModule] : [routeModule]), - ) -}) - -export const asyncRoutes = [...routeModules] - -export const routes = [ - LOGIN_ROUTE, - LOCK_SCREEN_ROUTE, - ROOT_ROUTE, - REDIRECT_ROUTE, - PAGE_NOT_FOUND_ROUTE, -] diff --git a/apps/grid-admin/src/router/routes/modules/dashboard.ts b/apps/grid-admin/src/router/routes/modules/dashboard.ts deleted file mode 100644 index c58bacef..00000000 --- a/apps/grid-admin/src/router/routes/modules/dashboard.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { LAYOUT } from '../basic' - -const dashboard: RouteRecordItem = { - path: '/dashboard', - name: 'Dashboard', - component: LAYOUT, - redirect: '/dashboard/analysis', - meta: { - orderNo: 1, - icon: 'mdi:monitor-dashboard', - title: 'routes.dashboard.dashboard', - }, - children: [ - { - path: 'analysis', - name: 'Analysis', - component: () => import('@/pages/dashboard/analysis/index.vue'), - meta: { - icon: 'mdi:monitor-dashboard', - title: 'routes.dashboard.analysis', - }, - }, - { - path: 'workbench', - name: 'Workbench', - component: () => import('@/pages/dashboard/workbench/index.vue'), - meta: { - title: 'routes.dashboard.workbench', - }, - }, - ], -} - -export default dashboard diff --git a/apps/grid-admin/src/router/routes/modules/demo/demo.ts b/apps/grid-admin/src/router/routes/modules/demo/demo.ts deleted file mode 100644 index 4dee29aa..00000000 --- a/apps/grid-admin/src/router/routes/modules/demo/demo.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {LAYOUT} from '../../basic' - -const dashboard: RouteRecordItem = { - path: '/demo', - name: 'Demo', - component: LAYOUT, - redirect: '/dashboard/form', - meta: { - orderNo: 2, - icon: 'line-md:clipboard-list-twotone', - title: 'routes.demo.demo', - }, - children: [ - { - path: 'table', - name: 'Table', - redirect: '/demo/form/basic', - meta: { - title: 'routes.demo.table.table', - }, - children: [{ - path: 'useTable', - name: 'UseTableDemo', - component: () => import('@/pages/demo/table/BasicTable.vue'), - meta: { - title: 'routes.demo.table.basic', - }, - }] - }, - { - path: 'form', - name: 'Form', - component: () => import('@/pages/demo/Form.vue'), - meta: { - title: 'routes.demo.form', - }, - }, - { - path: 'card', - name: 'Card', - component: () => import('@/pages/demo/Card.vue'), - meta: { - title: 'routes.demo.card', - }, - }, - { - path: 'draggable', - name: 'Draggable', - component: () => import('@/pages/demo/Draggable.vue'), - meta: { - title: '拖拽', - }, - }, - ], -} - -export default dashboard diff --git a/apps/grid-admin/src/router/routes/modules/demo/editor.ts b/apps/grid-admin/src/router/routes/modules/demo/editor.ts deleted file mode 100644 index 72955692..00000000 --- a/apps/grid-admin/src/router/routes/modules/demo/editor.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LAYOUT } from '@/router/routes' - -const Editor: RouteRecordItem = { - path: '/editor', - name: 'Editor', - component: LAYOUT, - meta: { - orderNo: 3, - title: '编辑器', - icon: 'openmoji:code-editor' - }, - children: [ - { - path: 'monaco-editor', - name: 'monaco-editor', - component: () => import('@/pages/demo/editor/monaco-editor.vue'), - meta: { - title: 'monaco-editor', - }, - }, - ], -} - -export default Editor diff --git a/apps/grid-admin/src/router/routes/modules/demo/page.ts b/apps/grid-admin/src/router/routes/modules/demo/page.ts deleted file mode 100644 index 2c7099b2..00000000 --- a/apps/grid-admin/src/router/routes/modules/demo/page.ts +++ /dev/null @@ -1,13 +0,0 @@ -const Page: RouteRecordItem = { - path: '/pageTest', - name: 'PageTest', - component: () => import('@/pages/demo/page/index.vue'), - meta: { - orderNo: 4, - title: '非框架页面', - icon: 'tabler:frame-off', - hideTab: true - }, -} - -export default Page diff --git a/apps/grid-admin/src/setting/design.ts b/apps/grid-admin/src/setting/design.ts deleted file mode 100644 index 6ec88ce9..00000000 --- a/apps/grid-admin/src/setting/design.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - ThemeEnum, - SIDE_BAR_BG_COLOR_LIST, - HEADER_PRESET_BG_COLOR_LIST, - APP_PRESET_COLOR_LIST -} from '@vben/constants' - - -export const namespace = 'vben' - -export const primaryColor = '#0960bd' - -export const darkMode = ThemeEnum.LIGHT - - -export { - // app theme preset color - SIDE_BAR_BG_COLOR_LIST, - // header preset color - HEADER_PRESET_BG_COLOR_LIST, - // sider preset color - APP_PRESET_COLOR_LIST -} diff --git a/apps/grid-admin/src/setting/index.ts b/apps/grid-admin/src/setting/index.ts deleted file mode 100644 index 0632d759..00000000 --- a/apps/grid-admin/src/setting/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './design' -export * from './project' diff --git a/apps/grid-admin/src/setting/project.ts b/apps/grid-admin/src/setting/project.ts deleted file mode 100644 index b0958a52..00000000 --- a/apps/grid-admin/src/setting/project.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { ProjectConfig } from '@vben/types' -import { - CacheTypeEnum, - ContentLayoutEnum, - MenuModeEnum, - MenuTypeEnum, - MixSidebarTriggerEnum, - PermissionModeEnum, - SessionTimeoutProcessingEnum, - SettingButtonPositionEnum, - ThemeEnum, - TriggerEnum, - RouterTransitionEnum, -} from '@vben/constants' - -import { - SIDE_BAR_BG_COLOR_LIST, - HEADER_PRESET_BG_COLOR_LIST, - primaryColor, -} from './design' - -// ! You need to clear the browser cache after the change -export const projectSetting: ProjectConfig = { - // Whether to show the configuration button - showSettingButton: true, - - // Whether to show the theme switch button - showDarkModeToggle: true, - - // `Settings` button position - settingButtonPosition: SettingButtonPositionEnum.AUTO, - - // Permission mode - permissionMode: PermissionModeEnum.ROUTE_MAPPING, - - // Permission-related cache is stored in sessionStorage or localStorage - permissionCacheType: CacheTypeEnum.LOCAL, - - // Session timeout processing - sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP, - - // color - themeColor: primaryColor, - - // Website gray mode, open for possible mourning dates - grayMode: false, - - // Color Weakness Mode - colorWeak: false, - - // Whether to cancel the menu, the top, the multi-tab page display, for possible embedded in other systems - fullContent: false, - - // content mode - contentMode: ContentLayoutEnum.FULL, - - // Whether to display the logo - showLogo: true, - - // Whether to show footer - showFooter: false, - - // Header configuration - headerSetting: { - // header bg color - bgColor: HEADER_PRESET_BG_COLOR_LIST[0], - // Fixed at the top - fixed: true, - // Whether to show top - show: true, - // theme - theme: ThemeEnum.LIGHT, - // Whether to enable the lock screen function - useLockPage: true, - // Whether to show the full screen button - showFullScreen: true, - // Whether to show the document button - showDoc: true, - // Whether to show the notification button - showNotice: true, - // Whether to display the menu search - showSearch: true, - showLocalePicker: true, - }, - - // Menu configuration - menuSetting: { - // sidebar menu bg color - bgColor: SIDE_BAR_BG_COLOR_LIST[0], - // Whether to fix the left menu - fixed: true, - // Menu collapse - collapsed: false, - // Whether to display the menu name when folding the menu - collapsedShowTitle: false, - // Whether it can be dragged - // Only limited to the opening of the left menu, the mouse has a drag bar on the right side of the menu - canDrag: false, - // Whether to show no dom - show: true, - // Whether to show dom - hidden: false, - // Menu width - menuWidth: 210, - // Menu mode - mode: MenuModeEnum.INLINE, - // Menu type - type: MenuTypeEnum.SIDEBAR, - // Menu theme - theme: ThemeEnum.DARK, - // Split menu - split: false, - // Top menu layout - topMenuAlign: 'center', - // Fold trigger position - trigger: TriggerEnum.HEADER, - // Turn on accordion mode, only show a menu - accordion: true, - // Switch page to close menu - closeMixSidebarOnChange: false, - // Module opening method ‘click’ |'hover' - mixSideTrigger: MixSidebarTriggerEnum.CLICK, - // Fixed expanded menu - mixSideFixed: false, - }, - // Transition Setting - transitionSetting: { - // Whether to open the page switching animation - // The disabled state will also disable pageLoading - enable: true, - - // Route basic switching animation - basicTransition: RouterTransitionEnum.FADE_SIDE, - - // Whether to open page switching loading - // Only open when enable=true - openPageLoading: true, - - // Whether to open the top progress bar - openNProgress: false, - }, - - // Multi-label - multiTabsSetting: { - cache: false, - // Turn on - show: true, - // Is it possible to drag and drop sorting tabs - canDrag: true, - // Turn on quick actions - showQuick: true, - // Whether to show the refresh button - showRedo: true, - // Whether to show the collapse button - showFold: true, - }, - - // Whether to open the top progress bar - openNProgress: false, - - // Whether to enable KeepAlive cache is best to close during development, otherwise the cache needs to be cleared every time - openKeepAlive: true, - - // Automatic screen lock time, 0 does not lock the screen. Unit minute default 0 - lockTime: 0, - - // Whether to show breadcrumbs - showBreadCrumb: true, - - // Whether to show the breadcrumb icon - showBreadCrumbIcon: true, - - // Whether to open back to top - useOpenBackTop: true, - - // Is it possible to embed iframe pages - canEmbedIFramePage: true, - - // Whether to delete unclosed messages and notify when switching the interface - closeMessageOnSwitch: true, - - // Whether to cancel the http request that has been sent but not responded when switching the interface. - // If it is enabled, I want to overwrite a single interface. Can be set in a separate interface - removeAllHttpPending: false, -} diff --git a/apps/grid-admin/src/store/auth.ts b/apps/grid-admin/src/store/auth.ts deleted file mode 100644 index 447126cd..00000000 --- a/apps/grid-admin/src/store/auth.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { defineStore } from 'pinia' -import { asyncRoutes, PAGE_NOT_FOUND_ROUTE } from '@/router/routes' -import { filterTree } from '@vben/utils' -import { Menu } from '@vben/types' -import { useConfigStoreWithOut } from './config' -import { useUserStore } from './user' -import { getPermCode } from '@/apis/auth' -import { toRaw } from 'vue' -import { projectSetting } from '@/setting' -import { PermissionModeEnum, PageEnum } from '@vben/constants' -import { - flatMultiLevelRoutes, - transformObjToRoute, - transformRouteToMenu, -} from '@/router' -import { getMenuList } from '@/apis/sys' - -interface AuthState { - // Permission code list - permCodeList: string[] | number[] - // Whether the route has been dynamically added - isDynamicAddedRoute: boolean - // To trigger a menu update - lastBuildMenuTime: number - // Backstage menu list - backMenuList: Menu[] - frontMenuList: Menu[] -} - -export const useAuthStore = defineStore({ - id: 'app-auth-store', - state: (): AuthState => ({ - permCodeList: [], - // Whether the route has been dynamically added - isDynamicAddedRoute: false, - // To trigger a menu update - lastBuildMenuTime: 0, - // Backstage menu list - backMenuList: [], - // menu List - frontMenuList: [], - }), - getters: { - getPermCodeList(): string[] | number[] { - return this.permCodeList - }, - getBackMenuList(): Menu[] { - return this.backMenuList - }, - getFrontMenuList(): Menu[] { - return this.frontMenuList - }, - getLastBuildMenuTime(): number { - return this.lastBuildMenuTime - }, - getIsDynamicAddedRoute(): boolean { - return this.isDynamicAddedRoute - }, - }, - actions: { - setPermCodeList(codeList: string[]) { - this.permCodeList = codeList - }, - - setBackMenuList(list: Menu[]) { - this.backMenuList = list - list?.length > 0 && this.setLastBuildMenuTime() - }, - - setFrontMenuList(list: Menu[]) { - this.frontMenuList = list - }, - - setLastBuildMenuTime() { - this.lastBuildMenuTime = new Date().getTime() - }, - - setDynamicAddedRoute(added: boolean) { - this.isDynamicAddedRoute = added - }, - resetState(): void { - this.isDynamicAddedRoute = false - this.permCodeList = [] - this.backMenuList = [] - this.lastBuildMenuTime = 0 - }, - async changePermissionCode() { - const codeList = await getPermCode() - this.setPermCodeList(codeList) - }, - async buildRoutesAction(): Promise { - // const { t } = useI18n() - const userStore = useUserStore() - const configStore = useConfigStoreWithOut() - - let routes: RouteRecordItem[] = [] - const roleList = toRaw(userStore.getRoles) || [] - const { permissionMode = projectSetting.permissionMode } = - configStore.getProjectConfig - - const routeFilter = (route: RouteRecordItem) => { - const { meta } = route - const { roles } = meta || {} - if (!roles) return true - return roleList.some((role) => roles.includes(role)) - } - - const routeRemoveIgnoreFilter = (route: RouteRecordItem) => { - const { meta } = route - const { ignoreRoute } = meta || {} - return !ignoreRoute - } - - /** - * @description 根据设置的首页path,修正routes中的affix标记(固定首页) - * */ - const patchHomeAffix = (routes: RouteRecordItem[]) => { - if (!routes || routes.length === 0) return - let homePath: string = - userStore.getUserInfo?.homePath || PageEnum.BASE_HOME - function patcher(routes: RouteRecordItem[], parentPath = '') { - if (parentPath) parentPath = parentPath + '/' - routes.forEach((route: RouteRecordItem) => { - const { path, children, redirect } = route - const currentPath = path.startsWith('/') ? path : parentPath + path - if (currentPath === homePath) { - if (redirect) { - homePath = route.redirect! as string - } else { - route.meta = Object.assign({}, route.meta, { affix: true }) - throw new Error('end') - } - } - children && children.length > 0 && patcher(children, currentPath) - }) - } - try { - patcher(routes) - } catch (e) { - // 已处理完毕跳出循环 - } - return - } - - switch (permissionMode) { - case PermissionModeEnum.ROLE: - routes = filterTree(asyncRoutes, routeFilter) - routes = routes.filter(routeFilter) - // Convert multi-level routing to level 2 routing - routes = flatMultiLevelRoutes(routes) - break - - case PermissionModeEnum.ROUTE_MAPPING: - routes = filterTree(asyncRoutes, routeFilter) - routes = routes.filter(routeFilter) - const menuList = transformRouteToMenu(routes, true) - routes = filterTree(routes, routeRemoveIgnoreFilter) - routes = routes.filter(routeRemoveIgnoreFilter) - menuList.sort((a, b) => { - return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0) - }) - - this.setFrontMenuList(menuList as Menu[]) - - // Convert multi-level routing to level 2 routing - routes = flatMultiLevelRoutes(routes) - break - - // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below - case PermissionModeEnum.BACK: - // const { createMessage } = useMessage() - - // createMessage.loading(t('sys.app.menuLoading')) - - // !Simulate to obtain permission codes from the background, - // this function may only need to be executed once, and the actual project can be put at the right time by itself - let routeList: RouteRecordItem[] = [] - try { - this.changePermissionCode() - routeList = (await getMenuList()) as RouteRecordItem[] - } catch (error) { - console.error(error) - } - - // Dynamically introduce components - routeList = transformObjToRoute(routeList) - - // Background routing to menu structure - const backMenuList = transformRouteToMenu(routeList) - this.setBackMenuList(backMenuList as Menu[]) - - // remove meta.ignoreRoute item - routeList = filterTree(routeList, routeRemoveIgnoreFilter) - routeList = routeList.filter(routeRemoveIgnoreFilter) - - routeList = flatMultiLevelRoutes(routeList) - routes = [PAGE_NOT_FOUND_ROUTE, ...routeList] - break - } - - patchHomeAffix(routes) - return routes - }, - }, -}) - -// Need to be used outside the setup -export function useAuthStoreWithout() { - return useAuthStore() -} diff --git a/apps/grid-admin/src/store/config.ts b/apps/grid-admin/src/store/config.ts deleted file mode 100644 index c6d54ae0..00000000 --- a/apps/grid-admin/src/store/config.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - BeforeMiniState, - HeaderSetting, - MenuSetting, - MultiTabsSetting, - ProjectConfig, - TransitionSetting, -} from '@vben/types' -import { defineStore } from 'pinia' -import { deepMerge } from '@vben/utils' -import { APP_DARK_MODE_KEY_, ThemeEnum } from '@vben/constants' -import { darkMode, projectSetting } from '@/setting' - -export interface ConfigStoreState { - darkMode?: ThemeEnum - // Page loading status - pageLoading: boolean - // project config - projectConfig: ProjectConfig | null - // When the window shrinks, remember some states, and restore these states when the window is restored - beforeMiniInfo: BeforeMiniState -} - -export const useConfigStore = defineStore({ - id: 'app-config-store', - persist: { - paths: ['darkMode', 'projectConfig'], - }, - state: (): ConfigStoreState => ({ - darkMode: undefined, - pageLoading: false, - projectConfig: {} as any, - beforeMiniInfo: {}, - }), - getters: { - getDarkMode(): ThemeEnum { - return ( - this.darkMode || - (localStorage.getItem(APP_DARK_MODE_KEY_) as ThemeEnum) || - darkMode - ) - }, - getBeforeMiniInfo(): BeforeMiniState { - return this.beforeMiniInfo - }, - getProjectConfig(): ProjectConfig { - return this.projectConfig || ({} as ProjectConfig) - }, - getHeaderSetting(): HeaderSetting { - return this.getProjectConfig.headerSetting - }, - getMenuSetting(): MenuSetting { - return this.getProjectConfig.menuSetting - }, - getMultiTabsSetting(): MultiTabsSetting { - return this.getProjectConfig.multiTabsSetting - }, - getPageLoading(): boolean { - return this.pageLoading - }, - getTransitionSetting(): TransitionSetting { - return this.getProjectConfig.transitionSetting - }, - }, - actions: { - setBeforeMiniInfo(state: BeforeMiniState): void { - this.beforeMiniInfo = state - }, - setProjectConfig(config: DeepPartial): void { - this.projectConfig = deepMerge(this.projectConfig || {}, config) - }, - setDarkMode(mode: ThemeEnum): void { - this.darkMode = mode - localStorage.setItem(APP_DARK_MODE_KEY_, mode) - }, - async setPageLoadingAction(loading: boolean): Promise { - console.log(loading) - }, - resetProjectConfig() { - this.setProjectConfig(projectSetting) - }, - }, -}) - -export function useConfigStoreWithOut() { - return useConfigStore() -} diff --git a/apps/grid-admin/src/store/lock.ts b/apps/grid-admin/src/store/lock.ts deleted file mode 100644 index 6296215a..00000000 --- a/apps/grid-admin/src/store/lock.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { LockInfo } from '@vben/types' -import { defineStore } from 'pinia' -import { useUserStore } from '@/store/user' - -interface LockState { - lockInfo: Nullable -} - -export const useLockStore = defineStore({ - id: 'app-lock', - persist: { - paths: ['lockInfo'], - }, - state: (): LockState => ({ - lockInfo: {}, - }), - getters: { - getLockInfo(): Nullable { - return this.lockInfo - }, - }, - actions: { - setLockInfo(info: LockInfo) { - this.lockInfo = Object.assign({}, this.lockInfo, info) - }, - resetLockInfo() { - this.lockInfo = null - }, - async unLock(password?: string) { - const userStore = useUserStore() - if (this.lockInfo?.pwd === password) { - this.resetLockInfo() - return true - } - const tryLogin = async () => { - try { - const username = userStore.getUserInfo?.username ?? '' - const res = await userStore.login({ - username, - password: password!, - goHome: false, - mode: 'none', - }) - if (res) { - this.resetLockInfo() - } - return res - } catch (error) { - return false - } - } - return await tryLogin() - }, - }, -}) diff --git a/apps/grid-admin/src/store/modules/app.ts b/apps/grid-admin/src/store/modules/app.ts deleted file mode 100644 index 6b1afc8c..00000000 --- a/apps/grid-admin/src/store/modules/app.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { defineStore } from 'pinia' -// import { pinia } from '@/pinia' -import { resetRouter } from '@/router' - -interface AppState { - pageLoading: boolean -} -let timeId: TimeoutHandle -export const useAppStore = defineStore({ - id: 'app', - state: (): AppState => ({ - pageLoading: false, - }), - getters: { - getPageLoading(): boolean { - return this.pageLoading - }, - }, - actions: { - setPageLoading(loading: boolean): void { - this.pageLoading = loading - }, - async resetAllState() { - resetRouter() - // Persistent.clearAll() - }, - async setPageLoadingAction(loading: boolean): Promise { - if (loading) { - clearTimeout(timeId) - // Prevent flicker - timeId = setTimeout(() => { - this.setPageLoading(loading) - }, 50) - } else { - this.setPageLoading(loading) - clearTimeout(timeId) - } - }, - }, -}) - -// Need to be used outside the setup -export function useAppStoreWithOut() { - return useAppStore() -} diff --git a/apps/grid-admin/src/store/test.ts b/apps/grid-admin/src/store/test.ts deleted file mode 100644 index 6b6e0c3b..00000000 --- a/apps/grid-admin/src/store/test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineStore } from 'pinia' - -export const useTest = defineStore({ - id: 'use--test', - state: () => ({ - test: '人孔盖福利卡', - }), - persist: true, -}) diff --git a/apps/grid-admin/src/store/user.ts b/apps/grid-admin/src/store/user.ts deleted file mode 100644 index 0c1edfee..00000000 --- a/apps/grid-admin/src/store/user.ts +++ /dev/null @@ -1,166 +0,0 @@ -import type { LoginParams } from '@/apis/auth' -import { defineStore } from 'pinia' -import { BASIC_HOME_PATH, BASIC_LOGIN_PATH, PageEnum } from '@vben/constants' -// import { pinia } from '@/pinia' -import { router } from '@/router' -import { doLogoutApi, getUserInfoApi, doLoginApi } from '@/apis/auth' -import { PAGE_NOT_FOUND_ROUTE } from '@/router/routes' -import { useAuthStoreWithout } from './auth' -import { GetUserInfoModel } from '@/apis/sys/user' -import { UserInfo, RoleInfo } from '@vben/types' -import { ErrorMessageMode } from '@vben/types' -import { isArray } from '@vben/utils' - -interface UserState { - userInfo: Nullable - accessToken?: string - roles: RoleInfo[] - sessionTimeout?: boolean - lastUpdateTime: number -} - -export const useUserStore = defineStore({ - id: 'app-user-store', - persist: { - paths: ['userInfo', 'accessToken', 'roles'], - }, - state: (): UserState => ({ - userInfo: null, - accessToken: undefined, - roles: [], - // Whether the login expired - sessionTimeout: false, - // Last fetch time - lastUpdateTime: 0, - }), - getters: { - getUserInfo(): UserInfo | null { - return this.userInfo - }, - getAccessToken(): string | undefined { - return this.accessToken - }, - getRoles(): RoleInfo[] { - return this.roles.length > 0 ? this.roles : [] - }, - getSessionTimeout(): boolean { - return !!this.sessionTimeout - }, - getLastUpdateTime(): number { - return this.lastUpdateTime - }, - }, - actions: { - setAccessToken(info: string | undefined) { - this.accessToken = info ? info : '' - }, - setRoles(roles: RoleInfo[]) { - this.roles = roles - }, - setUserInfo(info: UserInfo | null) { - this.userInfo = info - this.lastUpdateTime = new Date().getTime() - }, - setSessionTimeout(flag: boolean) { - this.sessionTimeout = flag - }, - resetState() { - this.userInfo = null - this.accessToken = undefined - this.roles = [] - this.sessionTimeout = false - }, - - async login( - params: LoginParams & { - goHome?: boolean - mode?: ErrorMessageMode - }, - ): Promise { - try { - const { goHome = true, mode, ...loginParams } = params - const { accessToken } = await doLoginApi(loginParams, mode) - - // save token - this.setAccessToken(accessToken) - if (!this.getAccessToken) { - return null - } - const userInfo = await this.getUserInfoAction() - if (goHome) { - await router.replace(BASIC_HOME_PATH) - } - return userInfo - } catch (error) { - return Promise.reject(error) - } - }, - async afterLoginAction(goHome?: boolean): Promise { - if (!this.getAccessToken) { - return null - } - // get user info - const userInfo = await this.getUserInfoAction() - - const sessionTimeout = this.sessionTimeout - if (sessionTimeout) { - this.setSessionTimeout(false) - } else { - const permissionStore = useAuthStoreWithout() - if (!permissionStore.isDynamicAddedRoute) { - const routes = await permissionStore.buildRoutesAction() - routes.forEach((route) => { - router.addRoute(route) - }) - router.addRoute(PAGE_NOT_FOUND_ROUTE) - permissionStore.setDynamicAddedRoute(true) - } - goHome && - (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)) - } - return userInfo - }, - - async getUserInfoAction(): Promise { - if (!this.getAccessToken) { - return null - } - - const userInfo = (await getUserInfoApi()) as unknown as UserInfo - const { roles = [] } = userInfo - if (isArray(roles)) { - const roleList = roles.map( - (item) => item.value, - ) as unknown as RoleInfo[] - this.setRoles(roleList) - } else { - userInfo.roles = [] - this.setRoles([]) - } - this.setUserInfo(userInfo) - - return userInfo - }, - - async logout(goLogin = false) { - if (this.getAccessToken) { - try { - await doLogoutApi() - } catch (error: any) { - console.log('logout error:' + error.toString()) - } - } - this.setAccessToken(undefined) - this.setSessionTimeout(false) - this.setUserInfo(null) - if (goLogin) { - router.push(BASIC_LOGIN_PATH) - } - }, - }, -}) - -// Need to be used outside the setup -export function useUserStoreWithout() { - return useUserStore() -} diff --git a/apps/grid-admin/tsconfig.json b/apps/grid-admin/tsconfig.json deleted file mode 100644 index 7cfe3b67..00000000 --- a/apps/grid-admin/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "extends": "tsconfig/base.json", - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "baseUrl": ".", - "paths": { - "@/*": ["src/*"], - "#/*": ["src/*"] - }, - "lib": ["dom", "esnext"], - "types": [ - "vite/client", - "@vben/constant", - "@vben/types/shims/pinia", - "@vben/types/shims/vue-router", - ] - }, - "include": [ - "src", - "mock", - "vite.config.ts", - "../../node_modules/.pnpm/vue@3.2.45/node_modules/vue/macros-global.d.ts" - ] -} diff --git a/apps/grid-admin/vite.config.ts b/apps/grid-admin/vite.config.ts deleted file mode 100644 index 62f5a739..00000000 --- a/apps/grid-admin/vite.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createViteConfig } from '@config/vite' -import { defineConfig, UserConfig } from 'vite' - -export default defineConfig(async ({ command, mode }): Promise => { - const cfg = await createViteConfig(command, mode, process.cwd(), { preset: 'antd' }) - return cfg -}) diff --git a/packages/grid-layouts/package.json b/packages/grid-layouts/package.json index 966f580c..ce8f85c5 100644 --- a/packages/grid-layouts/package.json +++ b/packages/grid-layouts/package.json @@ -13,6 +13,7 @@ "@vben/hooks": "workspace:*", "@vben/locale": "workspace:*", "@vben/stores": "workspace:*", + "@vben/router": "workspace:*", "@vben/utils": "workspace:*", "@vben/vbencomponents": "workspace:*", "pinia": "^2.0.30", diff --git a/packages/grid-layouts/src/components/Layout.vue b/packages/grid-layouts/src/components/Layout.vue index 65e9cd9d..deb3174e 100644 --- a/packages/grid-layouts/src/components/Layout.vue +++ b/packages/grid-layouts/src/components/Layout.vue @@ -11,8 +11,12 @@ import { useLayoutTab, useLayoutContent, } from '@vben/stores' -import {useAppConfig, createGridLayoutListen, createThemeColorListen} from '@vben/hooks' -import {nextTick, ref} from 'vue' +import { + useAppConfig, + createGridLayoutListen, + createThemeColorListen, +} from '@vben/hooks' +import { nextTick, ref } from 'vue' import { MaybeElementRef } from '@vben/utils' const { headerRef } = storeToRefs(useLayoutHeader() as StoreGeneric) @@ -22,7 +26,7 @@ const { contentRef } = storeToRefs(useLayoutContent() as StoreGeneric) const containerRef = ref(null) const { navBarMode } = useAppConfig() -nextTick(()=>{ +nextTick(() => { createGridLayoutListen(containerRef) createThemeColorListen(containerRef) }) @@ -43,10 +47,11 @@ nextTick(()=>{ diff --git a/packages/grid-layouts/src/components/breadcrumb/index.vue b/packages/grid-layouts/src/components/breadcrumb/index.vue index bfb0aba5..1d6f970e 100644 --- a/packages/grid-layouts/src/components/breadcrumb/index.vue +++ b/packages/grid-layouts/src/components/breadcrumb/index.vue @@ -1,13 +1,130 @@ - - - - - - breadcrumb + + + + + + {{ t(route.meta.title) }} + + + + + diff --git a/packages/grid-layouts/src/components/comm/SuffixItemWrapper.vue b/packages/grid-layouts/src/components/comm/SuffixItemWrapper.vue new file mode 100644 index 00000000..6cba67fb --- /dev/null +++ b/packages/grid-layouts/src/components/comm/SuffixItemWrapper.vue @@ -0,0 +1,11 @@ + + + + + + + diff --git a/packages/grid-layouts/src/components/comm/TopButtonWrapper.vue b/packages/grid-layouts/src/components/comm/TopButtonWrapper.vue index 2ae01435..b925bd84 100644 --- a/packages/grid-layouts/src/components/comm/TopButtonWrapper.vue +++ b/packages/grid-layouts/src/components/comm/TopButtonWrapper.vue @@ -1,6 +1,5 @@ - diff --git a/packages/grid-layouts/src/components/composables/LayoutContent.vue b/packages/grid-layouts/src/components/composables/LayoutContent.vue index 3bf776e7..ad490ed8 100644 --- a/packages/grid-layouts/src/components/composables/LayoutContent.vue +++ b/packages/grid-layouts/src/components/composables/LayoutContent.vue @@ -6,9 +6,15 @@ import { StoreGeneric, storeToRefs } from 'pinia' const { footerRef } = storeToRefs(useLayoutFooter() as StoreGeneric) - - - + + + + + + + diff --git a/packages/grid-layouts/src/components/menu/renderMenu.ts b/packages/grid-layouts/src/components/menu/renderMenu.ts new file mode 100644 index 00000000..9cb829a7 --- /dev/null +++ b/packages/grid-layouts/src/components/menu/renderMenu.ts @@ -0,0 +1,113 @@ +import { h, unref, VNode } from 'vue' +import { useAppConfig } from '@vben/hooks' +import { RouterLink } from 'vue-router' +import { renderIcon } from '../render' +import { useI18n } from '@vben/locale' + +const { t } = useI18n() + +type MenuOption = { + collapseTitle: string + key: string + icon: () => VNode + root?: boolean + + collapsedShowTitle?: boolean +} +export function renderMenuIcon(menuOption: MenuOption): VNode | undefined { + const { collapseTitle, icon, root, collapsedShowTitle } = menuOption + + if (!icon) return undefined + const { getCollapsedShowTitle } = useAppConfig() + if (unref(getCollapsedShowTitle) && (root || collapsedShowTitle)) { + return h( + 'div', + { + class: 'flex-center flex-col h-full w-full absolute', + style: { left: '0' }, + }, + [ + icon(), + h( + 'div', + { + class: 'truncate', + style: 'font-size: 12px;max-width: 64px;margin-top:2px;', + }, + collapseTitle || '', + ), + ], + ) + } + return icon() +} + +export function renderMenuLabelToRouterLink( + item: RouteRecordItem & { icon?: string }, +) { + const { path, children, meta, icon } = item + + const title = t(meta.title as string) + return { + label: () => { + if (children) { + return title + } + return h( + RouterLink, + { + to: { + path, + }, + }, + { default: () => title }, + ) + }, + key: path, + icon: renderIcon((icon || meta.icon) as unknown as string), + collapseTitle: title, + root: meta?.root || false, + collapsedShowTitle: meta?.collapsedShowTitle || false, + } +} + +export function renderMenuLabel( + item: RouteRecordItem & { icon?: string }, + attrs: Record, +) { + const { path, meta, icon } = item + const title = t(meta.title as string) + const { sidebar } = useAppConfig() + const { onMouseenter, onClick } = attrs + return { + key: path, + label: () => { + return h( + 'div', + { + class: 'flex-center flex-col h-full w-full absolute', + style: { left: '0', top: '0' }, + onMouseenter: () => { + onMouseenter && onMouseenter(item) + }, + onClick: () => { + onClick && onClick(item) + }, + }, + [ + renderIcon(icon)(), + unref(sidebar).collapsed + ? '' + : h( + 'div', + { + class: 'truncate', + style: 'font-size: 12px;max-width: 64px;margin-top:2px;', + }, + title || '', + ), + ], + ) + }, + } +} diff --git a/packages/grid-layouts/src/components/notify/NoticeList.vue b/packages/grid-layouts/src/components/notify/NoticeList.vue new file mode 100644 index 00000000..7cbd9e0c --- /dev/null +++ b/packages/grid-layouts/src/components/notify/NoticeList.vue @@ -0,0 +1,82 @@ + + + + + + + + + {{ item.title }} + + + + + + {{ item.avatar }} + + + + + + {{ item.extra }} + + + {{ item.description }} + + + + {{ item.datetime }} + + + + + + + + + diff --git a/packages/grid-layouts/src/components/notify/data.ts b/packages/grid-layouts/src/components/notify/data.ts new file mode 100644 index 00000000..6b75088c --- /dev/null +++ b/packages/grid-layouts/src/components/notify/data.ts @@ -0,0 +1,206 @@ +export interface ListItem { + id: string + avatar: string + // 通知的标题内容 + title: string + // 是否在标题上显示删除线 + titleDelete?: boolean + datetime: string + type: string + read?: boolean + description: string + clickClose?: boolean + extra?: string + color?: string +} + +export interface TabItem { + key: string + name: string + list: ListItem[] + unreadlist?: ListItem[] +} + +export const tabListData: TabItem[] = [ + { + key: '1', + name: '通知', + list: [ + { + id: '000000001', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + description: '', + datetime: '2017-08-09', + type: '1', + }, + { + id: '000000002', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + description: '', + datetime: '2017-08-08', + type: '1', + }, + { + id: '000000003', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + description: '', + datetime: '2017-08-07', + // read: true, + type: '1', + }, + { + id: '000000004', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000005', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: + '标题可以设置自动显示省略号,本例中标题行数已设为1行,如果内容超过1行将自动截断并支持tooltip显示完整标题。', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000006', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000007', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000008', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000009', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000010', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + ], + }, + { + key: '2', + name: '消息', + list: [ + { + id: '000000006', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + { + id: '000000007', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + { + id: '000000008', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: + '请将鼠标移动到此处,以便测试超长的消息在此处将如何处理。本例中设置的描述最大行数为2,超过2行的描述内容将被省略并且可以通过tooltip查看完整内容', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + ], + }, + { + key: '3', + name: '待办', + list: [ + { + id: '000000009', + avatar: '', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + datetime: '', + extra: '未开始', + color: 'info', + type: '3', + }, + { + id: '000000010', + avatar: '', + title: '第三方紧急代码变更', + description: '冠霖 需在 2017-01-07 前完成代码变更任务', + datetime: '', + extra: '紧急处理', + color: 'error', + type: '3', + }, + { + id: '000000011', + avatar: '', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + datetime: '', + extra: '已耗时 8 天', + color: 'error', + type: '3', + }, + { + id: '000000012', + avatar: '', + title: 'ABCD 版本发布', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + datetime: '', + extra: '进行中', + color: 'success', + type: '3', + }, + ], + }, +] diff --git a/packages/grid-layouts/src/components/notify/index.vue b/packages/grid-layouts/src/components/notify/index.vue index 7f0f7655..888073c0 100644 --- a/packages/grid-layouts/src/components/notify/index.vue +++ b/packages/grid-layouts/src/components/notify/index.vue @@ -1,9 +1,33 @@ - - - - + + + + + + + + + + + + + diff --git a/packages/grid-layouts/src/components/render.ts b/packages/grid-layouts/src/components/render.ts index 4e287e53..ca2a5440 100644 --- a/packages/grid-layouts/src/components/render.ts +++ b/packages/grid-layouts/src/components/render.ts @@ -1,7 +1,7 @@ -import { h } from 'vue' +import { h, VNode } from 'vue' import { VbenIconify } from '@vben/vbencomponents' -export const renderIcon = (icon: string) => { - if (!icon) return undefined +export function renderIcon(icon: string): () => VNode | undefined { + if (!icon) return () => undefined return () => h(VbenIconify, { icon }) } diff --git a/packages/grid-layouts/src/components/setting-drawer/components/InterfaceFunction.vue b/packages/grid-layouts/src/components/setting-drawer/components/InterfaceFunction.vue index 5f51dcb0..1e22fff4 100644 --- a/packages/grid-layouts/src/components/setting-drawer/components/InterfaceFunction.vue +++ b/packages/grid-layouts/src/components/setting-drawer/components/InterfaceFunction.vue @@ -44,6 +44,7 @@ const triggerOptions = getMenuTriggerOptions(menu.split) :disabled="!isMixSidebar" /> - - {{ t('layout.setting.sysTheme') }} - - + + + {{ t('layout.setting.sysTheme') }} + + + {{ t('layout.setting.headerTheme') }} diff --git a/packages/grid-layouts/src/components/tab-bar/SuffixItemWrapper.vue b/packages/grid-layouts/src/components/tab-bar/SuffixItemWrapper.vue deleted file mode 100644 index 12671ca9..00000000 --- a/packages/grid-layouts/src/components/tab-bar/SuffixItemWrapper.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/packages/grid-layouts/src/components/tab-bar/TabQuick.vue b/packages/grid-layouts/src/components/tab-bar/TabQuick.vue deleted file mode 100644 index 18872a37..00000000 --- a/packages/grid-layouts/src/components/tab-bar/TabQuick.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/packages/grid-layouts/src/components/tab-bar/FoldButton.vue b/packages/grid-layouts/src/components/tabs-bar/components/FoldButton.vue similarity index 75% rename from packages/grid-layouts/src/components/tab-bar/FoldButton.vue rename to packages/grid-layouts/src/components/tabs-bar/components/FoldButton.vue index 8af927ce..e4202e21 100644 --- a/packages/grid-layouts/src/components/tab-bar/FoldButton.vue +++ b/packages/grid-layouts/src/components/tabs-bar/components/FoldButton.vue @@ -1,10 +1,10 @@ - + diff --git a/packages/grid-layouts/src/components/tabs-bar/components/TabDropdown.vue b/packages/grid-layouts/src/components/tabs-bar/components/TabDropdown.vue new file mode 100644 index 00000000..89b439a9 --- /dev/null +++ b/packages/grid-layouts/src/components/tabs-bar/components/TabDropdown.vue @@ -0,0 +1,138 @@ + + + + diff --git a/packages/grid-layouts/src/components/tabs-bar/components/TabItem.vue b/packages/grid-layouts/src/components/tabs-bar/components/TabItem.vue new file mode 100644 index 00000000..5ce5ddd1 --- /dev/null +++ b/packages/grid-layouts/src/components/tabs-bar/components/TabItem.vue @@ -0,0 +1,31 @@ + + + + {{ title }} + + + diff --git a/packages/grid-layouts/src/components/tabs-bar/components/TabQuick.vue b/packages/grid-layouts/src/components/tabs-bar/components/TabQuick.vue new file mode 100644 index 00000000..fb84e33c --- /dev/null +++ b/packages/grid-layouts/src/components/tabs-bar/components/TabQuick.vue @@ -0,0 +1,135 @@ + + + + + + + + diff --git a/packages/grid-layouts/src/components/tab-bar/TabRedo.vue b/packages/grid-layouts/src/components/tabs-bar/components/TabRedo.vue similarity index 56% rename from packages/grid-layouts/src/components/tab-bar/TabRedo.vue rename to packages/grid-layouts/src/components/tabs-bar/components/TabRedo.vue index 8c4c8b4f..fbd6dd0b 100644 --- a/packages/grid-layouts/src/components/tab-bar/TabRedo.vue +++ b/packages/grid-layouts/src/components/tabs-bar/components/TabRedo.vue @@ -1,10 +1,13 @@ - + diff --git a/packages/grid-layouts/src/components/tabs-bar/index.vue b/packages/grid-layouts/src/components/tabs-bar/index.vue new file mode 100644 index 00000000..6058fc38 --- /dev/null +++ b/packages/grid-layouts/src/components/tabs-bar/index.vue @@ -0,0 +1,97 @@ + + + + + { + close(route) + } + " + /> + + + + diff --git a/packages/grid-layouts/src/components/widgets/HeaderTrigger.vue b/packages/grid-layouts/src/components/widgets/HeaderTrigger.vue index 0d3adef2..e9a04219 100644 --- a/packages/grid-layouts/src/components/widgets/HeaderTrigger.vue +++ b/packages/grid-layouts/src/components/widgets/HeaderTrigger.vue @@ -7,7 +7,6 @@ const { sidebar, toggleCollapse } = useAppConfig() -import TopButtonWrapper from '../comm/TopButtonWrapper.vue' - - - - - - diff --git a/packages/grid-layouts/src/components/widgets/LocalePicker.vue b/packages/grid-layouts/src/components/widgets/LocalePicker.vue new file mode 100644 index 00000000..1da25061 --- /dev/null +++ b/packages/grid-layouts/src/components/widgets/LocalePicker.vue @@ -0,0 +1,64 @@ + + + + + + + {{ + getLocaleText + }} + + + + diff --git a/packages/grid-layouts/src/components/widgets/MenuFixedTrigger.vue b/packages/grid-layouts/src/components/widgets/MenuFixedTrigger.vue new file mode 100644 index 00000000..a3654bb6 --- /dev/null +++ b/packages/grid-layouts/src/components/widgets/MenuFixedTrigger.vue @@ -0,0 +1,14 @@ + + + + + + diff --git a/packages/grid-layouts/src/components/widgets/Setting.vue b/packages/grid-layouts/src/components/widgets/Setting.vue index 6cb4f996..c1304b1a 100644 --- a/packages/grid-layouts/src/components/widgets/Setting.vue +++ b/packages/grid-layouts/src/components/widgets/Setting.vue @@ -18,10 +18,7 @@ const getShowSetting = computed(() => { }) - + diff --git a/packages/grid-layouts/src/components/widgets/SiderCenterTrigger.vue b/packages/grid-layouts/src/components/widgets/SiderCenterTrigger.vue index b75bb586..2833e014 100644 --- a/packages/grid-layouts/src/components/widgets/SiderCenterTrigger.vue +++ b/packages/grid-layouts/src/components/widgets/SiderCenterTrigger.vue @@ -5,14 +5,13 @@ const { sidebar, toggleCollapse } = useAppConfig() diff --git a/packages/grid-layouts/src/components/widgets/UserDropdown.vue b/packages/grid-layouts/src/components/widgets/UserDropdown.vue index 21d435b8..3e0d0212 100644 --- a/packages/grid-layouts/src/components/widgets/UserDropdown.vue +++ b/packages/grid-layouts/src/components/widgets/UserDropdown.vue @@ -1,13 +1,65 @@ - - - - Vben Admin - - + + + diff --git a/packages/grid-layouts/src/components/widgets/UserInfo.vue b/packages/grid-layouts/src/components/widgets/UserInfo.vue new file mode 100644 index 00000000..eb2d8e5b --- /dev/null +++ b/packages/grid-layouts/src/components/widgets/UserInfo.vue @@ -0,0 +1,16 @@ + + + + + + {{ username }} + + + + diff --git a/packages/hooks/src/config/index.ts b/packages/hooks/src/config/index.ts index ddfcd2b2..cb2df051 100644 --- a/packages/hooks/src/config/index.ts +++ b/packages/hooks/src/config/index.ts @@ -1 +1,3 @@ export * from './useAppConfig' +export * from './useSiteGeneral' +export * from './useTabs' diff --git a/packages/hooks/src/config/useAppConfig.ts b/packages/hooks/src/config/useAppConfig.ts index 319f49b7..a8a4250f 100644 --- a/packages/hooks/src/config/useAppConfig.ts +++ b/packages/hooks/src/config/useAppConfig.ts @@ -5,8 +5,8 @@ import { } from '@vben/stores' import { DefineAppConfigOptions } from '@vben/types' import { HandlerSettingEnum, ThemeEnum } from '@vben/constants' -import { _merge, toggleClass } from '@vben/utils' -import { reactive, unref } from 'vue' +import { _merge } from '@vben/utils' +import { computed, reactive, unref } from 'vue' import { useClipboard, _omit } from '@vben/utils' import { useAppTheme } from '@/web' @@ -23,7 +23,7 @@ export const useAppConfig = () => { const appConfigOptions = storeToRefs( useAppConfigStore as StoreGeneric, ) as unknown as DefineAppConfigOptions & DefineAppConfigStoreGetters - const { openSettingDrawer, sidebar, grayMode, colorWeak } = appConfigOptions + const { openSettingDrawer, sidebar, menu, isMixSidebar } = appConfigOptions const setAppConfig = (configs: DeepPartial) => { useAppConfigStore.$patch((state) => { _merge(state, configs) @@ -38,16 +38,12 @@ export const useAppConfig = () => { useAppConfigStore.setSidebar({ collapsed: !unref(sidebar).collapsed }) } - function baseHandler(event: HandlerSettingEnum, value: any) { - setAppConfig(handlerResults(event, value, appConfigOptions)) - } - - function toggleGrayMode(isGrayMode = unref(grayMode)) { - toggleClass(isGrayMode, 'gray-mode', document.body) + function toggleMenuFixed() { + useAppConfigStore.setMenu({ mixSideFixed: !unref(menu).mixSideFixed }) } - function toggleColorWeak(isColorWeak = colorWeak) { - toggleClass(isColorWeak, 'color-weak', document.body) + function baseHandler(event: HandlerSettingEnum, value: any) { + setAppConfig(handlerResults(event, value, appConfigOptions)) } async function copyConfigs() { @@ -71,6 +67,12 @@ export const useAppConfig = () => { function resetAllConfig() { useAppConfigStore.$reset() } + const getCollapsedShowTitle = computed(() => { + if (unref(isMixSidebar)) { + return !unref(sidebar).collapsed + } + return unref(menu).collapsedShowTitle && unref(sidebar).collapsed + }) return { ...appConfigOptions, setAppConfig, @@ -80,8 +82,8 @@ export const useAppConfig = () => { clearAndRedo, resetAllConfig, toggleCollapse, - toggleGrayMode, - toggleColorWeak, + toggleMenuFixed, + getCollapsedShowTitle, } } @@ -139,7 +141,7 @@ function handlerResults( return { sidebar: { show: value, visible: value } } case HandlerSettingEnum.MENU_COLLAPSED_SHOW_TITLE: - return { menu: { collapsedShowLabel: value } } + return { menu: { collapsedShowTitle: value } } case HandlerSettingEnum.MENU_THEME: // updateSidebarBgColor(value); diff --git a/packages/hooks/src/config/useSiteGeneral.ts b/packages/hooks/src/config/useSiteGeneral.ts new file mode 100644 index 00000000..4791f345 --- /dev/null +++ b/packages/hooks/src/config/useSiteGeneral.ts @@ -0,0 +1,26 @@ +import { + StoreGeneric, + storeToRefs, + useSiteGeneral as siteGeneralStore, +} from '@vben/stores' + +import { _merge } from '@vben/utils' +import { DefineSiteGeneralOptions } from '@vben/types' + +export const useSiteGeneral = () => { + const useSiteGeneralStore = siteGeneralStore() + const siteGeneral = storeToRefs( + useSiteGeneralStore as StoreGeneric, + ) as unknown as DefineSiteGeneralOptions + const initSiteGeneralConfig = ( + configs: DeepPartial, + ) => { + useSiteGeneralStore.$patch((state) => { + _merge(state, configs) + }) + } + return { + ...siteGeneral, + initSiteGeneralConfig, + } +} diff --git a/packages/hooks/src/config/useTabs.ts b/packages/hooks/src/config/useTabs.ts new file mode 100644 index 00000000..f47327c3 --- /dev/null +++ b/packages/hooks/src/config/useTabs.ts @@ -0,0 +1,103 @@ +import type { RouteLocationNormalized, Router } from 'vue-router' + +import { useRouter } from 'vue-router' +import { unref } from 'vue' +import { useMultipleTab, useAppConfig } from '@vben/stores' +import { TabActionEnum } from '@vben/constants' +import { useGo, useRedo } from '../usePage' + +export function useTabs(_router?: Router) { + const appStore = useAppConfig() + + function canIUseTabs(): boolean { + const { show } = appStore.tabTar + if (!show) { + throw new Error( + 'The multi-tab page is currently not open, please open it in the settings!', + ) + } + return !!show + } + + const tabStore = useMultipleTab() + const router = _router || useRouter() + + const { currentRoute } = router + + function getCurrentTab() { + const route = unref(currentRoute) + + return tabStore.getTabList.find((item) => item.fullPath === route.fullPath)! + } + + async function updateTabTitle(title: string, tab?: RouteLocationNormalized) { + const canIUse = canIUseTabs + if (!canIUse) { + return + } + const targetTab = tab || getCurrentTab() + await tabStore.setTabTitle(title, targetTab) + } + + async function updateTabPath(path: string, tab?: RouteLocationNormalized) { + const canIUse = canIUseTabs + if (!canIUse) { + return + } + const targetTab = tab || getCurrentTab() + await tabStore.updateTabPath(path, targetTab) + } + + async function handleTabAction( + action: TabActionEnum, + tab?: RouteLocationNormalized, + ) { + const canIUse = canIUseTabs + if (!canIUse) { + return + } + const currentTab = getCurrentTab() + switch (action) { + case TabActionEnum.REFRESH_PAGE: + await tabStore.refreshPage(router) + await useRedo(router) + break + + case TabActionEnum.CLOSE_ALL: + await tabStore.closeAllTab(router) + break + + case TabActionEnum.CLOSE_LEFT: + await tabStore.closeLeftTabs(currentTab, router) + break + + case TabActionEnum.CLOSE_RIGHT: + await tabStore.closeRightTabs(currentTab, router) + break + + case TabActionEnum.CLOSE_OTHER: + await tabStore.closeOtherTabs(currentTab, router) + break + + case TabActionEnum.CLOSE_CURRENT: + case TabActionEnum.CLOSE: + await tabStore.closeTab(tab || currentTab, router) + break + } + } + + return { + refreshPage: () => handleTabAction(TabActionEnum.REFRESH_PAGE), + closeAll: () => handleTabAction(TabActionEnum.CLOSE_ALL), + closeLeft: () => handleTabAction(TabActionEnum.CLOSE_LEFT), + closeRight: () => handleTabAction(TabActionEnum.CLOSE_RIGHT), + closeOther: () => handleTabAction(TabActionEnum.CLOSE_OTHER), + closeCurrent: () => handleTabAction(TabActionEnum.CLOSE_CURRENT), + close: (tab?: RouteLocationNormalized) => + handleTabAction(TabActionEnum.CLOSE, tab), + setTitle: (title: string, tab?: RouteLocationNormalized) => + updateTabTitle(title, tab), + updatePath: (fullPath: string, tab?: RouteLocationNormalized) => + updateTabPath(fullPath, tab), + } +} diff --git a/packages/hooks/src/web/useLayout.ts b/packages/hooks/src/web/useLayout.ts index ee83e92e..ec86a741 100644 --- a/packages/hooks/src/web/useLayout.ts +++ b/packages/hooks/src/web/useLayout.ts @@ -7,8 +7,9 @@ import { lighten, pickTextColorBasedOnBgColor, darken, - addClass, + toggleClass, } from '@vben/utils' +import { ThemeEnum } from '@vben/constants' const HEADER_HEIGHT = '--header-height' const HEADER_BG_COLOR_VAR = '--header-background-color' @@ -19,6 +20,8 @@ const ASIDE_WIDTH = '--aside-width' const ASIDE_DARK_BG_COLOR = '--aside-background-color' const ASIDE_TEXT_COLOR_VAR = '--aside-text-color' +const TRIGGER_BG_COLOR_VAR = '--trigger-background-color' + const TAB_BAR_HEIGHT = '--tab-bar-height' const FOOTER_HEIGHT = '--footer-height' @@ -26,16 +29,9 @@ const FOOTER_HEIGHT = '--footer-height' const LIGHT_TEXT_COLOR = 'rgba(0,0,0,.85)' const DARK_TEXT_COLOR = '#fff' -export function createThemeColorListen(el: MaybeElementRef | null) { - const { - sidebar, - header, - grayMode, - colorWeak, - theme, - toggleGrayMode, - toggleColorWeak, - } = useAppConfig() +export function createThemeColorListen(el?: MaybeElementRef | null) { + const { sidebar, header, grayMode, colorWeak, theme, setAppConfig } = + useAppConfig() const { sidebarRef } = useLayoutSidebar() const { headerRef } = useLayoutHeader() @@ -75,6 +71,10 @@ export function createThemeColorListen(el: MaybeElementRef | null) { initialValue: LIGHT_TEXT_COLOR, }, ) + const triggerBackgroundColor = useCssVar( + TRIGGER_BG_COLOR_VAR, + sidebarRef as MaybeElementRef, + ) watchEffect(() => { headerBgColor.value = unref(header).bgColor @@ -83,11 +83,14 @@ export function createThemeColorListen(el: MaybeElementRef | null) { LIGHT_TEXT_COLOR, DARK_TEXT_COLOR, ) - headerActionHoverBgColor.value = ['#fff', '#ffffff'].includes( - unref(header).bgColor.toLowerCase(), - ) - ? darken(unref(header).bgColor, 6) - : lighten(unref(header).bgColor, 6) + + if (['#fff', '#ffffff'].includes(unref(header).bgColor.toLowerCase())) { + headerActionHoverBgColor.value = darken(unref(header).bgColor, 6) + setAppConfig({ header: { theme: ThemeEnum.LIGHT } }) + } else { + headerActionHoverBgColor.value = lighten(unref(header).bgColor, 6) + setAppConfig({ header: { theme: ThemeEnum.DARK } }) + } sidebarBgColor.value = unref(sidebar).bgColor asideTextColor.value = pickTextColorBasedOnBgColor( @@ -95,15 +98,35 @@ export function createThemeColorListen(el: MaybeElementRef | null) { LIGHT_TEXT_COLOR, DARK_TEXT_COLOR, ) + + if (['#fff', '#ffffff'].includes(unref(sidebar).bgColor.toLowerCase())) { + setAppConfig({ sidebar: { theme: ThemeEnum.LIGHT } }) + triggerBackgroundColor.value = darken(unref(sidebar).bgColor, 6) + } else { + triggerBackgroundColor.value = lighten(unref(sidebar).bgColor, 6) + setAppConfig({ sidebar: { theme: ThemeEnum.DARK } }) + } toggleGrayMode(unref(grayMode)) toggleColorWeak(unref(colorWeak)) - addClass(document.documentElement, unref(theme)) + toggleClass( + ThemeEnum.DARK === unref(theme), + ThemeEnum.DARK, + document.documentElement, + ) }) } export function createGridLayoutListen(el: MaybeElementRef | null) { - const { isTopMenu, isMixSidebar, sidebar, header, footer, tabTar } = - useAppConfig() + const { + isTopMenu, + sidebar, + header, + footer, + tabTar, + getCollapsedShowTitle, + menu, + isMixSidebar, + } = useAppConfig() const asideWidth = useCssVar(ASIDE_WIDTH, el, { initialValue: `${unref(sidebar).width}px`, }) @@ -120,8 +143,16 @@ export function createGridLayoutListen(el: MaybeElementRef | null) { watchEffect(() => { const getAsideWidth = () => { if (unref(isTopMenu) || !unref(sidebar).visible) return 0 - if (unref(sidebar).collapsed) return unref(sidebar).collapsedWidth - if (unref(isMixSidebar)) return unref(sidebar).mixSidebarWidth + if (unref(getCollapsedShowTitle)) { + return unref(menu).mixSideFixed && unref(isMixSidebar) + ? unref(sidebar).mixSidebarWidth + unref(menu).subMenuWidth + : unref(sidebar).mixSidebarWidth + } + if (unref(sidebar).collapsed) { + return unref(menu).mixSideFixed && unref(isMixSidebar) + ? unref(sidebar).collapsedWidth + unref(menu).subMenuWidth + : unref(sidebar).collapsedWidth + } return unref(sidebar).width } @@ -145,3 +176,11 @@ export function createGridLayoutListen(el: MaybeElementRef | null) { footerHeight.value = `${getFooterHeight()}px` }) } + +function toggleGrayMode(isGrayMode: boolean) { + toggleClass(isGrayMode, 'gray-mode', document.body) +} + +function toggleColorWeak(isColorWeak: boolean) { + toggleClass(isColorWeak, 'color-weak', document.body) +} diff --git a/packages/layouts/src/components/search/useMenuSearch.ts b/packages/layouts/src/components/search/useMenuSearch.ts index 6a272dc6..6e2d92cf 100644 --- a/packages/layouts/src/components/search/useMenuSearch.ts +++ b/packages/layouts/src/components/search/useMenuSearch.ts @@ -7,9 +7,8 @@ import { onKeyStroke, } from '@vben/utils' import { useI18n } from '@vben/locale' -import { useGo } from '@vben/hooks' +import { useGo, useScrollTo } from '@vben/hooks' import { context } from '../../../bridge' -import { useScrollTo } from '@/hooks/event/use-scroll-to' export interface SearchResult { name: string diff --git a/packages/locale/index.ts b/packages/locale/index.ts index 41ac8be4..4a65daa4 100644 --- a/packages/locale/index.ts +++ b/packages/locale/index.ts @@ -1,3 +1,4 @@ export { setupI18n } from './src/setup-i18n' export { useI18n, t } from './src/use-i18n' export { useLocale } from './src/use-locale' +export * from './src/config' diff --git a/packages/router/index.ts b/packages/router/index.ts index 6f39cd49..f906c061 100644 --- a/packages/router/index.ts +++ b/packages/router/index.ts @@ -1 +1,3 @@ export * from './src' + +export * from 'vue-router' diff --git a/packages/router/src/helper/menu.ts b/packages/router/src/helper/menu.ts index 485ca352..193a2aed 100644 --- a/packages/router/src/helper/menu.ts +++ b/packages/router/src/helper/menu.ts @@ -36,7 +36,7 @@ export function transformMenuModule(menuModule: MenuModule): Menu { const menuList = [menu] - joinParentPath(menuList) + joinParentPath(menuList as RouteRecordItem[]) return menuList[0] } diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index 511c320b..96e81e6f 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -8,6 +8,7 @@ export * from './routes' export * from './helper' export * from './guard' export * from './menus' +export * from './mitt/routeChange' export interface Stores { userStore?: any diff --git a/apps/grid-admin/src/logics/mitt/routeChange.ts b/packages/router/src/mitt/routeChange.ts similarity index 54% rename from apps/grid-admin/src/logics/mitt/routeChange.ts rename to packages/router/src/mitt/routeChange.ts index 0c4e3571..d585b63c 100644 --- a/apps/grid-admin/src/logics/mitt/routeChange.ts +++ b/packages/router/src/mitt/routeChange.ts @@ -2,29 +2,29 @@ * Used to monitor routing changes to change the status of menus and tabs. There is no need to monitor the route, because the route status change is affected by the page rendering time, which will be slow */ -import type { RouteLocationNormalized } from 'vue-router'; -import { getRawRoute, mitt } from "@vben/utils"; +import type { RouteLocationNormalized } from 'vue-router' +import { getRawRoute, mitt } from '@vben/utils' -const emitter = mitt(); +const emitter = mitt() -const key = Symbol(); +const key = Symbol() -let lastChangeTab: RouteLocationNormalized; +let lastChangeTab: RouteLocationNormalized export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { - const r = getRawRoute(lastChangeRoute); - emitter.emit(key, r); - lastChangeTab = r; + const r = getRawRoute(lastChangeRoute) + emitter.emit(key, r) + lastChangeTab = r } export function listenerRouteChange( callback: (route: RouteLocationNormalized) => void, immediate = true, ) { - emitter.on(key, callback); - immediate && lastChangeTab && callback(lastChangeTab); + emitter.on(key, callback) + immediate && lastChangeTab && callback(lastChangeTab) } export function removeTabChangeListener() { - emitter.clear(); + emitter.clear() } diff --git a/packages/router/src/routes/modules/dashboard.ts b/packages/router/src/routes/modules/dashboard.ts index c58bacef..451920cd 100644 --- a/packages/router/src/routes/modules/dashboard.ts +++ b/packages/router/src/routes/modules/dashboard.ts @@ -9,6 +9,7 @@ const dashboard: RouteRecordItem = { orderNo: 1, icon: 'mdi:monitor-dashboard', title: 'routes.dashboard.dashboard', + root: true, }, children: [ { @@ -18,6 +19,7 @@ const dashboard: RouteRecordItem = { meta: { icon: 'mdi:monitor-dashboard', title: 'routes.dashboard.analysis', + affix: true, }, }, { diff --git a/packages/router/src/routes/modules/demo/demo.ts b/packages/router/src/routes/modules/demo/demo.ts index f1ad1827..35b20a5d 100644 --- a/packages/router/src/routes/modules/demo/demo.ts +++ b/packages/router/src/routes/modules/demo/demo.ts @@ -4,11 +4,12 @@ const dashboard: RouteRecordItem = { path: '/demo', name: 'Demo', component: LAYOUT, - redirect: '/dashboard/form', + redirect: '/demo/form', meta: { orderNo: 2, icon: 'line-md:clipboard-list-twotone', title: 'routes.demo.demo', + root: true, }, children: [ { diff --git a/packages/router/src/routes/modules/demo/editor.ts b/packages/router/src/routes/modules/demo/editor.ts index 28892fee..2d759fae 100644 --- a/packages/router/src/routes/modules/demo/editor.ts +++ b/packages/router/src/routes/modules/demo/editor.ts @@ -4,10 +4,12 @@ const Editor: RouteRecordItem = { path: '/editor', name: 'Editor', component: LAYOUT, + redirect: '/editor/monaco-editor', meta: { orderNo: 3, title: '编辑器', icon: 'openmoji:code-editor', + root: true, }, children: [ { diff --git a/packages/router/src/routes/modules/demo/page.ts b/packages/router/src/routes/modules/demo/page.ts index 2c7099b2..c40ff2f8 100644 --- a/packages/router/src/routes/modules/demo/page.ts +++ b/packages/router/src/routes/modules/demo/page.ts @@ -6,7 +6,8 @@ const Page: RouteRecordItem = { orderNo: 4, title: '非框架页面', icon: 'tabler:frame-off', - hideTab: true + hideTab: true, + root: true, }, } diff --git a/packages/stores/package.json b/packages/stores/package.json index 6098203d..a7b78f96 100644 --- a/packages/stores/package.json +++ b/packages/stores/package.json @@ -9,10 +9,12 @@ }, "dependencies": { "@vben/constants": "workspace:*", + "@vben/locale": "workspace:*", "@vben/utils": "workspace:*", "pinia": "^2.0.30", "pinia-plugin-persistedstate": "^3.0.2", - "vue": "^3.2.47" + "vue": "^3.2.47", + "vue-router": "^4.1.6" }, "devDependencies": { "@vben/types": "workspace:*" diff --git a/packages/stores/src/modules/appConfig.ts b/packages/stores/src/modules/appConfig.ts index 0eef25c0..60c88289 100644 --- a/packages/stores/src/modules/appConfig.ts +++ b/packages/stores/src/modules/appConfig.ts @@ -50,6 +50,7 @@ export const useAppConfig = defineStore({ canEmbedIFramePage: true, closeMixSidebarOnChange: false, sidebar: { + theme: ThemeEnum.LIGHT, show: true, visible: true, bgColor: SIDE_BAR_BG_COLOR_LIST[0], @@ -63,15 +64,17 @@ export const useAppConfig = defineStore({ menu: { canDrag: false, split: false, - mode: MenuModeEnum.INLINE, + mode: MenuModeEnum.VERTICAL, accordion: false, - collapsedShowLabel: false, + collapsedShowTitle: false, mixSideTrigger: MixSidebarTriggerEnum.CLICK, mixSideFixed: false, topMenuAlign: 'start', dropdownPlacement: 'top-start', + subMenuWidth: 0, }, header: { + theme: ThemeEnum.DARK, show: true, visible: true, bgColor: HEADER_PRESET_BG_COLOR_LIST[0], @@ -126,6 +129,7 @@ export const useAppConfig = defineStore({ state.menu.mode === MenuModeEnum.INLINE && state.navBarMode === NavBarModeEnum.MIX, isHorizontal: (state) => state.menu.mode === MenuModeEnum.HORIZONTAL, + getTabTarCache: (state) => state.tabTar.cache, }, actions: { setTheme(value: ThemeEnum) { diff --git a/packages/stores/src/modules/index.ts b/packages/stores/src/modules/index.ts index fc809df8..1221b0e0 100644 --- a/packages/stores/src/modules/index.ts +++ b/packages/stores/src/modules/index.ts @@ -1,2 +1,4 @@ export * from './layoutComposables' export * from './appConfig' +export * from './siteGeneral' +export * from './multipleTab' diff --git a/apps/grid-admin/src/store/multipleTab.ts b/packages/stores/src/modules/multipleTab.ts similarity index 89% rename from apps/grid-admin/src/store/multipleTab.ts rename to packages/stores/src/modules/multipleTab.ts index fd896678..3aadc774 100644 --- a/apps/grid-admin/src/store/multipleTab.ts +++ b/packages/stores/src/modules/multipleTab.ts @@ -1,25 +1,14 @@ +import { defineStore } from 'pinia' +import { toRaw, unref } from 'vue' +import { PAGE_NOT_FOUND_NAME, PageEnum, REDIRECT_NAME } from '@vben/constants' import type { RouteLocationNormalized, RouteLocationRaw, Router, } from 'vue-router' -import { toRaw, unref } from 'vue' -import { defineStore } from 'pinia' -import { useGo, useRedo } from '@vben/hooks' -// import { Persistent } from '/@/utils/cache/persistent'; - -import { PageEnum } from '@vben/constants' -import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes/basic' import { getRawRoute, RemovableRef } from '@vben/utils' -import { useUserStore } from '@/store/user' -// import { useRouter, useRoute } from 'vue-router' -// import { router } from '@/router' -// import {debug} from "util"; -// -// import projectSetting from '/@/settings/projectSetting'; -// import { useUserStore } from '/@/store/user'; -// useUserStore +import { useAppConfig } from './appConfig' export interface MultipleTabState { cacheTabList: Set tabList: RouteLocationNormalized[] | RemovableRef @@ -27,8 +16,8 @@ export interface MultipleTabState { } function handleGotoPage(router: Router) { - const go = useGo(router) - go(unref(router.currentRoute).path, true) + // const go = useGo(router) + // go(unref(router.currentRoute).path, true) } const getToTarget = (tabItem: RouteLocationNormalized) => { @@ -39,15 +28,13 @@ const getToTarget = (tabItem: RouteLocationNormalized) => { query: query || {}, } } -// const TabsStorage = useLocalStorage('MULTIPLE_TABS_KEY', []) -// const cacheTab = true -// const cacheTab = projectSetting.multiTabsSetting.cache -export const useMultipleTabStore = defineStore({ - id: 'app-multiple-tab', - persist: { - paths: ['tabList'], - }, +// const appConfig = useAppConfig() + +// const cacheTab = appConfig.getTabTarCache + +export const useMultipleTab = defineStore({ + id: 'APP_MULTIPLE_TABS', state: (): MultipleTabState => ({ // Tabs that need to be cached cacheTabList: new Set(), @@ -99,8 +86,6 @@ export const useMultipleTabStore = defineStore({ if (findTab) { this.cacheTabList.delete(findTab) } - const redo = useRedo(router) - await redo() }, clearCacheTabs(): void { this.cacheTabList = new Set() @@ -137,9 +122,7 @@ export const useMultipleTabStore = defineStore({ ) || meta?.hideTab || !name || - [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes( - name as string, - ) + [REDIRECT_NAME, PAGE_NOT_FOUND_NAME].includes(name as string) ) { return } @@ -193,6 +176,7 @@ export const useMultipleTabStore = defineStore({ async closeTab(tab: RouteLocationNormalized, router: Router) { const close = (route: RouteLocationNormalized) => { + // @ts-ignore const { fullPath, meta: { affix } = {} } = route if (affix) { return @@ -221,8 +205,9 @@ export const useMultipleTabStore = defineStore({ if (index === 0) { // There is only one tab, then jump to the homepage, otherwise jump to the right tab if (this.tabList.length === 1) { - const userStore = useUserStore() - toTarget = userStore.getUserInfo?.homePath || PageEnum.BASE_HOME + // const userStore = useUserStore() + // toTarget = userStore.getUserInfo?.homePath || PageEnum.BASE_HOME + toTarget = PageEnum.BASE_HOME } else { // Jump to the right tab const page = this.tabList[index + 1] @@ -379,9 +364,7 @@ export const useMultipleTabStore = defineStore({ } }, }, + persist: { + paths: ['tabList'], + }, }) - -// Need to be used outside the setup -export function useMultipleTabWithOut() { - return useMultipleTabStore() -} diff --git a/packages/stores/src/modules/siteGeneral.ts b/packages/stores/src/modules/siteGeneral.ts new file mode 100644 index 00000000..e224e830 --- /dev/null +++ b/packages/stores/src/modules/siteGeneral.ts @@ -0,0 +1,48 @@ +import { defineStore } from 'pinia' +import { FooterLinkOptions, DefineSiteGeneralOptions } from '@vben/types' +import { useI18n } from '@vben/locale' +// @ts-ignore +import defaultLogo from '@/assets/images/logo.png' +// @ts-ignore +import defaultAvatar from '@/assets/images/header.jpg' +import { getGlobalConfig } from '@vben/utils' + +const { t } = useI18n() + +const { title } = getGlobalConfig(import.meta.env) + +// github repo url +export const GITHUB_URL = 'https://github.com/vbenjs/vben3' + +// vue-vben-admin-next-doc +export const DOC_URL = 'https://vbenjs.github.io/vben3-doc/' + +// site url +export const SITE_URL = 'https://vben.mufei88.com/' + +const links: FooterLinkOptions[] = [ + { + label: t('layout.footer.onlinePreview'), + url: SITE_URL, + }, + { + icon: 'uim:github', + url: GITHUB_URL, + }, + { + label: t('layout.footer.onlineDocument'), + url: DOC_URL, + }, +] + +export const useSiteGeneral = defineStore({ + id: 'APP_SITE_GENERAL_OPTIONS', + state: (): DefineSiteGeneralOptions => ({ + logo: defaultLogo, + title, + copyright: '2023 Vben Admin', + links: links, + avatar: defaultAvatar, + username: 'Vben Admin', + }), +}) diff --git a/packages/styles/src/variables.css b/packages/styles/src/variables.css index 5c0887c1..a70ffa29 100644 --- a/packages/styles/src/variables.css +++ b/packages/styles/src/variables.css @@ -14,6 +14,7 @@ /* layout start */ --layout-color: #fff; + --layout-container-background-color: #fff; --layout-border-color: rgb(239, 239, 245); /* header */ @@ -35,13 +36,13 @@ --aside-submenu-background-color: #0c2135; --aside-text-color: #fff; - --trigger-color: rgb(72, 72, 78); - --trigger-border: 1px solid rgb(239, 239, 245); + --trigger-background-color: rgb(72, 72, 78); + /*--trigger-border: 1px solid rgb(239, 239, 245);*/ --trigger-border-color: rgb(239, 239, 245); /*--trigger-border-color: rgb(239, 239, 245);*/ - --trigger-icon-color: #f3f1f1; + /*--trigger-icon-color: #f3f1f1;*/ /*--trigger-icon-color: rgb(51, 54, 57);*/ - --trigger-hover-icon-color: #fff; + /*--trigger-hover-icon-color: #fff;*/ /* main */ --main-height: calc(100% - var(--footer-height)); @@ -55,8 +56,9 @@ } -@media (prefers-color-scheme: dark) { - :root { - visibility: visible; - } +:root[class=dark] { + --layout-border-color: rgba(255, 255, 255, 0.09); + --layout-container-background-color: rgb(16, 16, 20); + + --component-background-color: rgb(24, 24, 28); } diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index df796429..1d0c97df 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -106,6 +106,7 @@ export interface DefineAppConfigOptions { } export interface SidebarConfigOptions { + theme: ThemeEnum show: boolean visible: boolean fixed: boolean @@ -121,10 +122,12 @@ export interface MenuConfigOptions { split: boolean mode: MenuModeEnum accordion: boolean - collapsedShowLabel: boolean + collapsedShowTitle: boolean mixSideTrigger: MixSidebarTriggerEnum mixSideFixed: boolean topMenuAlign: 'start' | 'center' | 'end' + + subMenuWidth: number dropdownPlacement: | 'top-start' | 'top' @@ -141,6 +144,7 @@ export interface MenuConfigOptions { } export interface HeaderConfigOptions { + theme: ThemeEnum show: boolean visible: boolean bgColor: string @@ -196,3 +200,24 @@ export interface TransitionConfigOptions { // Whether to open the top progress bar openNProgress: boolean } + +export interface FooterLinkOptions { + label?: string + icon?: string + target?: '_self' | '_blank' + url: string +} +export interface DefineSiteGeneralOptions { + // Logo url + logo: string + // Site title + title: string + // Copyright Information + copyright: string + // Footer link + links: FooterLinkOptions[] + // Avatar url + avatar: string + // username + username: string +} diff --git a/packages/utils/src/theme.ts b/packages/utils/src/theme.ts index a1f383a3..3bf352c4 100644 --- a/packages/utils/src/theme.ts +++ b/packages/utils/src/theme.ts @@ -1,10 +1,18 @@ -export function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) { - const targetEl = target || document.body; - let { className } = targetEl; - className = className.replace(clsName, ''); - targetEl.className = flag ? `${className} ${clsName} ` : className; +export function toggleClass( + flag: boolean, + clsName: string, + target?: HTMLElement, +) { + const targetEl = target || document.body + let { className } = targetEl + className = className.replace(clsName, '') + targetEl.className = (flag ? `${className} ${clsName} ` : className).trim() } -export function setCssVar(prop: string, val: any, dom = document.documentElement) { - dom.style.setProperty(prop, val); +export function setCssVar( + prop: string, + val: any, + dom = document.documentElement, +) { + dom.style.setProperty(prop, val) } diff --git a/packages/vbenComponents/src/config/src/Config.vue b/packages/vbenComponents/src/config/src/Config.vue index fc004ad0..aee0f069 100644 --- a/packages/vbenComponents/src/config/src/Config.vue +++ b/packages/vbenComponents/src/config/src/Config.vue @@ -2,11 +2,29 @@ import { maps } from '#/index' import { computed, unref } from 'vue' import { useAppTheme } from '@vben/hooks' +import { ThemeEnum } from '@vben/constants' const Config = maps.get('Config') const darkTheme = maps.get('DarkTheme') +const props = defineProps({ + // Customize the configuration theme mode + themeMode: { + type: String, + default: 'dark' + }, + // Whether to inherit the theme + inherit: { + type: Boolean, + default: true + } +}) const { isDark } = useAppTheme() -const appTheme = computed(() => (unref(isDark) ? darkTheme : null)) +const appTheme = computed(() => { + if (!props.inherit){ + return props.themeMode === ThemeEnum.DARK ? darkTheme : null + } + return unref(isDark) ? darkTheme : null +})
- {{ userInfo.realName }} -