【更新】重写layout布局,为更多布局扩展更方便,顺手解决标签点击不切换应用的问题

pull/141/MERGE
小诺 2023-09-25 00:49:28 +08:00 committed by 俞宝山
parent e6f4ee7f4d
commit d00dd22a29
15 changed files with 789 additions and 553 deletions

View File

@ -28,7 +28,7 @@
<strong>We're sorry but Snowy2.0 doesn't work properly without JavaScript <strong>We're sorry but Snowy2.0 doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong> enabled. Please enable it to continue.</strong>
</noscript> </noscript>
<div id="app"> <div id="app" class="admin-ui">
<div class="app-loading"> <div class="app-loading">
<div class="app-loading__logo"> <div class="app-loading__logo">
<img src="/img/logo.png"/> <img src="/img/logo.png"/>

View File

@ -46,10 +46,10 @@ const DEFAULT_CONFIG = {
SNOWY_BREADCRUMD_OPEN: false, SNOWY_BREADCRUMD_OPEN: false,
// 顶栏是否应用主题色 // 顶栏是否应用主题色
SNOWY_TOP_HANDER_THEME_COLOR_OPEN: false, SNOWY_TOP_HEADER_THEME_COLOR_OPEN: false,
// 顶栏主题色通栏 // 顶栏主题色通栏
SNOWY_TOP_HANDER_THEME_COLOR_SPREAD: false, SNOWY_TOP_HEADER_THEME_COLOR_SPREAD: false,
// 侧边菜单是否排他展开 // 侧边菜单是否排他展开
SNOWY_SIDE_UNIQUE_OPEN: true, SNOWY_SIDE_UNIQUE_OPEN: true,

View File

@ -20,7 +20,7 @@
}, },
computed: { computed: {
...mapState(iframeStore, ['iframeList']), ...mapState(iframeStore, ['iframeList']),
...mapState(globalStore, ['ismobile', 'layoutTags']) ...mapState(globalStore, ['isMobile', 'layoutTags'])
}, },
watch: { watch: {
$route(e) { $route(e) {
@ -35,12 +35,12 @@
...mapActions(iframeStore, ['setIframeList', 'pushIframeList', 'clearIframeList']), ...mapActions(iframeStore, ['setIframeList', 'pushIframeList', 'clearIframeList']),
push(route) { push(route) {
if (route.meta.type === 'iframe') { if (route.meta.type === 'iframe') {
if (this.ismobile || !this.layoutTags) { if (this.isMobile || !this.layoutTags) {
this.setIframeList(route) this.setIframeList(route)
} else { } else {
this.pushIframeList(route) this.pushIframeList(route)
} }
} else if (this.ismobile || !this.layoutTags) { } else if (this.isMobile || !this.layoutTags) {
this.clearIframeList() this.clearIframeList()
} }
} }

View File

@ -20,13 +20,7 @@
<a-button type="primary" @click="leaveFor('/usercenter')"></a-button> <a-button type="primary" @click="leaveFor('/usercenter')"></a-button>
</a-space> </a-space>
</a-drawer> </a-drawer>
<xn-form-container <xn-form-container title="详情" :width="700" :visible="visible" :destroy-on-close="true" @close="onClose">
title="详情"
:width="700"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<a-form ref="formRef" :model="formData" layout="vertical"> <a-form ref="formRef" :model="formData" layout="vertical">
<a-form-item label="主题:" name="subject"> <a-form-item label="主题:" name="subject">
<span>{{ formData.subject }}</span> <span>{{ formData.subject }}</span>
@ -84,7 +78,10 @@
let clientId = tool.data.get('CLIENTID') ? tool.data.get('CLIENTID') : '' let clientId = tool.data.get('CLIENTID') ? tool.data.get('CLIENTID') : ''
let url = sysConfig.API_URL + '/dev/message/createSseConnect?clientId=' + clientId let url = sysConfig.API_URL + '/dev/message/createSseConnect?clientId=' + clientId
// heartbeatTimeout: 30s // heartbeatTimeout: 30s
let source = new EventSourcePolyfill(url, { headers: { token: tool.data.get('TOKEN') }, heartbeatTimeout: 30000 }) let source = new EventSourcePolyfill(url, {
headers: { token: tool.data.get('TOKEN') },
heartbeatTimeout: 300000
})
// //
source.addEventListener('open', (e) => {}) source.addEventListener('open', (e) => {})
// //

View File

@ -5,7 +5,7 @@
mode="horizontal" mode="horizontal"
v-if="menu && menu.length > 1" v-if="menu && menu.length > 1"
class="module-menu" class="module-menu"
id="moduleMunu" id="moduleMenu"
> >
<a-menu-item <a-menu-item
v-for="item in menu" v-for="item in menu"
@ -21,7 +21,7 @@
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</div> </div>
<div v-else class="panel-item hidden-sm-and-down"> <div v-else>
<a-popover v-if="menu.length > 1" placement="bottomLeft"> <a-popover v-if="menu.length > 1" placement="bottomLeft">
<template #content> <template #content>
<a-row :gutter="[0, 5]" class="module-row"> <a-row :gutter="[0, 5]" class="module-row">
@ -35,7 +35,9 @@
</div> </div>
</a-row> </a-row>
</template> </template>
<div class="panel-item hidden-sm-and-down module-card-scope">
<appstore-outlined /> <appstore-outlined />
</div>
</a-popover> </a-popover>
</div> </div>
</template> </template>
@ -49,24 +51,30 @@
const store = globalStore() const store = globalStore()
const { moduleUnfoldOpen, topHanderThemeColorOpen } = storeToRefs(store) const { moduleUnfoldOpen, topHeaderThemeColorOpen } = storeToRefs(store)
const moduleBackColor = ref(topHanderThemeColorOpen) const moduleBackColor = ref(topHeaderThemeColorOpen)
const module = computed(() => {
return store.module
})
// //
watch(moduleUnfoldOpen, (newValue) => { watch(moduleUnfoldOpen, (newValue) => {
nextTick(() => { nextTick(() => {
setModuleBackColor() setModuleBackColor()
}) })
}) })
watch(module, (newValue) => {
selectedKeys.value = [newValue]
setSelectedKeys()
})
// //
watch(topHanderThemeColorOpen, (newValue) => { watch(topHeaderThemeColorOpen, (newValue) => {
moduleBackColor.value = newValue moduleBackColor.value = newValue
setModuleBackColor() setModuleBackColor()
}) })
const emit = defineEmits({ switchModule: null }) const emit = defineEmits({ switchModule: null })
const menu = router.getMenu() const menu = router.getMenu()
const selectedKeys = ref([tool.data.get('SNOWY_MENU_MODULE_ID')]) const selectedKeys = ref([module.value])
const moduleClick = (id) => { const moduleClick = (id) => {
emit('switchModule', id) emit('switchModule', id)
tool.data.set('SNOWY_MENU_MODULE_ID', id) tool.data.set('SNOWY_MENU_MODULE_ID', id)
@ -82,24 +90,24 @@
const setModuleBackColor = () => { const setModuleBackColor = () => {
if (moduleUnfoldOpen.value) { if (moduleUnfoldOpen.value) {
try { try {
const moduleMunu = document.getElementById('moduleMunu') const moduleMenu = document.getElementById('moduleMenu')
moduleBackColor.value moduleBackColor.value
? moduleMunu.classList.add('module-menu-color') ? moduleMenu.classList.add('module-menu-color')
: moduleMunu.classList.remove('module-menu-color') : moduleMenu.classList.remove('module-menu-color')
} catch (err) {} } catch (err) {}
setSelectedKeys() setSelectedKeys()
} }
} }
// //
const setSelectedKeys = () => { const setSelectedKeys = () => {
// //
moduleBackColor.value moduleBackColor.value
? (selectedKeys.value = new Array([])) ? (selectedKeys.value = new Array([]))
: (selectedKeys.value = [tool.data.get('SNOWY_MENU_MODULE_ID')]) : (selectedKeys.value = [tool.data.get('SNOWY_MENU_MODULE_ID')])
} }
</script> </script>
<style type="less"> <style lang="less">
.module-row { .module-row {
max-width: 357px; max-width: 357px;
} }
@ -135,4 +143,7 @@
color: white; color: white;
background-color: var(--primary-color); background-color: var(--primary-color);
} }
.module-card-scope {
height: 49px;
}
</style> </style>

View File

@ -41,14 +41,14 @@
</div> </div>
<div class="mb-4 layout-slide"> <div class="mb-4 layout-slide">
<h4 class="">顶栏应用主题色</h4> <h4 class="">顶栏应用主题色</h4>
<a-switch :checked="topHanderThemeColorOpen" @change="changeTopHanderThemeColorOpen" /> <a-switch :checked="topHeaderThemeColorOpen" @change="changeTopHanderThemeColorOpen" />
</div> </div>
<div class="mb-4 layout-slide"> <div class="mb-4 layout-slide">
<h4>顶栏主题色通栏</h4> <h4>顶栏主题色通栏</h4>
<a-switch <a-switch
style="float: right" style="float: right"
:checked="topHanderThemeColorSpread" :checked="topHeaderThemeColorSpread"
:disabled="!topHanderThemeColorOpen" :disabled="!topHeaderThemeColorOpen"
@change="changeTopHanderThemeColorSpread" @change="changeTopHanderThemeColorSpread"
/> />
</div> </div>
@ -99,8 +99,8 @@
sideUniqueOpen: 'SIDE_UNIQUE_OPEN', sideUniqueOpen: 'SIDE_UNIQUE_OPEN',
layoutTagsOpen: 'LAYOUT_TAGS_OPEN', layoutTagsOpen: 'LAYOUT_TAGS_OPEN',
breadcrumbOpen: 'BREADCRUMD_OPEN', breadcrumbOpen: 'BREADCRUMD_OPEN',
topHanderThemeColorOpen: 'TOP_HANDER_THEME_COLOR_OPEN', topHeaderThemeColorOpen: 'TOP_HEADER_THEME_COLOR_OPEN',
topHanderThemeColorSpread: 'TOP_HANDER_THEME_COLOR_SPREAD', topHeaderThemeColorSpread: 'TOP_HEADER_THEME_COLOR_SPREAD',
moduleUnfoldOpen: 'MODULE_UNFOLD_OPEN' moduleUnfoldOpen: 'MODULE_UNFOLD_OPEN'
} }
export default defineComponent({ export default defineComponent({
@ -159,22 +159,22 @@
'layoutTagsOpen', 'layoutTagsOpen',
'breadcrumbOpen', 'breadcrumbOpen',
'moduleUnfoldOpen', 'moduleUnfoldOpen',
'topHanderThemeColorOpen', 'topHeaderThemeColorOpen',
'topHanderThemeColorSpread', 'topHeaderThemeColorSpread',
'formStyle' 'formStyle'
]) ])
}, },
mounted() {}, mounted() {},
methods: { methods: {
changeTopHanderThemeColorOpen() { changeTopHanderThemeColorOpen() {
this.toggleState('topHanderThemeColorOpen') this.toggleState('topHeaderThemeColorOpen')
if (!this.topHanderThemeColorOpen) { if (!this.topHeaderThemeColorOpen) {
this.globalStore.topHanderThemeColorSpread = false this.globalStore.topHeaderThemeColorSpread = false
tool.data.set('SNOWY_TOP_HANDER_THEME_COLOR_SPREAD', false) tool.data.set('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD', false)
} }
}, },
changeTopHanderThemeColorSpread() { changeTopHanderThemeColorSpread() {
this.toggleState('topHanderThemeColorSpread') this.toggleState('topHeaderThemeColorSpread')
}, },
toggleState(stateName) { toggleState(stateName) {
this.globalStore.toggleConfig(stateName) this.globalStore.toggleConfig(stateName)

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="adminui-topbar"> <div class="admin-ui-topbar">
<div class="left-panel"> <div class="left-panel">
<a-breadcrumb> <a-breadcrumb>
<template v-for="item in breadList" :key="item.title"> <template v-for="item in breadList" :key="item.title">

View File

@ -5,7 +5,7 @@
<div v-if="!isMobile" class="screen panel-item hidden-sm-and-down" @click="fullscreen"> <div v-if="!isMobile" class="screen panel-item hidden-sm-and-down" @click="fullscreen">
<fullscreen-outlined /> <fullscreen-outlined />
</div> </div>
<dev-user-message /> <!-- <dev-user-message />-->
<a-dropdown class="user panel-item"> <a-dropdown class="user panel-item">
<div class="user-avatar"> <div class="user-avatar">
<a-avatar :src="userInfo.avatar" /> <a-avatar :src="userInfo.avatar" />
@ -74,7 +74,7 @@
const setDrawer = ref(import.meta.env.VITE_SET_DRAWER) const setDrawer = ref(import.meta.env.VITE_SET_DRAWER)
const store = globalStore() const store = globalStore()
const isMobile = computed(() => { const isMobile = computed(() => {
return store.ismobile return store.isMobile
}) })
const userInfo = computed(() => { const userInfo = computed(() => {
return store.userInfo return store.userInfo

View File

@ -1,501 +1,388 @@
<template> <template>
<div class="aminui">
<!-- 经典布局 --> <!-- 经典布局 -->
<template v-if="layout === 'classical'"> <classical
<a-layout> v-if="layout === 'classical'"
<a-layout-sider :is-mobile="isMobile"
v-if="!ismobile" :menu-is-collapse="menuIsCollapse"
v-model:collapsed="menuIsCollapse" :side-theme="sideTheme"
:trigger="null" :sys-base-config="sysBaseConfig"
collapsible :open-keys="openKeys"
:theme="sideTheme" :selected-keys="selectedKeys"
width="210" :menu="menu"
> :breadcrumb-open="breadcrumbOpen"
<header id="snowyHeaderLogo" class="snowy-header-logo"> :layout-tags-open="layoutTagsOpen"
<div class="snowy-header-left"> :keep-live-route="keepLiveRoute"
<div class="logo-bar"> :route-show="routeShow"
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" /> :route="route"
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span> @onSelect="onSelect"
</div> @onOpenChange="onOpenChange"
</div> @menuIsCollapseClick="menuIsCollapseClick"
</header> @switchModule="switchModule"
<div :class="menuIsCollapse ? 'aminui-side isCollapse' : 'aminui-side'"> />
<div class="adminui-side-scroll">
<a-menu
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
:theme="sideTheme"
mode="inline"
@select="onSelect"
@openChange="onOpenChange"
>
<NavMenu :nav-menus="menu" />
</a-menu>
</div>
</div>
</a-layout-sider>
<!-- 手机端情况下的左侧菜单 -->
<Side-m v-if="ismobile" />
<!-- 右侧布局 -->
<a-layout>
<div id="snowyHeader" class="snowy-header">
<div class="snowy-header-left" style="padding-left: 0px">
<div v-if="!ismobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
<MenuUnfoldOutlined v-if="menuIsCollapse" />
<MenuFoldOutlined v-else />
</div>
<moduleMenu @switchModule="switchModule" />
<Topbar v-if="!ismobile && breadcrumbOpen" />
</div>
<div class="snowy-header-right">
<userbar />
</div>
</div>
<!-- 多标签 -->
<Tags v-if="!ismobile && layoutTagsOpen" />
<a-layout-content class="main-content-wrapper">
<div id="adminui-main" class="adminui-main">
<router-view v-slot="{ Component }">
<keep-alive :include="keepLiveRoute">
<component :is="Component" :key="$route.name" v-if="routeShow" />
</keep-alive>
</router-view>
<iframe-view />
<div class="main-bottom-wrapper">
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
sysBaseConfig.SNOWY_SYS_COPYRIGHT
}}</a>
</div>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<!-- 双排菜单布局 --> <!-- 双排菜单布局 -->
<template v-else-if="layout === 'doublerow'"> <double-row
<a-layout> v-else-if="layout === 'doublerow'"
<a-layout-sider v-if="!ismobile" width="80" :theme="sideTheme" :trigger="null" collapsible> :is-mobile="isMobile"
<header id="snowyHeaderLogo" class="snowy-header-logo"> :menu-is-collapse="menuIsCollapse"
<div class="snowy-header-left"> :side-theme="sideTheme"
<div class="logo-bar"> :sys-base-config="sysBaseConfig"
<router-link to="/"> :open-keys="openKeys"
<img class="logo" :title="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" /> :selected-keys="selectedKeys"
</router-link> :menu="menu"
</div> :breadcrumb-open="breadcrumbOpen"
</div> :layout-tags-open="layoutTagsOpen"
</header> :keep-live-route="keepLiveRoute"
<a-menu v-model:selectedKeys="doublerowSelectedKey" :theme="sideTheme" class="snowy-doublerow-layout-menu"> :route-show="routeShow"
<a-menu-item :route="route"
v-for="item in menu" :layoutSiderDowbleMenu="layoutSiderDowbleMenu"
:key="item.path" :secondMenuSideTheme="secondMenuSideTheme"
style=" :nextMenu="nextMenu"
text-align: center; :doublerowSelectedKey="doublerowSelectedKey"
border-radius: 2px; :pMenu="pMenu"
height: auto; @onSelect="onSelect"
line-height: 20px; @showMenu="showMenu"
flex: none; @onOpenChange="onOpenChange"
display: block; @menuIsCollapseClick="menuIsCollapseClick"
padding: 12px 0 !important; @switchModule="switchModule"
" />
@click="showMenu(item)"
>
<a
v-if="item.meta && item.meta.type === 'link'"
:href="item.path"
target="_blank"
@click.stop="() => {}"
></a>
<template #icon>
<component :is="item.meta.icon" style="padding-left: 10px" />
</template>
<div class="snowy-doublerow-layout-menu-item-fort-div">
<span class="snowy-doublerow-layout-menu-item-fort-div-span">
{{ item.meta.title }}
</span>
</div>
</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout-sider
v-if="!ismobile"
v-show="layoutSiderDowbleMenu"
v-model:collapsed="menuIsCollapse"
:trigger="null"
width="170"
collapsible
:theme="secondMenuSideTheme"
>
<div v-if="!menuIsCollapse" id="snowyDoublerowSideTop" class="snowy-doublerow-side-top">
<h2 class="snowy-title">{{ pmenu.meta.title }}</h2>
</div>
<a-menu
v-model:collapsed="menuIsCollapse"
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
mode="inline"
:theme="secondMenuSideTheme"
@select="onSelect"
>
<NavMenu :nav-menus="nextMenu" />
</a-menu>
</a-layout-sider>
<!-- 手机端情况下的左侧菜单 -->
<Side-m v-if="ismobile" />
<a-layout>
<div id="snowyHeader" class="snowy-header">
<div class="snowy-header-left" style="padding-left: 0px">
<div v-if="!ismobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
<MenuUnfoldOutlined v-if="menuIsCollapse" />
<MenuFoldOutlined v-else />
</div>
<moduleMenu @switchModule="switchModule" />
<Topbar v-if="!ismobile && breadcrumbOpen" />
</div>
<div class="snowy-header-right">
<userbar />
</div>
</div>
<!-- 多标签 -->
<Tags v-if="!ismobile && layoutTagsOpen"></Tags>
<a-layout-content class="main-content-wrapper">
<div id="adminui-main" class="adminui-main">
<router-view v-slot="{ Component }">
<keep-alive :include="keepLiveRoute">
<component :is="Component" v-if="routeShow" :key="$route.name" />
</keep-alive>
</router-view>
<iframe-view />
<div class="main-bottom-wrapper">
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
sysBaseConfig.SNOWY_SYS_COPYRIGHT
}}</a>
</div>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<!-- 退出最大化 --> <!-- 退出最大化 -->
<div class="main-maximize-exit" @click="exitMaximize"> <div class="main-maximize-exit" @click="exitMaximize">
<fullscreen-exit-outlined style="color: #fff" /> <fullscreen-exit-outlined style="color: #fff" />
</div> </div>
</div>
</template> </template>
<script> <script setup>
import SideM from './components/sideM.vue' import Classical from '@/layout/pattern/classical.vue'
import Topbar from './components/topbar.vue' import DoubleRow from '@/layout/pattern/doublerow.vue'
import Tags from './components/tags.vue'
import NavMenu from './components/NavMenu.vue'
import userbar from './components/userbar.vue'
import iframeView from './components/iframeView.vue'
import moduleMenu from './components/moduleMenu.vue'
import { ThemeModeEnum } from '@/utils/enum'
import { globalStore, keepAliveStore } from '@/store' import { globalStore, keepAliveStore } from '@/store'
import { mapState, mapStores, mapActions } from 'pinia' import { ThemeModeEnum } from '@/utils/enum'
import { useRouter, useRoute } from 'vue-router'
import tool from '@/utils/tool' import tool from '@/utils/tool'
import { message } from 'ant-design-vue'
export default defineComponent({ const store = globalStore()
name: 'Index', const kStore = keepAliveStore()
components: { const route = useRoute()
SideM, const router = useRouter()
Topbar, const menu = ref([])
Tags, const pMenu = ref({})
NavMenu, const nextMenu = ref([])
userbar, const selectedKeys = ref([])
moduleMenu, const openKeys = ref([])
iframeView const onSelectTag = ref(false)
}, const moduleMenu = ref([])
data() { const doublerowSelectedKey = ref([])
return { const layoutSiderDowbleMenu = ref(true)
menu: [], const currentRoute = ref()
moduleMenu: [], // computed - start
nextMenu: [], const layout = computed(() => {
pmenu: {}, return store.layout
doublerowSelectedKey: [],
layoutSiderDowbleMenu: true,
onSelectTag: false,
selectedKeys: [],
openKeys: [],
openKeysOther: []
}
},
computed: {
...mapStores(globalStore),
...mapState(globalStore, [
'theme',
'ismobile',
'layout',
'layoutTagsOpen',
'menuIsCollapse',
'breadcrumbOpen',
'topHanderThemeColorOpen',
'topHanderThemeColorSpread',
'topHanderThemeColor',
'sideUniqueOpen',
'sysBaseConfig'
]),
...mapState(keepAliveStore, ['keepLiveRoute', 'routeShow']),
sideTheme() {
const theme = this.theme
return theme === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme
},
secondMenuSideTheme() {
const theme = this.theme
return theme === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : ThemeModeEnum.LIGHT
}
},
watch: {
$route() {
this.showThis()
},
layout: {
handler(val) {
document.body.setAttribute('data-layout', val)
if (val.includes('doublerow')) {
this.setDoublerowSelectedKey()
}
this.$nextTick(() => {
//
this.switchoverTopHanderThemeColor()
}) })
}, const isMobile = computed(() => {
immediate: true return store.isMobile
},
topHanderThemeColorOpen() {
this.switchoverTopHanderThemeColor()
},
topHanderThemeColorSpread() {
this.switchoverTopHanderThemeColor()
}
},
created() {
//
this.onLayoutResize()
window.addEventListener('resize', this.onLayoutResize)
this.moduleMenu = this.$router.getMenu()
//
const menuModuleId = tool.data.get('SNOWY_MENU_MODULE_ID')
let menu = []
if (menuModuleId) {
//
const module = this.$router.getMenu().filter((item) => item.id === menuModuleId)
if (module.length > 0) {
menu = module[0].children
} else {
menu = this.$router.getMenu()[0].children
}
} else {
menu = this.$router.getMenu()[0].children
}
//
this.menu = this.filterUrl(menu)
this.showThis()
},
mounted() {
this.switchoverTopHanderThemeColor()
},
methods: {
...mapActions(globalStore, ['setTheme', 'setIsmobile', 'setLayout', 'setMenuIsCollapse']),
//
switchModule(id) {
const menu = this.moduleMenu
if (menu.length > 0) {
const menus = menu.filter((item) => item.id === id)[0].children
if (menus.length > 0) {
//
tool.data.set('SNOWY_MENU_MODULE_ID', id)
//
this.menu = this.filterUrl(menus)
//
const path = this.traverseChild(this.menu)
this.$router.push({ path })
} else {
this.$message.warning('该模块下无任何菜单')
}
}
},
// path
traverseChild(menu) {
if (menu[0].children !== undefined) {
if (menu[0].children.length > 0) {
return this.traverseChild(menu[0].children)
} else {
return menu[0].path
}
} else {
return menu[0].path
}
},
//
onSelect(obj) {
this.onSelectTag = true
const pathLength = obj.keyPath.length
const path = obj.keyPath[pathLength - 1]
this.$router.push({ path })
//
this.selectedKeys = obj.selectedKeys
},
onLayoutResize() {
const clientWidth = document.body.clientWidth
this.setIsmobile(clientWidth < 992)
},
//
showThis() {
this.pmenu = this.$route.meta.breadcrumb ? this.$route.meta.breadcrumb[0] : {}
const nextTickMenu = this.filterUrl(this.pmenu.children)
this.$nextTick(() => {
let routeMenu = this.filterUrl(this.pmenu.children)
const active = this.$route.meta.active || this.$route.fullPath
const parentPathArray = this.getParentKeys(routeMenu, active)
if (parentPathArray) {
const parentPath = parentPathArray[parentPathArray.length - 1]
//
const nextMenuTemp = nextTickMenu.filter((item) => item.path === parentPath)[0].children
if (nextMenuTemp) {
this.nextMenu = nextTickMenu.filter((item) => item.path === parentPath)[0].children
}
}
this.selectedKeys = new Array(active)
if (!this.onSelectTag) {
const pidKey = this.getParentKeys(this.menu, active)
this.openKeys = pidKey
} else if (this.sideUniqueOpen) {
const pidKey = this.getParentKeys(this.menu, active)
this.openKeys = pidKey
}
//
if (this.layout === 'doublerow') {
this.setDoublerowSelectedKey()
}
}) })
}, const menuIsCollapse = computed(() => {
// return store.menuIsCollapse
showMenu(route) {
this.pmenu = route
if (this.pmenu.children) {
this.nextMenu = this.filterUrl(this.pmenu.children)
}
if (!route.children || route.children.length === 0) {
this.layoutSiderDowbleMenu = false
this.$router.push({ path: route.path })
} else {
this.layoutSiderDowbleMenu = true
}
if (this.layout === 'doublerow') {
this.doublerowSelectedKey = [route.path]
}
},
//
setDoublerowSelectedKey() {
const pidKey = this.getParentKeys(this.menu, this.selectedKeys.toString())
this.$nextTick(() => {
const pidKeyArray = []
for (const key in pidKey) {
pidKeyArray.push(key)
}
if (pidKeyArray.length > 1) {
this.layoutSiderDowbleMenu = true
} else {
this.layoutSiderDowbleMenu = false
}
}) })
// const theme = computed(() => {
this.menu.forEach((item) => { return store.theme
if (pidKey !== undefined) { })
if (pidKey[pidKey.length - 1].toString() === item.path) { const layoutTagsOpen = computed(() => {
this.doublerowSelectedKey = [item.path] return store.layoutTagsOpen
} })
} const breadcrumbOpen = computed(() => {
return store.breadcrumbOpen
})
const topHeaderThemeColorOpen = computed(() => {
return store.topHeaderThemeColorOpen
})
const topHeaderThemeColorSpread = computed(() => {
return store.topHeaderThemeColorSpread
})
const sideUniqueOpen = computed(() => {
return store.sideUniqueOpen
})
const sysBaseConfig = computed(() => {
return store.sysBaseConfig
})
const module = computed(() => {
return store.module
})
const keepLiveRoute = computed(() => {
return kStore.keepLiveRoute
})
const routeShow = computed(() => {
return kStore.routeShow
})
const sideTheme = computed(() => {
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme.value
})
const secondMenuSideTheme = computed(() => {
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : ThemeModeEnum.LIGHT
}) })
},
// /
onOpenChange(keys) {
if (this.sideUniqueOpen) {
//
const openKey = keys[keys.length - 1]
if (keys.length > 1) {
//
const pidKey = this.getParentKeys(this.menu, openKey)
this.openKeys = pidKey
} else {
this.openKeys = Array.of(openKey) // new Array(openKey);
}
} else {
this.openKeys = keys
}
},
// keys
getParentKeys(data, val) {
// key
for (const element of data) {
if (element.path === val) {
return [element.path]
}
if (element.children) {
const far = this.getParentKeys(element.children, val)
if (far) {
return far.concat(element.path)
}
}
}
},
// //
filterUrl(map) { const filterUrl = (map) => {
const newMap = [] const newMap = []
// eslint-disable-next-line no-unused-expressions const traverse = (maps) => {
map && maps &&
map.forEach((item) => { maps.forEach((item) => {
item.meta = item.meta ? item.meta : {} item.meta = item.meta ? item.meta : {}
// //
if (item.meta.hidden) { if (item.meta.hidden) {
return false return false
} }
// http // iframe
if (item.meta.type === 'iframe') { if (item.meta.type === 'iframe') {
item.path = `/i/${item.name}` item.path = `/i/${item.name}`
} }
// //
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
item.children = this.filterUrl(item.children) item.children = filterUrl(item.children)
} }
newMap.push(item) newMap.push(item)
}) })
}
traverse(map)
return newMap return newMap
}, }
menuIsCollapseClick() { //
this.globalStore.toggleConfig('menuIsCollapse') const showThis = () => {
}, pMenu.value = route.meta.breadcrumb ? route.meta.breadcrumb[0] : {}
// 退 //
exitMaximize() { nextTick(() => {
document.getElementById('app').classList.remove('main-maximize') //
}, const active = route.meta.active || route.fullPath
selectedKeys.value = new Array(active)
const pidKey = getParentKeys(pMenu.value.children, active)
const nextTickMenu = pMenu.value.children
if (pidKey) {
const parentPath = pidKey[pidKey.length - 1]
if (layout.value === 'doublerow') {
//
const nextMenuTemp = nextTickMenu.filter((item) => item.path === parentPath)[0].children
if (nextMenuTemp) {
nextMenu.value = nextTickMenu.filter((item) => item.path === parentPath)[0].children
}
}
}
if (!onSelectTag.value || sideUniqueOpen.value) {
openKeys.value = pidKey
}
//
if (layout.value === 'doublerow') {
setDoubleRowSelectedKey()
}
})
}
// -start
moduleMenu.value = router.getMenu()
//
const menuModuleId = tool.data.get('SNOWY_MENU_MODULE_ID')
let initMenu = []
if (menuModuleId) {
//
const module = router.getMenu().filter((item) => item.id === menuModuleId)
if (module.length > 0) {
initMenu = module[0].children
} else {
initMenu = router.getMenu()[0].children
}
} else {
initMenu = router.getMenu()[0].children
}
menu.value = filterUrl(initMenu)
showThis()
onMounted(() => {
switchoverTopHeaderThemeColor()
})
watch(route, (newValue) => {
currentRoute.value = route.path
//
selectedKeys.value = []
showThis()
if (layoutTagsOpen.value) {
const pidKey = getParentKeys(moduleMenu.value, route.path)
moduleMenu.value.forEach((item) => {
if (pidKey.includes(item.path)) {
tagSwitchModule(item.id, route.path)
}
})
}
})
//
watch(layout, (newValue) => {
document.body.setAttribute('data-layout', newValue)
if (newValue.includes('doublerow')) {
showThis()
setDoubleRowSelectedKey()
}
nextTick(() => {
//
switchoverTopHeaderThemeColor()
})
})
watch(topHeaderThemeColorOpen, (newValue) => {
console.log(topHeaderThemeColorOpen)
switchoverTopHeaderThemeColor()
})
watch(topHeaderThemeColorSpread, (newValue) => {
switchoverTopHeaderThemeColor()
})
const menuIsCollapseClick = () => {
store.toggleConfig('menuIsCollapse')
}
// //
switchoverTopHanderThemeColor() { const switchoverTopHeaderThemeColor = () => {
console.log('刷新完之后' + topHeaderThemeColorOpen.value)
// //
const header = document.getElementById('snowyHeader') const header = document.getElementById('snowyHeader')
this.topHanderThemeColorOpen topHeaderThemeColorOpen.value
? header.classList.add('snowy-header-primary-color') ? header.classList.add('snowy-header-primary-color')
: header.classList.remove('snowy-header-primary-color') : header.classList.remove('snowy-header-primary-color')
// //
const headerLogin = document.getElementById('snowyHeaderLogo') const headerLogin = document.getElementById('snowyHeaderLogo')
try { try {
this.topHanderThemeColorSpread topHeaderThemeColorSpread.value
? headerLogin.classList.add('snowy-header-logo-primary-color') ? headerLogin.classList.add('snowy-header-logo-primary-color')
: headerLogin.classList.remove('snowy-header-logo-primary-color') : headerLogin.classList.remove('snowy-header-logo-primary-color')
} catch (e) {} } catch (e) {}
// //
if (this.layout === 'doublerow') { if (layout.value === 'doublerow') {
const snowyDoublerowSideTop = document.getElementById('snowyDoublerowSideTop') const snowyDoublerowSideTop = document.getElementById('snowyDoublerowSideTop')
try { try {
this.topHanderThemeColorSpread topHeaderThemeColorSpread.value
? snowyDoublerowSideTop.classList.add('snowy-doublerow-side-top-primary-color') ? snowyDoublerowSideTop.classList.add('snowy-doublerow-side-top-primary-color')
: snowyDoublerowSideTop.classList.remove('snowy-doublerow-side-top-primary-color') : snowyDoublerowSideTop.classList.remove('snowy-doublerow-side-top-primary-color')
} catch (e) {} } catch (e) {}
} }
} }
//
const setDoubleRowSelectedKey = () => {
const pidKey = getParentKeys(menu.value, selectedKeys.value.toString())
nextTick(() => {
const pidKeyArray = []
for (const key in pidKey) {
pidKeyArray.push(key)
}
layoutSiderDowbleMenu.value = pidKeyArray.length > 1
})
//
menu.value.forEach((item) => {
if (pidKey !== undefined) {
if (pidKey[pidKey.length - 1].toString() === item.path) {
doublerowSelectedKey.value = [item.path]
}
} }
}) })
}
// /
const onOpenChange = (keys) => {
if (sideUniqueOpen.value) {
//
const openKey = keys[keys.length - 1]
if (keys.length > 1) {
//
openKeys.value = getParentKeys(menu.value, openKey)
} else {
openKeys.value = Array.of(openKey) // new Array(openKey);
}
} else {
openKeys.value = keys
}
}
// keys
const getParentKeys = (data, val) => {
const traverse = (array, val) => {
// key
for (const element of array) {
if (element.path === val) {
return [element.path]
}
if (element.children) {
const far = traverse(element.children, val)
if (far) {
return far.concat(element.path)
}
}
}
}
return traverse(data, val)
}
//
const showMenu = (route) => {
pMenu.value = route
if (pMenu.value.children) {
nextMenu.value = filterUrl(pMenu.value.children)
}
if (!route.children || route.children.length === 0) {
layoutSiderDowbleMenu.value = false
router.push({ path: route.path })
} else {
layoutSiderDowbleMenu.value = true
}
if (layout.value === 'doublerow') {
doublerowSelectedKey.value = [route.path]
}
}
//
const onSelect = (obj) => {
onSelectTag.value = true
const pathLength = obj.keyPath.length
const path = obj.keyPath[pathLength - 1]
router.push({ path })
//
selectedKeys.value = obj.selectedKeys
}
const onLayoutResize = () => {
const clientWidth = document.body.clientWidth
store.setIsMobile(clientWidth < 992)
}
//
const switchModule = (id) => {
if (moduleMenu.value.length > 0) {
showThis()
const menus = moduleMenu.value.filter((item) => item.id === id)[0].children
if (menus.length > 0) {
//
tool.data.set('SNOWY_MENU_MODULE_ID', id)
//
menu.value = filterUrl(menus)
//
const path = traverseChild(menu.value)
router.push({ path })
} else {
message.warning('该模块下无任何菜单')
}
}
}
//
const tagSwitchModule = (id, path) => {
//
tool.data.set('SNOWY_MENU_MODULE_ID', id)
store.setModule(id)
const menus = moduleMenu.value.filter((item) => item.id === id)[0].children
//
menu.value = filterUrl(menus)
router.push({ path })
}
// path
const traverseChild = (menu) => {
if (menu[0].children !== undefined) {
if (menu[0].children.length > 0) {
return traverseChild(menu[0].children)
} else {
return menu[0].path
}
} else {
return menu[0].path
}
}
// 退
const exitMaximize = () => {
document.getElementById('app').classList.remove('main-maximize')
}
</script> </script>

View File

@ -0,0 +1,146 @@
<template>
<a-layout>
<a-layout-sider
v-if="!isMobile"
v-model:collapsed="menuIsCollapse"
:trigger="null"
collapsible
:theme="sideTheme"
width="210"
>
<header id="snowyHeaderLogo" class="snowy-header-logo">
<div class="snowy-header-left">
<div class="logo-bar">
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
</div>
</div>
</header>
<div :class="menuIsCollapse ? 'admin-ui-side isCollapse' : 'admin-ui-side'">
<div class="admin-ui-side-scroll">
<a-menu
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
:theme="sideTheme"
mode="inline"
@select="onSelect"
@openChange="onOpenChange"
>
<NavMenu :nav-menus="menu" />
</a-menu>
</div>
</div>
</a-layout-sider>
<!-- 手机端情况下的左侧菜单 -->
<Side-m v-if="isMobile" />
<!-- 右侧布局 -->
<a-layout>
<div id="snowyHeader" class="snowy-header">
<div class="snowy-header-left" style="padding-left: 0px">
<div v-if="!isMobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
<MenuUnfoldOutlined v-if="menuIsCollapse" />
<MenuFoldOutlined v-else />
</div>
<moduleMenu @switchModule="switchModule" />
<top-bar v-if="!isMobile && breadcrumbOpen" />
</div>
<div class="snowy-header-right">
<user-bar />
</div>
</div>
<!-- 多标签 -->
<Tags v-if="!isMobile && layoutTagsOpen" />
<a-layout-content class="main-content-wrapper">
<div id="admin-ui-main" class="admin-ui-main">
<router-view v-slot="{ Component }">
<keep-alive :include="keepLiveRoute">
<component :is="Component" :key="route.name" v-if="routeShow" />
</keep-alive>
</router-view>
<iframe-view />
<div class="main-bottom-wrapper">
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
sysBaseConfig.SNOWY_SYS_COPYRIGHT
}}</a>
</div>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script setup name="classicalLayout">
import UserBar from '@/layout/components/userbar.vue'
import Tags from '@/layout/components/tags.vue'
import SideM from '@/layout/components/sideM.vue'
import NavMenu from '@/layout/components/NavMenu.vue'
import ModuleMenu from '@/layout/components/moduleMenu.vue'
import IframeView from '@/layout/components/iframeView.vue'
import TopBar from '@/layout/components/topbar.vue'
const props = defineProps({
isMobile: {
type: Boolean,
default: () => false
},
menuIsCollapse: {
type: Boolean,
default: () => false
},
sideTheme: {
type: String,
default: () => ''
},
sysBaseConfig: {
type: Object,
default: () => undefined
},
openKeys: {
type: Array,
default: () => []
},
selectedKeys: {
type: Array,
default: () => []
},
menu: {
type: Array,
default: () => []
},
breadcrumbOpen: {
type: Boolean,
default: () => false
},
layoutTagsOpen: {
type: Boolean,
default: () => false
},
keepLiveRoute: {
type: Array,
default: () => []
},
routeShow: {
type: Boolean,
default: () => false
},
route: {
type: Object,
default: () => undefined
}
})
const emit = defineEmits(['onSelect', 'onOpenChange', 'menuIsCollapseClick', 'switchModule'])
const onSelect = (obj) => {
emit('onSelect', obj)
}
//
const onOpenChange = (keys) => {
emit('onOpenChange', keys)
}
//
const switchModule = (id) => {
emit('switchModule', id)
}
const menuIsCollapseClick = () => {
emit('menuIsCollapseClick')
}
</script>

View File

@ -0,0 +1,189 @@
<template>
<a-layout>
<a-layout-sider v-if="!isMobile" width="80" :theme="sideTheme" :trigger="null" collapsible>
<header id="snowyHeaderLogo" class="snowy-header-logo">
<div class="snowy-header-left">
<div class="logo-bar">
<router-link to="/">
<img class="logo" :title="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
</router-link>
</div>
</div>
</header>
<a-menu v-model:selectedKeys="doublerowSelectedKey" :theme="sideTheme" class="snowy-doublerow-layout-menu">
<a-menu-item
v-for="item in menu"
:key="item.path"
style="
text-align: center;
border-radius: 2px;
height: auto;
line-height: 20px;
flex: none;
display: block;
padding: 12px 0 !important;
"
@click="showMenu(item)"
>
<a v-if="item.meta && item.meta.type === 'link'" :href="item.path" target="_blank" @click.stop="() => {}"></a>
<template #icon>
<component :is="item.meta.icon" style="padding-left: 10px" />
</template>
<div class="snowy-doublerow-layout-menu-item-fort-div">
<span class="snowy-doublerow-layout-menu-item-fort-div-span">
{{ item.meta.title }}
</span>
</div>
</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout-sider
v-if="!isMobile"
v-show="layoutSiderDowbleMenu"
v-model:collapsed="menuIsCollapse"
:trigger="null"
width="170"
collapsible
:theme="secondMenuSideTheme"
>
<div v-if="!menuIsCollapse" id="snowyDoublerowSideTop" class="snowy-doublerow-side-top">
<h2 class="snowy-title">{{ pMenu.meta.title }}</h2>
</div>
<a-menu
v-model:collapsed="menuIsCollapse"
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
mode="inline"
:theme="secondMenuSideTheme"
@select="onSelect"
>
<NavMenu :nav-menus="nextMenu" />
</a-menu>
</a-layout-sider>
<!-- 手机端情况下的左侧菜单 -->
<Side-m v-if="isMobile" />
<a-layout>
<div id="snowyHeader" class="snowy-header">
<div class="snowy-header-left" style="padding-left: 0px">
<moduleMenu @switchModule="switchModule" />
<top-bar v-if="!isMobile && breadcrumbOpen" />
</div>
<div class="snowy-header-right">
<user-bar />
</div>
</div>
<!-- 多标签 -->
<Tags v-if="!isMobile && layoutTagsOpen"></Tags>
<a-layout-content class="main-content-wrapper">
<div id="admin-ui-main" class="admin-ui-main">
<router-view v-slot="{ Component }">
<keep-alive :include="keepLiveRoute">
<component :is="Component" v-if="routeShow" :key="route.name" />
</keep-alive>
</router-view>
<iframe-view />
<div class="main-bottom-wrapper">
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
sysBaseConfig.SNOWY_SYS_COPYRIGHT
}}</a>
</div>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script setup name="doublerowLayout">
import UserBar from '@/layout/components/userbar.vue'
import Tags from '@/layout/components/tags.vue'
import SideM from '@/layout/components/sideM.vue'
import NavMenu from '@/layout/components/NavMenu.vue'
import ModuleMenu from '@/layout/components/moduleMenu.vue'
import IframeView from '@/layout/components/iframeView.vue'
import TopBar from '@/layout/components/topbar.vue'
const props = defineProps({
isMobile: {
type: Boolean,
default: () => false
},
menuIsCollapse: {
type: Boolean,
default: () => false
},
sideTheme: {
type: String,
default: () => ''
},
sysBaseConfig: {
type: Object,
default: () => undefined
},
openKeys: {
type: Array,
default: () => []
},
selectedKeys: {
type: Array,
default: () => []
},
menu: {
type: Array,
default: () => []
},
breadcrumbOpen: {
type: Boolean,
default: () => false
},
layoutTagsOpen: {
type: Boolean,
default: () => false
},
keepLiveRoute: {
type: Array,
default: () => []
},
routeShow: {
type: Boolean,
default: () => false
},
route: {
type: Object,
default: () => undefined
},
layoutSiderDowbleMenu: {
type: Boolean,
default: () => true
},
secondMenuSideTheme: {
type: String,
default: () => undefined
},
nextMenu: {
type: Array,
default: () => []
},
doublerowSelectedKey: {
type: Array,
default: () => []
},
pMenu: {
type: Object,
default: () => undefined
}
})
const emit = defineEmits(['onSelect', 'showMenu', 'onOpenChange', 'menuIsCollapseClick', 'switchModule'])
const onSelect = (obj) => {
emit('onSelect', obj)
}
const showMenu = (route) => {
emit('showMenu', route)
}
const menuIsCollapseClick = () => {
emit('menuIsCollapseClick')
}
//
const switchModule = (id) => {
emit('switchModule', id)
}
</script>

View File

@ -12,7 +12,7 @@ import { nextTick } from 'vue'
import { viewTagsStore } from '@/store' import { viewTagsStore } from '@/store'
export function beforeEach(to, from) { export function beforeEach(to, from) {
const adminMain = document.querySelector('#adminui-main') const adminMain = document.querySelector('#admin-ui-main')
if (!adminMain) { if (!adminMain) {
return false return false
} }
@ -24,7 +24,7 @@ export function beforeEach(to, from) {
} }
export function afterEach(to) { export function afterEach(to) {
const adminMain = document.querySelector('#adminui-main') const adminMain = document.querySelector('#admin-ui-main')
if (!adminMain) { if (!adminMain) {
return false return false
} }

View File

@ -34,7 +34,7 @@ export const globalStore = defineStore({
id: 'global', id: 'global',
state: () => ({ state: () => ({
// 移动端布局 // 移动端布局
ismobile: false, isMobile: false,
// 布局 // 布局
layout: getCacheConfig('SNOWY_LAYOUT'), layout: getCacheConfig('SNOWY_LAYOUT'),
// 菜单是否折叠 toggle // 菜单是否折叠 toggle
@ -46,9 +46,9 @@ export const globalStore = defineStore({
// 是否展示面包屑 // 是否展示面包屑
breadcrumbOpen: getCacheConfig('SNOWY_BREADCRUMD_OPEN'), breadcrumbOpen: getCacheConfig('SNOWY_BREADCRUMD_OPEN'),
// 顶栏是否应用主题色 // 顶栏是否应用主题色
topHanderThemeColorOpen: getCacheConfig('SNOWY_TOP_HANDER_THEME_COLOR_OPEN'), topHeaderThemeColorOpen: getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_OPEN'),
// 顶栏主题色通栏 // 顶栏主题色通栏
topHanderThemeColorSpread: getCacheConfig('SNOWY_TOP_HANDER_THEME_COLOR_SPREAD'), topHeaderThemeColorSpread: getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD'),
// 模块坞 // 模块坞
moduleUnfoldOpen: getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'), moduleUnfoldOpen: getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'),
// 主题 // 主题
@ -60,12 +60,14 @@ export const globalStore = defineStore({
// 用户信息 // 用户信息
userInfo: toolDataGet('USER_INFO') || {}, userInfo: toolDataGet('USER_INFO') || {},
// 系统配置 // 系统配置
sysBaseConfig: toolDataGet('SNOWY_SYS_BASE_CONFIG') || config.SYS_BASE_CONFIG sysBaseConfig: toolDataGet('SNOWY_SYS_BASE_CONFIG') || config.SYS_BASE_CONFIG,
// 默认应用
module: getCacheConfig('SNOWY_MENU_MODULE_ID')
}), }),
getters: {}, getters: {},
actions: { actions: {
setIsmobile(key) { setIsMobile(key) {
this.ismobile = key this.isMobile = key
}, },
setLayout(key) { setLayout(key) {
this.layout = key this.layout = key
@ -95,6 +97,9 @@ export const globalStore = defineStore({
}, },
setSysBaseConfig(key) { setSysBaseConfig(key) {
this.sysBaseConfig = key this.sysBaseConfig = key
},
setModule(key) {
this.module = key
} }
} }
}) })

View File

@ -33,20 +33,20 @@ a, button, input, textarea {
} }
/* 大布局样式 */ /* 大布局样式 */
.aminui { .admin-ui {
overflow: hidden; overflow: hidden;
height: 100vh; height: 100%;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
} }
.aminui-wrapper { .admin-ui-wrapper {
display: flex; display: flex;
flex: 1; flex: 1;
overflow: auto; overflow: auto;
} }
.adminui-main { .admin-ui-main {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
@ -222,16 +222,16 @@ a, button, input, textarea {
} }
/* 面包屑 */ /* 面包屑 */
.adminui-topbar { .admin-ui-topbar {
padding-left: 15px padding-left: 15px
} }
.adminui-topbar .left-panel { .admin-ui-topbar .left-panel {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.adminui-topbar .right-panel { .admin-ui-topbar .right-panel {
display: flex; display: flex;
align-items: center; align-items: center;
} }
@ -363,7 +363,7 @@ a, button, input, textarea {
} }
/*页面最大化*/ /*页面最大化*/
.aminui.main-maximize { .admin-ui.main-maximize {
.main-maximize-exit { .main-maximize-exit {
display: block; display: block;
} }
@ -436,9 +436,10 @@ a, button, input, textarea {
// 滚动条需要哪里加哪个class // 滚动条需要哪里加哪个class
body, body,
.ant-scrolling-effect,
.ant-drawer-wrapper-body, .ant-drawer-wrapper-body,
.ant-drawer-body, .ant-drawer-body,
.aminui, .admin-ui,
.ant-modal-wrap, .ant-modal-wrap,
.ant-transfer-list-content, .ant-transfer-list-content,
.ant-card, .ant-card,
@ -460,7 +461,7 @@ body,
.gen-preview-content, .gen-preview-content,
.ant-menu, .ant-menu,
.adminui-main{ .admin-ui-main{
&::-webkit-scrollbar { &::-webkit-scrollbar {
/*滚动条整体样式*/ /*滚动条整体样式*/
width : 0px; /*高宽分别对应横竖滚动条的尺寸*/ width : 0px; /*高宽分别对应横竖滚动条的尺寸*/

View File

@ -26,7 +26,7 @@
margin-left: 0px !important; margin-left: 0px !important;
} }
.adminui-main { .admin-ui-main {
> .el-container { > .el-container {
display: block; display: block;
height: auto; height: auto;
@ -84,43 +84,43 @@
} }
} }
.adminui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) { .admin-ui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) {
border: 0; border: 0;
margin-top: 0; margin-top: 0;
} }
.adminui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) + .el-aside { .admin-ui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) + .el-aside {
margin-top: 0; margin-top: 0;
} }
.adminui-main > .el-container > .el-aside { .admin-ui-main > .el-container > .el-aside {
border-bottom: 1px solid #ebeef5 !important; border-bottom: 1px solid #ebeef5 !important;
} }
.adminui-main > .el-container > .el-container { .admin-ui-main > .el-container > .el-container {
border-top: 1px solid #ebeef5; border-top: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
margin-top: 15px; margin-top: 15px;
} }
.adminui-main > .el-container > .el-header { .admin-ui-main > .el-container > .el-header {
@extend . headerPublic; @extend . headerPublic;
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
} }
.adminui-main > .el-container > .el-main { .admin-ui-main > .el-container > .el-main {
border-top: 1px solid #ebeef5; border-top: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
margin-top: 15px; margin-top: 15px;
} }
.adminui-main > .el-container > .el-main + .el-aside { .admin-ui-main > .el-container > .el-main + .el-aside {
border-left: 0 !important; border-left: 0 !important;
border-top: 1px solid #ebeef5; border-top: 1px solid #ebeef5;
margin-top: 15px; margin-top: 15px;
} }
.adminui-main > .el-container > .el-container > .el-header { .admin-ui-main > .el-container > .el-container > .el-header {
@extend . headerPublic @extend . headerPublic
} }
} }