Files
zhgh_whcp/target/classes/views/layouts/platform.html
T
2026-01-08 14:58:16 +08:00

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>
<!--#
}
#-->