mirror of https://gitee.com/xiaonuobase/snowy
【更新】重写layout布局,为更多布局扩展更方便,顺手解决标签点击不切换应用的问题
parent
e6f4ee7f4d
commit
d00dd22a29
|
@ -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"/>
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {})
|
||||||
// 监听消息事件
|
// 监听消息事件
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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; /*高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue