2
This commit is contained in:
Anfioo
2025-12-18 18:54:48 +08:00
parent 080084b356
commit 727d6a3a54
51 changed files with 207 additions and 92 deletions

View File

@@ -1,19 +1,21 @@
<div class="vc-menu flex justify-start" id="menu-nav"> <!--顶部的logo是在nav2里面声明的-->
<div class="vc-menu flex justify-start" id="menu-nav" style="position: relative; overflow: visible;">
<div class="vc-menu-main"> <div class="vc-menu-main">
<ul> <ul>
<li v-for="menu in menus" v-bind:class="{ active: menu.active }" v-if="menu.childs != undefined && menu.childs.length >0" v-on:click="switchMenu(menu)"> <!-- <li class="title"><a href="/">{{logo}}</a></li>-->
<i class="fa " v-bind:class="menu.icon"></i><span class="margin-left-xs">{{vc.i18n(menu.name)}}</span> <li v-for="menu in menus" v-bind:class="{ active: menu.active }" v-if="menu.childs != undefined && menu.childs.length >0" @mouseenter="hoverMenu(menu)" @mouseleave="leaveMenu">
<i class="fa " v-bind:class="menu.icon"></i>
<span class="margin-left-xs">{{vc.i18n(menu.name)}}</span>
</li> </li>
</ul> </ul>
</div> </div>
<div class="vc-menu-sub" v-if="subMenus && subMenus.length > 0"> <div class="vc-menu-sub flyout" v-if="subMenus && subMenus.length > 0" @mouseenter="keepMenuOpen" @mouseleave="leaveMenu">
<ul> <ul>
<li class="title">{{curMenuName}}</li> <li class="title">{{curMenuName}}</li>
<li v-for="subMenu in subMenus" v-if="subMenu.isShow == 'Y'" v-bind:class="{ active: subMenu.active }" v-on:click="_gotoPage(subMenu.href,subMenu.name)"> <li v-for="subMenu in subMenus" v-if="subMenu.isShow == 'Y'" v-bind:class="{ active: subMenu.active }" @click.stop="_gotoPage(subMenu.href, subMenu.name)">
{{vc.i18n(subMenu.name)}} {{vc.i18n(subMenu.name)}}
</li> </li>
<li class="sub-footer" @click="_closeSubMenu()"><i class="fa fa-dedent"></i></li> <!-- <li class="sub-footer" @click="_closeSubMenu()"><i class="fa fa-dedent"></i></li>-->
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -19,15 +19,35 @@
vm.subMenus = []; vm.subMenus = [];
vm.getMenus(_param.detail); vm.getMenus(_param.detail);
}, false); }, false);
// 点击页面空白处自动关闭二级菜单
document.addEventListener('click', (e) => {
const menuNav = document.getElementById('menu-nav'); // 整个菜单区域(包含一级和二级)
const flyoutMenu = document.querySelector('.vc-menu-sub.flyout');
// 如果点击的是菜单区域内部(一级菜单或二级菜单),不关闭
if (menuNav && menuNav.contains(e.target)) {
return;
}
// 点击的是页面其他地方 → 关闭二级菜单
if (flyoutMenu && flyoutMenu.classList.contains('active')) {
this._closeSubMenu();
}
});
}, },
methods: { methods: {
_initSysInfo: function () { _initSysInfo: function () {
let sysInfo = vc.getData("_sysInfo"); let sysInfo = vc.getData("java110SystemInfo");
if (sysInfo == null) { let _that = this;
this.logo = "HC"; if (!sysInfo) {
setTimeout(function () {
sysInfo = vc.getData("java110SystemInfo");
_that.logo = sysInfo.systemSimpleTitle;
}, 2000);
return; return;
} }
this.logo = sysInfo.logo; this.logo = sysInfo.systemSimpleTitle;
}, },
_gotoIndex: function() { _gotoIndex: function() {
vc.jumpToPage("/") vc.jumpToPage("/")
@@ -93,6 +113,38 @@
vm.subMenus = _menu.childs; vm.subMenus = _menu.childs;
vm.curMenuName = _menu.name; vm.curMenuName = _menu.name;
// 二级菜单样式调整
vm.$nextTick(() => {
const activeItem = document.querySelector('.vc-menu-main li.active');
const flyoutMenu = document.querySelector('.vc-menu-sub.flyout');
const mainMenu = document.querySelector('.vc-menu-main'); // 一级菜单容器
if (activeItem && flyoutMenu && mainMenu) {
const itemTop = activeItem.offsetTop;
const itemHeight = activeItem.offsetHeight;
const menuHeight = flyoutMenu.offsetHeight;
const mainMenuRect = mainMenu.getBoundingClientRect();
const availableBottom = mainMenuRect.bottom - 20; // 距离视口底部留20px边距
// 理想位置:垂直居中对齐当前项
let desiredTop = itemTop + (itemHeight - menuHeight) / 2;
// 限制:不能超出顶部
if (desiredTop < 10) {
desiredTop = 10;
}
// 限制:底部不能超过一级菜单可见底部
const maxTop = window.innerHeight - menuHeight - 60; // 留出顶部导航和底部安全距
if (desiredTop > maxTop) {
desiredTop = maxTop;
}
flyoutMenu.style.top = desiredTop + 'px';
flyoutMenu.classList.add('active');
}
});
if (!_menu.childs || _menu.childs.length < 1) { if (!_menu.childs || _menu.childs.length < 1) {
return; return;
} }
@@ -147,7 +199,61 @@
vm.menus.forEach(item => { vm.menus.forEach(item => {
item.active = false; item.active = false;
}); });
},
// 新增:鼠标进入一级菜单项
hoverMenu: function(_menu) {
// 高亮当前一级菜单
this.menus = this.refreshMenuActive(this.menus, _menu.id);
vc.setMenus(this.menus);
// 显示对应的二级菜单
this.subMenus = _menu.childs || [];
this.curMenuName = _menu.name;
// Vue渲染完成后定位并显示二级菜单
this.$nextTick(() => {
const hoveredItem = document.querySelector('.vc-menu-main li.active');
const flyoutMenu = document.querySelector('.vc-menu-sub.flyout');
if (hoveredItem && flyoutMenu) {
const itemTop = hoveredItem.offsetTop;
const itemHeight = hoveredItem.offsetHeight;
const menuHeight = flyoutMenu.offsetHeight;
// 垂直居中对齐当前项
let desiredTop = itemTop + (itemHeight - menuHeight) / 2;
if (desiredTop < 10) desiredTop = 10;
const maxTop = window.innerHeight - menuHeight - 60;
if (desiredTop > maxTop) desiredTop = maxTop;
flyoutMenu.style.top = desiredTop + 'px';
flyoutMenu.classList.add('active');
} }
});
},
// 新增:鼠标离开一级菜单项时隐藏二级菜单
leaveMenu: function() {
// 延迟隐藏,防止鼠标快速移到二级菜单时闪烁
setTimeout(() => {
const flyoutMenu = document.querySelector('.vc-menu-sub.flyout');
const menuNav = document.getElementById('menu-nav');
// 如果鼠标当前不在整个菜单区域内,才关闭
if (flyoutMenu && menuNav && !menuNav.matches(':hover')) {
this.subMenus = [];
this.curMenuName = '';
this.menus.forEach(item => item.active = false);
flyoutMenu.classList.remove('active');
}
}, 200); // 200ms 延迟,给用户时间把鼠标移到二级菜单上
},
// 鼠标在二级菜单上时保持打开
keepMenuOpen: function() {
// 可以什么都不做,只是阻止 leaveMenu 的定时器触发关闭
// 实际通过 :hover 判断已足够
},
}, },
}); });

View File

@@ -1,8 +1,14 @@
<div class="vc-nav flex justify-between" id="nav"> <div class="vc-nav flex justify-between" id="nav" style="position: relative;">
<!-- 顶部 logo 容器:复用侧边栏 logo 样式类 + 背景色 -->
<div class="vc-nav-logo vc-menu-main title">
<ul>
<li class="title"><a href="/">{{logo}}</a></li>
</ul>
</div>
<!-- 原顶部内容容器:整体右移,保持原有布局 -->
<div class="vc-nav-content flex justify-between w-full">
<div> <div>
<ul class="flex flex-start"> <ul class="flex flex-start">
<!-- <li class="title"><a href="/">{{vc.i18n('systemName')}}</a></li> -->
<li class="title"><a href="/">{{logo}}</a></li>
<li :class="{'active' :item.active == '1' }" v-for="(item,index) in nav.catalogs" @click="_changeMenuCatalog(item)" v-if="!item.privId || vc.hasPrivilege(item.privId)"> <li :class="{'active' :item.active == '1' }" v-for="(item,index) in nav.catalogs" @click="_changeMenuCatalog(item)" v-if="!item.privId || vc.hasPrivilege(item.privId)">
<i :class="item.icon"></i>{{item.name}} <i :class="item.icon"></i>{{item.name}}
</li> </li>
@@ -47,3 +53,4 @@
</ul> </ul>
</div> </div>
</div> </div>
</div>

View File

@@ -237,13 +237,13 @@
<vc:i18n name="扫码收费" namespace="payFeeOrder"></vc:i18n> <vc:i18n name="扫码收费" namespace="payFeeOrder"></vc:i18n>
</button> </button>
<button type="button" <!-- <button type="button"-->
class="btn btn-lg btn-block" <!-- class="btn btn-lg btn-block"-->
style="background-color: #00cdd4; border-color: #00cdd4; color: white;" <!-- style="background-color: #00cdd4; border-color: #00cdd4; color: white;"-->
v-if="payFeeOrderInfo.primeRate == '9' " <!-- v-if="payFeeOrderInfo.primeRate == '9' "-->
@click="_openPayFee('qrCode')"> <!-- @click="_openPayFee('qrCode')">-->
<vc:i18n name="扫码收费" namespace="payFeeOrder"></vc:i18n> <!-- <vc:i18n name="扫码收费" namespace="payFeeOrder"></vc:i18n>-->
</button> <!-- </button>-->
</div> </div>

View File

@@ -1,2 +1,2 @@
<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>业主家园</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)')) <!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>业主家园</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/static/index.ed4a2d2b.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/static/js/chunk-vendors.e5157221.js></script><script src=/static/js/index.9983b0c6.js></script></body></html> document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/static/index.ed4a2d2b.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/static/js/chunk-vendors.e5157221.js></script><script src=/static/js/index.d45760b4.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long