diff --git a/index.html b/index.html index 65997a9..329d3c9 100644 --- a/index.html +++ b/index.html @@ -18,6 +18,7 @@ padding: 0; border: 0; font-size: var(--el-font-size-medium); + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } html, diff --git a/src/assets/stylus/index.styl b/src/assets/stylus/index.styl index b15a207..a7bb178 100644 --- a/src/assets/stylus/index.styl +++ b/src/assets/stylus/index.styl @@ -1,7 +1,7 @@ // 优化 Element Plus 组件库默认样式 :root { - --custom-radius: 5px; + --custom-radius: 9px; // 系统主色 --main-color: #1C6EFF; --el-color-white: white !important; @@ -11,6 +11,11 @@ --el-button-hover-border-color: #458FFF !important; --el-color-primary-light-3: #458FFF !important; --el-color-danger: #CF171D !important; + --el-menu-text-color: #29343D !important; + --el-menu-hover-text-color: #29343D !important; + --el-menu-bg-color: #FFFFFF !important; + --el-menu-hover-bg-color: rgb(204, 204, 204) !important; + --el-menu-level: 0; // 输入框边框颜色 // --el-border-color: #E4E4E7 !important; // DCDFE6 // 按钮粗度 diff --git a/src/common/app/app-page-store.ts b/src/common/app/app-page-store.ts index a0a97b4..dfd9768 100644 --- a/src/common/app/app-page-store.ts +++ b/src/common/app/app-page-store.ts @@ -1,5 +1,6 @@ import { defineStore } from 'pinia' import Evt from '@/common/utils/evt.ts' +import Nav from '@/common/router/nav.ts' const pageContextCache = new Map() @@ -12,6 +13,7 @@ initCache() export const useAppPageStore = defineStore('AppPage', () => { const keepAliveInclude = ref([]) + const pages = ref([]) const currentPage = ref('') @@ -27,13 +29,68 @@ export const useAppPageStore = defineStore('AppPage', () => { if (!keepAliveInclude.value.includes(ctx_.insId)) { keepAliveInclude.value.push(ctx_.insId) } + if (!pages.value.find(it => it.insId === ctx_.insId)) { + pages.value.push(ctx_) + } } - function close(insId: string) { + function reopen(insId: string) { + if (currentPage.value === insId) { + return + } + const page = pageContextCache.get(insId) + if (page) { + currentPage.value = insId + Nav.open(page.routeName) + } + } + + function closePage(insId: string) { pageContextCache.delete(insId) if (keepAliveInclude.value.includes(insId)) { keepAliveInclude.value = keepAliveInclude.value.splice(keepAliveInclude.value.indexOf(insId), 1) } + const index = pages.value.findIndex(it => it.insId === insId) + if (index !== -1) { + const oldLen = pages.value.length + pages.value = pages.value.filter(it => it.insId !== insId) + + if (currentPage.value !== insId) { + return + } + if (index === 0) { + if (pages.value.length > 0) { + reopen(pages.value[0]?.insId) + } else { + Nav.open('home') + } + } else if (index === oldLen - 1) { + if (pages.value.length > 0) { + reopen(pages.value[pages.value.length - 1]?.insId) + } else { + Nav.open('home') + } + } else { + if (pages.value.length > 0) { + reopen(pages.value[index]?.insId) + } else { + Nav.open('home') + } + } + } + } + + function closeCurrent() { + closePage(currentPage.value) + } + + function closeOther() { + pages.value = pages.value.filter(it => it.insId === currentPage.value) + } + + function closeAll() { + pages.value = [] + Nav.open('home') } function $reset() { @@ -46,8 +103,14 @@ export const useAppPageStore = defineStore('AppPage', () => { return { ctx, + reopen, open, - close, + closePage, + closeCurrent, + closeOther, + closeAll, + pages, + currentPage, keepAliveInclude, $reset, } diff --git a/src/common/app/app.d.ts b/src/common/app/app.d.ts index b5c1b76..7f8a826 100644 --- a/src/common/app/app.d.ts +++ b/src/common/app/app.d.ts @@ -11,6 +11,8 @@ declare global { params: Record routeName: string menuId: string + icon: string + breadcrumb: string[] } // 菜单 diff --git a/src/common/app/index.ts b/src/common/app/index.ts index bbbf88b..754be9c 100644 --- a/src/common/app/index.ts +++ b/src/common/app/index.ts @@ -4,13 +4,32 @@ import { useAppSettingStore } from '@/common/app/app-setting-store.ts' import { useAppUserStore } from '@/common/app/app-user-store.ts' import Utils from '@/common/utils' import type { R } from '@/common/utils/http-util.ts' +import { MenuCategory } from '@/common/app/constants.ts' +const home = { + 'id': '-1', + 'sn': 'menus', + 'pid': '0', + 'title': '首页', + 'icon': 'menus', + 'tier': 1, + 'breadcrumb': [ + '首页', + ], + 'menuCategory': MenuCategory.Page, + 'freeze': null, + 'sort': 0, + 'routeName': 'home', + 'path': '/home', +} export const reloadUserInfo = () => { const appSettingStore = useAppSettingStore() const appUserStore = useAppUserStore() return LoginApi.my() .then(({data}) => { const menuTree = Utils.clone(Colls.toTree(data.menus)) + data.menus.unshift(home) + menuTree.unshift(home) appSettingStore.$patch({ menus: data.menus, menuTree, theme: data.setting?.theme ?? 'light', @@ -30,30 +49,30 @@ export const reloadUserInfo = () => { }) } -export const loadUserInfo = () => { - const appSettingStore = useAppSettingStore() - const appUserStore = useAppUserStore() - return LoginApi.my() - .then(({data}) => { - const menuTree = Utils.clone(Colls.toTree(data.menus)) - appSettingStore.$patch({ - menus: data.menus, menuTree, - theme: data.setting?.theme ?? 'light', - collectedMenus: data.setting?.collectedMenus ?? [], - logo: data.setting?.logo, - language: data.setting?.language ?? 'zh', - }) - appUserStore.$patch({ - userId: data.id, - nickname: data.nickname, - avatar: data.avatar, - tenantId: data.tenantId, - tenantName: data.tenantName, - bizObj: data.bizObj, - roles: data.roles, - }) - }) -} +/* export const loadUserInfo = () => { + const appSettingStore = useAppSettingStore() + const appUserStore = useAppUserStore() + return LoginApi.my() + .then(({data}) => { + const menuTree = Utils.clone(Colls.toTree(data.menus)) + appSettingStore.$patch({ + menus: data.menus, menuTree, + theme: data.setting?.theme ?? 'light', + collectedMenus: data.setting?.collectedMenus ?? [], + logo: data.setting?.logo, + language: data.setting?.language ?? 'zh', + }) + appUserStore.$patch({ + userId: data.id, + nickname: data.nickname, + avatar: data.avatar, + tenantId: data.tenantId, + tenantName: data.tenantName, + bizObj: data.bizObj, + roles: data.roles, + }) + }) + } */ export function hasPermission(resSn?: string) { const appSettingStore = useAppSettingStore() diff --git a/src/common/router/index.ts b/src/common/router/index.ts index 44b38a0..bdb0a09 100644 --- a/src/common/router/index.ts +++ b/src/common/router/index.ts @@ -9,11 +9,13 @@ import { useAppUserStore } from '@/common/app/app-user-store.ts' import { MenuCategory } from '@/common/app/constants.ts' import { appBaseUrl } from '@/common' import strings from '@/common/utils/strings.ts' +import Strings from '@/common/utils/strings.ts' import { getRoute, getRoutes, } from '@/common/router/route-config.ts' import { SpecialPage } from '@/common/router/constants.ts' +import Nav from '@/common/router/nav.ts' function addRoutes(routNames: string[]) { if (Colls.isEmpty(routNames)) return @@ -74,10 +76,17 @@ router.beforeEach((to, from) => { name: SpecialPage.Home, } } else { - return { - replace: true, - path: to.fullPath, + let routeName = router.getRoutes().find((it) => it.path === to.path)?.name as string + console.log('reloadRouter11', routeName, Strings.isBlank(routeName)) + if (Strings.isBlank(routeName)) { + routeName = SpecialPage.Home + ElMessage.error('页面不存在222') } + console.log('reloadRouter', to, router.getRoutes(), routeName) + setTimeout(() => { + Nav.open(routeName) + }) + return false } } return true @@ -113,7 +122,7 @@ export function reloadRouter() { } Evt.on('login', (_) => { - router.replace('/') + Nav.open(SpecialPage.Home) }) Evt.on('logout', (_) => { diff --git a/src/common/router/nav.ts b/src/common/router/nav.ts index 295cd51..a0cdfba 100644 --- a/src/common/router/nav.ts +++ b/src/common/router/nav.ts @@ -38,6 +38,8 @@ function open(option: string | Option) { params: {}, routeName, menuId: menu.id, + icon: menu.icon, + breadcrumb: menu.breadcrumb, } ctx.insId = ctx.routeName useAppPageStore().open(ctx) @@ -67,6 +69,8 @@ function open(option: string | Option) { params: {}, routeName, menuId: menu.id, + icon: menu.icon, + breadcrumb: menu.breadcrumb, } } else { const routeName = option.routeName @@ -91,6 +95,8 @@ function open(option: string | Option) { keepAlive: true, params: option_.params ?? {}, menuId: menu.id, + icon: menu.icon, + breadcrumb: menu.breadcrumb, } ctx.insId = ctx.routeName useAppPageStore().open(ctx) @@ -121,6 +127,8 @@ function open(option: string | Option) { keepAlive: true, params: option.params ?? {}, menuId: menu.id, + icon: menu.icon, + breadcrumb: menu.breadcrumb, } } ctx.insId = ctx.routeName diff --git a/src/components/page/FormPage.vue b/src/components/page/FormPage.vue index 20c6acd..fbd473d 100644 --- a/src/components/page/FormPage.vue +++ b/src/components/page/FormPage.vue @@ -1,4 +1,4 @@ - @@ -156,7 +177,6 @@ onMounted(doSearch) - 搜索 重置 @@ -165,7 +185,7 @@ onMounted(doSearch) - + tableProps.treeLoad!(searchForm as F, row, expandedRows, undefined)):undefined" cell-class-name="table-cell" class="table-list" header-row-class-name="table-header" @@ -311,9 +335,10 @@ onMounted(doSearch) .form-page { .search-form { - border: 1px solid #00000014; + border: 1px solid #EAEBF1; padding: 20px; border-radius: 8px; background-color: white; @@ -401,7 +426,7 @@ onMounted(doSearch) flex 1 display flex flex-direction column - border: 1px solid #00000014; + border: 1px solid #EAEBF1; padding: 15px 20px 20px 15px; border-radius: 8px; background-color: white; diff --git a/src/components/page/Page.vue b/src/components/page/Page.vue index 77fc6b6..fca7cfd 100644 --- a/src/components/page/Page.vue +++ b/src/components/page/Page.vue @@ -14,7 +14,8 @@ width 100%; overflow hidden padding 5px - + contain: layout paint; + transform: translateZ(0); box-sizing border-box //box-shadow: inset rgba(30, 35, 43, 0.16) 0px 0 10px 1px; //background-color: white; diff --git a/src/dts/components.d.ts b/src/dts/components.d.ts index a7d2661..0f866c9 100644 --- a/src/dts/components.d.ts +++ b/src/dts/components.d.ts @@ -13,6 +13,8 @@ declare module 'vue' { export interface GlobalComponents { ElAside: typeof import('element-plus/es')['ElAside'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] + ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] + ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] @@ -32,8 +34,6 @@ declare module 'vue' { ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose'] - ElIconCirclePlus: typeof import('@element-plus/icons-vue')['CirclePlus'] - ElIconDelete: typeof import('@element-plus/icons-vue')['Delete'] ElIconPicture: typeof import('@element-plus/icons-vue')['Picture'] ElIconPlus: typeof import('@element-plus/icons-vue')['Plus'] ElImage: typeof import('element-plus/es')['ElImage'] @@ -71,6 +71,8 @@ declare module 'vue' { declare global { const ElAside: typeof import('element-plus/es')['ElAside'] const ElAvatar: typeof import('element-plus/es')['ElAvatar'] + const ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] + const ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] const ElButton: typeof import('element-plus/es')['ElButton'] const ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] const ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] @@ -90,8 +92,6 @@ declare global { const ElHeader: typeof import('element-plus/es')['ElHeader'] const ElIcon: typeof import('element-plus/es')['ElIcon'] const ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose'] - const ElIconCirclePlus: typeof import('@element-plus/icons-vue')['CirclePlus'] - const ElIconDelete: typeof import('@element-plus/icons-vue')['Delete'] const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture'] const ElIconPlus: typeof import('@element-plus/icons-vue')['Plus'] const ElImage: typeof import('element-plus/es')['ElImage'] diff --git a/src/pages/a-frame/AAside.tsx b/src/pages/a-frame/AAside.tsx index 245a2c5..ce15074 100644 --- a/src/pages/a-frame/AAside.tsx +++ b/src/pages/a-frame/AAside.tsx @@ -1,13 +1,11 @@ import { - ElButton, - ElIcon, ElMenu, ElMenuItem, ElMenuItemGroup, + ElScrollbar, ElSubMenu, type MenuItemRegistered, } from 'element-plus' -import { elIcons } from '@/common/element/element.ts' import AIcon from '@/components/a-icon/AIcon.vue' import type { IconName } from '@/components/a-icon/iconfont.ts' import styles from '@/pages/a-frame/aaside.module.styl' @@ -17,6 +15,7 @@ import { MenuCategory } from '@/common/app/constants.ts' import { useRouter } from 'vue-router' import { computed } from 'vue' import Nav from '@/common/router/nav.ts' +import logo from '@/assets/images/zsy.png' export interface Menu extends G.TreeNode { // Id @@ -44,11 +43,10 @@ export interface Menu extends G.TreeNode { } export default defineComponent( - () => { + (props) => { const router = useRouter() const appSettingStore = useAppSettingStore() const defaultActive = ref('') - const isCollapse = ref(false) onMounted(() => { const currentRouteName = router.currentRoute.value.name @@ -118,23 +116,27 @@ export default defineComponent( return () => ( <> - - {{ - default: () => menuTree.value.map(renderMenu), - }} - - { - isCollapse.value = !isCollapse.value - }} - > - {isCollapse.value ? : } - + + + 再昇云 + + + + {{ + default: () => menuTree.value.map(renderMenu), + }} + + > ) }, { name: 'AAside', + props: { + isCollapse: { + type: Boolean, + default: false, + }, + }, }, ) diff --git a/src/pages/a-frame/AFrame.vue b/src/pages/a-frame/AFrame.vue index 1da22fc..96387c7 100644 --- a/src/pages/a-frame/AFrame.vue +++ b/src/pages/a-frame/AFrame.vue @@ -1,9 +1,15 @@ + diff --git a/src/pages/a-frame/aaside.module.styl b/src/pages/a-frame/aaside.module.styl index bc3859f..69fb74a 100644 --- a/src/pages/a-frame/aaside.module.styl +++ b/src/pages/a-frame/aaside.module.styl @@ -1,3 +1,55 @@ +.a-aside-top { + height 60px + width 100%; + display: flex; + align-items: center; + box-sizing border-box + //padding 8px 8px 8px 18px; + padding-left 18px + //border-bottom: solid 1px var(--el-menu-border-color); + transition all 0.333s ease-in-out + gap 12px + overflow hidden + max-width 230px + //justify-content center + + & > img { + height 32px + width 32px + //margin-left 18px + //transition margin-left 0.333s ease-in-out + } + + & > div { + color: #252f4a; + font-weight: 700; + font-size: 1.5rem; + opacity 1 + width 168px; + overflow hidden + transition all 0.333s ease-in-out + text-wrap nowrap + letter-spacing 10px + } + + &.a-aside-top-collapse { + width 60px; + padding-left 14px + + & > div { + opacity 0 + width 0 + } + } +} + +.a-scrollbar { + height calc(100% - 60px) + width 100%; + padding: 0 0 10px 0; + box-sizing: border-box; +} + .a-menus { height: 100%; --el-menu-base-level-padding: 10px; @@ -65,7 +117,7 @@ bottom: 6px; width: 32px; height: 32px; - transition right 0.3s ease-in-out; + transition right 0.333s ease-in-out; &.a-collapse-btn-collapse { right: calc(50% - 16px); diff --git a/src/pages/home/Home.vue b/src/pages/home/Home.vue index 6985e16..3dd602d 100644 --- a/src/pages/home/Home.vue +++ b/src/pages/home/Home.vue @@ -4,6 +4,13 @@ + + + + 首页 + + + diff --git a/src/pages/login/Login.vue b/src/pages/login/Login.vue index 60890df..b540356 100644 --- a/src/pages/login/Login.vue +++ b/src/pages/login/Login.vue @@ -10,7 +10,7 @@ import { } from 'element-plus' import Strings from '@/common/utils/strings.ts' import FormUtil from '@/common/utils/formUtil.ts' -import { loadUserInfo } from '@/common/app' +import { reloadUserInfo } from '@/common/app' const loginFormIns = useTemplateRef('loginFormRef') @@ -55,7 +55,7 @@ function loginSubmitHandler() { () => LoginApi.login(loginForm)) .then(({data}) => { appUserStore.$patch({token: data.token}) - return loadUserInfo() + return reloadUserInfo() }) .then(() => { Evt.emit('login') diff --git a/src/pages/sys/menus/Menus.vue b/src/pages/sys/menus/Menus.vue index 976539d..87a0815 100644 --- a/src/pages/sys/menus/Menus.vue +++ b/src/pages/sys/menus/Menus.vue @@ -1,34 +1,31 @@ - - - + + + - + - - 搜索 - 重置 - - - - 新建 - - - - + + + + @@ -37,7 +34,6 @@ - @@ -52,102 +48,87 @@ - - - - - - 删除 - - - 修改 - - - - + - + + + -