508 lines
16 KiB
HTML
508 lines
16 KiB
HTML
<!--#
|
|
layout("/layouts/v4/baseLayout.html"){
|
|
#-->
|
|
|
|
<style>
|
|
.sub-app-container {
|
|
margin: 0 auto;
|
|
background: #fff;
|
|
display: flex;
|
|
overflow: hidden;
|
|
min-height: calc(100vh - 64px);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.sidebar-menu {
|
|
width: 250px;
|
|
background: rgb(35 85 120);
|
|
color: #fff;
|
|
flex-shrink: 0;
|
|
height: calc(100vh - 64px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.menu-header {
|
|
padding: 20px;
|
|
background: rgba(0, 0, 0, 0.1);
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.menu-title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
}
|
|
|
|
#sidebar-menu .el-scrollbar {
|
|
flex: 1;
|
|
}
|
|
|
|
#sidebar-menu .el-scrollbar .el-scrollbar__wrap {
|
|
overflow-x: hidden;
|
|
margin-bottom: 0 !important;
|
|
}
|
|
|
|
#sidebar-menu .el-menu {
|
|
background: transparent;
|
|
border: none;
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-submenu__title {
|
|
color: #ffffff;
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-submenu__title i,
|
|
#sidebar-menu .el-menu .el-menu-item i {
|
|
color: inherit;
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-submenu__title:hover {
|
|
background: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-menu-item {
|
|
color: inherit;
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-menu-item.is-active {
|
|
background: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-menu-item:focus,
|
|
.el-menu-item:hover {
|
|
background: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
#sidebar-menu .el-menu .el-menu-item a {
|
|
text-decoration: none;
|
|
color: inherit;
|
|
display: inline-block;
|
|
width: 100%;
|
|
}
|
|
|
|
.sub-app-container-main-content {
|
|
flex: 1;
|
|
padding: 10px;
|
|
background: #f6f6f6;
|
|
box-sizing: border-box;
|
|
overflow: auto;
|
|
height: calc(100vh - 64px);
|
|
}
|
|
|
|
.content-header {
|
|
margin-bottom: 30px;
|
|
padding-bottom: 20px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.content-title {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
color: #2c3e50;
|
|
margin: 0;
|
|
}
|
|
|
|
.content-subtitle {
|
|
color: #7f8c8d;
|
|
margin-top: 5px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.content-body {
|
|
min-height: 400px;
|
|
height: 100%;
|
|
}
|
|
|
|
|
|
/* 悬浮菜单按钮样式 */
|
|
.menu-toggle-btn {
|
|
display: none;
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
width: 50px;
|
|
height: 50px;
|
|
border-radius: 50%;
|
|
background-color: rgb(64 109 157);
|
|
color: white;
|
|
text-align: center;
|
|
line-height: 50px;
|
|
font-size: 24px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
z-index: 1000;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.menu-toggle-btn:hover {
|
|
background-color: rgb(54 99 147);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.menu-toggle-btn.active {
|
|
background-color: #d9534f;
|
|
}
|
|
|
|
/* 菜单遮罩层样式 */
|
|
.menu-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
z-index: 998;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.sidebar-menu {
|
|
position: fixed;
|
|
top: 64px;
|
|
left: -100%;
|
|
width: 40%;
|
|
z-index: 999;
|
|
transition: left 0.3s ease;
|
|
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.sidebar-menu.show {
|
|
left: 0;
|
|
}
|
|
|
|
.menu-toggle-btn {
|
|
display: block;
|
|
}
|
|
|
|
.menu-overlay.show {
|
|
display: block;
|
|
}
|
|
|
|
.main-content {
|
|
padding: 20px;
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="sub-app-container" id="sub-app-container">
|
|
<!-- 菜单遮罩层 -->
|
|
<div class="menu-overlay" id="menu-overlay"></div>
|
|
|
|
<!-- 左侧菜单区域 -->
|
|
<nav class="sidebar-menu" id="sidebar-menu">
|
|
<div class="menu-header">
|
|
<h2 class="menu-title">子系统</h2>
|
|
</div>
|
|
|
|
<el-scrollbar>
|
|
<el-menu unique-opened :default-active="activeMenuIndex" :default-openeds="openedMenus"
|
|
@select="menuSelect">
|
|
<menu-list :menus="leftMenus" :depth="0"></menu-list>
|
|
</el-menu>
|
|
</el-scrollbar>
|
|
</nav>
|
|
|
|
<!-- 右侧主体区域 -->
|
|
<main class="sub-app-container-main-content" id="sub-app-container-main-content">
|
|
<div class="content-body" id="sub-app-container-main-content-body">${layoutContent!}</div>
|
|
</main>
|
|
|
|
<!-- 悬浮菜单按钮 -->
|
|
<div class="menu-toggle-btn" id="menu-toggle-btn">
|
|
<i class="fa fa-bars"></i>
|
|
</div>
|
|
|
|
<!-- 子应用ID -->
|
|
<div id="sub-app-id" style="display: none"></div>
|
|
</div>
|
|
|
|
<script nonce="${cspNonce!}">
|
|
// 初始化pjax加载
|
|
;(function initPjax() {
|
|
$(document).pjax("#sidebar-menu a[data-pjax]", "#sub-app-container-main-content-body", {
|
|
maxCacheLength: 0,
|
|
push: true,
|
|
replace: false,
|
|
fragment: "#sub-app-container-main-content-body",
|
|
timeout: 8000
|
|
})
|
|
|
|
$(document).on("pjax:send", function () {
|
|
NProgress.configure({parent: ".sub-app-container-main-content"})
|
|
NProgress.start()
|
|
$("#sub-app-container-main-content").hide()
|
|
})
|
|
|
|
$(document).on("pjax:complete", function () {
|
|
NProgress.done()
|
|
$("#sub-app-container-main-content").show()
|
|
})
|
|
|
|
|
|
try {
|
|
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
|
$("#sub-app-container #sidebar-menu .menu-header .menu-title").text(app?.name)
|
|
} catch (e) {
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
new Vue({
|
|
el: "#sidebar-menu",
|
|
components: {
|
|
"menu-list": {
|
|
name: "menu-list",
|
|
template:
|
|
/*language=HTML*/
|
|
`
|
|
<div>
|
|
<template v-for="(item, index) in menus">
|
|
<el-submenu :index="item.id" v-if="item.children && item.children.length > 0">
|
|
<template #title>
|
|
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
|
<i v-else class="el-icon-paperclip"></i>
|
|
<span>{{ item.name }}</span>
|
|
</template>
|
|
<menu-list :menus="item.children" :depth="depth + 1"/>
|
|
</el-submenu>
|
|
<el-menu-item :index="item.id" v-else>
|
|
<a :href="item.href" data-pjax>
|
|
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
|
<i v-else :class="item.icon ? item.icon : 'el-icon-menu'"></i>
|
|
<span>{{ item.name }}</span>
|
|
</a>
|
|
</el-menu-item>
|
|
</template>
|
|
</div>
|
|
`,
|
|
props: ["menus", "depth"]
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
// 菜单数据
|
|
menus: [],
|
|
// 当前激活的菜单索引
|
|
activeMenuIndex: null,
|
|
// 当前打开的菜单索引
|
|
openedMenus: [],
|
|
// 默认选中菜单是否加载中
|
|
defaultSelectLoading: true
|
|
}
|
|
},
|
|
computed: {
|
|
leftMenus() {
|
|
if (this.menus) {
|
|
return this.menus
|
|
} else {
|
|
try {
|
|
return JSON.parse(window.sessionStorage.getItem("zhgh_sub_app_menus"))
|
|
} catch (e) {
|
|
return []
|
|
}
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
menuSelect(index, indexPath) {
|
|
try {
|
|
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
|
window.sessionStorage.setItem("zhgh_sub_app_left_menu_active_index-" + app.id, index)
|
|
window.sessionStorage.setItem("zhgh_sub_app_left_menu_opens-" + app.id, JSON.stringify(indexPath))
|
|
} catch (e) {
|
|
}
|
|
},
|
|
// 获取菜单
|
|
getMenus(appId) {
|
|
if (!appId) return
|
|
this.$axios.post("/platform/sys/user/subAppMenus", {appId}).then((res) => {
|
|
if (res.code === 0) {
|
|
this.menus = res.data
|
|
window.sessionStorage.setItem("zhgh_sub_app_menus", JSON.stringify(res.data))
|
|
this.echoMenus()
|
|
} else {
|
|
this.menus = []
|
|
}
|
|
})
|
|
},
|
|
|
|
// 设置应用信息
|
|
setAppInfo(app) {
|
|
if (app) {
|
|
// 储存到缓存
|
|
window.sessionStorage.setItem("zhgh_sub_app", JSON.stringify(app))
|
|
// 储存到div中
|
|
document.getElementById("sub-app-id").innerText = app.id
|
|
try {
|
|
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
|
$("#sub-app-container #sidebar-menu .menu-header .menu-title").text(app?.name)
|
|
} catch (e) {
|
|
|
|
}
|
|
}
|
|
},
|
|
// 菜单回显
|
|
echoMenus() {
|
|
try {
|
|
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
|
this.activeMenuIndex = window.sessionStorage.getItem("zhgh_sub_app_left_menu_active_index-" + app.id)
|
|
this.openedMenus = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app_left_menu_opens-" + app.id)) || []
|
|
|
|
// !this.activeMenuIndex &&
|
|
if ('/platform/v4/subApp' === getBaseSubAppPath()) {
|
|
this.defaultSelect()
|
|
} else {
|
|
this.hrefSelect()
|
|
}
|
|
|
|
} catch (e) {
|
|
}
|
|
},
|
|
|
|
// 地址选中
|
|
hrefSelect() {
|
|
function findMenuPath(menus, targetHref) {
|
|
function search(items, path) {
|
|
for (const item of items) {
|
|
// 如果当前项匹配 href,返回路径(包含自己)
|
|
if (item.href === targetHref) {
|
|
return [...path, item];
|
|
}
|
|
// 如果有子菜单,递归查找
|
|
if (item.children?.length) {
|
|
const result = search(item.children, [...path, item]);
|
|
if (result) return result;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
return search(menus, []);
|
|
}
|
|
|
|
const result = findMenuPath(this.menus, window.location.pathname)
|
|
if(result){
|
|
this.activeMenuIndex = result[result.length-1]['id']
|
|
this.openedMenus = result.map(v=>v.id)
|
|
|
|
this.$nextTick(() => {
|
|
this.menuSelect(this.activeMenuIndex, this.openedMenus)
|
|
})
|
|
}
|
|
},
|
|
|
|
|
|
// 默认选中
|
|
defaultSelect() {
|
|
// 查找第一个有href的子菜单
|
|
function findFirstChildWithHref(menus) {
|
|
for (const menu of menus) {
|
|
// 如果当前菜单有href,返回它
|
|
if (menu.href) {
|
|
return {
|
|
menu: menu,
|
|
parentIds: [menu.parentId]
|
|
};
|
|
}
|
|
|
|
// 如果有子菜单,递归查找
|
|
if (menu.children && menu.children.length > 0) {
|
|
const result = findFirstChildWithHref(menu.children);
|
|
if (result) {
|
|
// 添加当前菜单的ID到父ID集合
|
|
result.parentIds.push(menu.id);
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const result = findFirstChildWithHref(this.menus)
|
|
if (result) {
|
|
this.activeMenuIndex = result.menu.id
|
|
this.openedMenus = result.parentIds
|
|
this.$nextTick(() => {
|
|
this.menuSelect(this.activeMenuIndex, this.openedMenus)
|
|
// 使用pjax跳转
|
|
commonUtil.pjaxPush(getBaseSubAppPath(result.menu.href))
|
|
|
|
/*const tempLink = document.createElement('a')
|
|
tempLink.href = result.menu.href
|
|
tempLink.setAttribute('data-pjax', '')
|
|
tempLink.style.display = 'none'
|
|
document.body.appendChild(tempLink)
|
|
tempLink.click()
|
|
document.body.removeChild(tempLink)*/
|
|
})
|
|
}
|
|
},
|
|
|
|
init() {
|
|
// 页面加载时获取到正确的菜单
|
|
const pathname = window.location.pathname
|
|
if (!pathname.startsWith("/platform/v4/subApp")) {
|
|
const path = getFullSubAppPath()
|
|
this.$axios.post("/platform/sys/user/rootMenuByPath", {pathname: path}).then((res) => {
|
|
if (res.code === 0) {
|
|
this.setAppInfo(res.data)
|
|
this.getMenus(res.data?.id)
|
|
}
|
|
})
|
|
} else {
|
|
const appId = GetQueryString("appId")
|
|
if (!appId) return
|
|
this.getMenus(appId)
|
|
}
|
|
},
|
|
|
|
},
|
|
mounted() {
|
|
this.init()
|
|
|
|
|
|
// 移动端布局
|
|
const sidebarMenu = document.getElementById("sidebar-menu")
|
|
const menuToggleBtn = document.getElementById("menu-toggle-btn")
|
|
const menuOverlay = document.getElementById("menu-overlay")
|
|
|
|
// 初始化菜单状态
|
|
if (window.innerWidth <= 768) {
|
|
menuToggleBtn.style.display = "block"
|
|
} else {
|
|
menuToggleBtn.style.display = "none"
|
|
}
|
|
|
|
// 菜单按钮点击事件
|
|
menuToggleBtn.addEventListener("click", function () {
|
|
sidebarMenu.classList.toggle("show")
|
|
menuOverlay.classList.toggle("show")
|
|
})
|
|
|
|
|
|
// 遮罩层点击事件
|
|
menuOverlay.addEventListener("click", function () {
|
|
sidebarMenu.classList.remove("show")
|
|
menuOverlay.classList.remove("show")
|
|
})
|
|
|
|
window.addEventListener("resize", function () {
|
|
if (window.innerWidth <= 768) {
|
|
menuToggleBtn.style.display = "block"
|
|
} else {
|
|
menuToggleBtn.style.display = "none"
|
|
sidebarMenu.classList.remove("show")
|
|
menuOverlay.classList.remove("show")
|
|
}
|
|
})
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<!--#
|
|
}
|
|
#-->
|