txw/txw-mhzc-web/src/pages/index/components/nav/index2.vue

840 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 顶部菜单栏 -->
<div class="nav-box">
<div class="logo-box" @click="goHome">
<img src="@/pages/index/assets/logo-name.png">
</div>
<div class="menu-box">
<div v-for="(menu,index) in menuOptions" :key="index">
<t-dropdown v-if="menu.child" trigger="hover" :options="menu.child" @click="handleDropdownClick">
<div class="menu-title" :class="{'meun-title-active': curPage == menu.name ,'meun-title-disable':menu.disable}" @click="gotoIfreamPage(menu)">
<!-- <img v-if="menu.icon" :src="menu.icon" width="24px" height="24px" style="margin-right:10px"> -->
<span> {{menu.title}} </span>
</div>
</t-dropdown>
<div v-else class="menu-title" :class="{'meun-title-active': curPage == menu.name ,'meun-title-disable':menu.disable}" @click="gotoIfreamPage(menu)">
<!-- <img v-if="menu.icon" :src="menu.icon" width="24px" height="24px" style="margin-right:10px"> -->
<span> {{menu.title}} </span>
</div>
</div>
</div>
<div class="option-wrapper">
<div v-if="loginFlag" class="option-box">
<!-- <div class="gzt" @click="goyhzx">
<img src="@/pages/index/assets/home-gzt-icon.png" />
<span> 工作台</span>
</div> -->
<div style="margin-left:20px; cursor: pointer;" @click="goyhzx">企业工作台</div>
<div>|</div>
<div style="cursor: pointer;" @click="logoutHandler">退出登录</div>
</div>
<div v-else class="option-box">
<!-- <div class="gzt">
<img src="@/pages/index/assets/home-gzt-icon.png" />
<span> 工作台</span>
</div> -->
<!-- <div style="margin-left:20px; cursor: pointer;">激活</div>
<div>|</div> -->
<div style="cursor: pointer;" @click="gologin">登录</div>
</div>
</div>
<!-- 移动端汉堡菜单按钮 -->
<div class="hamburger-btn" @click="toggleMobileMenu">
<div :class="['hamburger-icon', { active: mobileMenuOpen }]">
<span></span>
<span></span>
<span></span>
</div>
</div>
<!-- 移动端菜单 -->
<div :class="['mobile-menu', { open: mobileMenuOpen }]">
<div class="mobile-menu-overlay" @click="toggleMobileMenu"></div>
<div class="mobile-menu-content">
<div class="mobile-menu-header">
<img src="@/pages/index/assets/logo-name.png">
<div class="close-btn" @click="toggleMobileMenu">×</div>
</div>
<div class="mobile-menu-list">
<div v-for="(menu, index) in menuOptions" :key="index">
<!-- 有子菜单的项 -->
<t-dropdown v-if="menu.child" trigger="click" :options="menu.child" @click="handleMobileDropdownClick">
<div class="mobile-menu-item" :class="{'active': curPage == menu.name}">
<img v-if="menu.icon" :src="menu.icon" width="20px" height="20px">
<span>{{ menu.title }}</span>
<img class="arrow" src="@/pages/index/assets/home-arrow-right.png" width="16px" height="16px">
</div>
</t-dropdown>
<!-- 无子菜单的项 -->
<div v-else class="mobile-menu-item" :class="{'active': curPage == menu.name, 'disable': menu.disable}" @click="gotoIfreamPage(menu)">
<img v-if="menu.icon" :src="menu.icon" width="20px" height="20px">
<span>{{ menu.title }}</span>
<img class="arrow" src="@/pages/index/assets/home-arrow-right.png" width="16px" height="16px">
</div>
</div>
</div>
<div class="mobile-menu-footer">
<div v-if="loginFlag" class="mobile-auth-btns">
<div class="mobile-auth-btn" @click="goyhzx">用户中心</div>
<div class="mobile-auth-btn logout" @click="logoutHandler">退出登录</div>
</div>
<div v-else class="mobile-auth-btns">
<div class="mobile-auth-btn activate">激活</div>
<div class="mobile-auth-btn login" @click="gologin">登录</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { logout, authorize, init } from '@/pages/index/api/login';
import api from '@/pages/index/api/gxzx/index.js';
export default {
name: 'Nav',
props: {
},
data() {
return {
curPage: "home",
loginFlag: false, //是否已完成登录
mobileMenuOpen: false, //移动端菜单是否展开
// 路由路径到菜单名的映射
routeToMenuMap: {
'/home': 'home',
'/fwsc': 'fwsc',
'/tfwsc': 'fwsc',
'/txqsc': 'fwsc',
'/tjrsc': 'fwsc',
'/tsjsc': 'fwsc',
'/yhzx': 'yhzx',
'/gxnlpt': 'gxnlpt',
'/qych': 'qych',
'/hyzt': 'hyzt',
'/login': 'login',
},
menuOptions: [
{
name: 'home',
title: '首页',
icon: require('@/pages/index/assets/nav-home.png'),
},
{
name: 'tzzx',
title: '碳证中心',
iframeUrl: 'https://ctn-web-pre.lingshu.net/carbon-index',
needLogin: true,
clientId: 'client_id_tfwzx',//单点登录接入子系统的标识由txw_sso_client表配置
child: [
{
name: 'tzcx',
title: '碳证查询',
value: 'tzcx', //菜单显示需要同name
content: '碳证查询', //菜单显示需要同title
divider: true, //是否显示子菜单分割线
needLogin: true, //是否需要登录才能访问
clientId: 'client_id_tfwzx',
iframeUrl: 'https://ctn-web-pre.lingshu.net/trustedCarbonQuery/index', //外部系统链接地址
// iframeUrl: 'https://ctn-web-pre.lingshu.net/trustedCarbonQuery/list?type=carbon-query', //外部系统链接地址
},
{
name: 'tsjfcg',
title: '碳数据防篡改',
value: 'tsjfcg',
content: '碳数据防篡改',
divider: true,
needLogin: true,
clientId: 'client_id_tfwzx',
iframeUrl: 'https://ctn-web-pre.lingshu.net/carbon-protection',
},
{
name: 'tzhy',
title: '碳证核验',
value: 'tzhy',
content: '碳证核验',
divider: true,
needLogin: true,
clientId: 'client_id_tfwzx',
iframeUrl: 'https://ctn-web-pre.lingshu.net/carbon-verify',
},
{
name: 'tgbcz',
title: '碳报告存证',
value: 'tgbcz',
content: '碳报告存证',
divider: true,
needLogin: true,
clientId: 'client_id_tfwzx',
iframeUrl: 'https://ctn-web-pre.lingshu.net/carbon-report-cert',
},
{
name: 'tbgtg',
title: '碳报告托管:',
value: 'tgbcz',
content: '碳报告托管',
divider: true,
needLogin: true,
clientId: 'client_id_tfwzx',
iframeUrl: 'https://ctn-web-pre.lingshu.net/carbon-report-hosting',
}
]
},
{
name: 'fwsc',
title: '服务中心',
child: [
{
name: 'tfwsc',
title: '碳服务市场',
value: 'tfwsc',
content: '碳服务市场',
divider: true,
},
{
name: 'tjrsc',
title: '碳金融市场',
value: 'tjrsc',
content: '碳金融市场',
divider: true,
parentName: 'fwsc',
},
{
name: 'txqsc',
title: '碳需求市场',
value: 'txqsc',
content: '碳需求市场',
divider: true,
},
{
name: 'tsjsc',
title: '碳数据市场',
value: 'tsjsc',
content: '碳数据市场',
divider: true,
},
// {
// name: 'fwscsjlbc',
// title: '数据列表',
// value: 'fwscsjlbc',
// content: '数据列表',
// divider: true,
// }
]
},
{
name: 'gxnlpt',
title: '共性能力',
// disable: true
},
{
name: 'qych',
title: '企业出海',
// disable: true
},
{
name: 'hyzt',
title: '行业专题',
// disable: true
},
]
};
},
created() {
// this.gettfwzxurl();
},
mounted() {
// this.gettfwzxurl();
console.log('newUrl', this.$route);
this.newUrl = this.$route.query.newUrl;
this.nowurl = this.newUrl || '/view/mhzc/home';
if (this.$route.name == 'yhzx') {
this.nowurl = '/yhzx';
}
if (this.$route.name == 'newsCenter') {
this.nowurl = '/yhzx';
}
const sfdl = window.sessionStorage.getItem('sfdl');
if (sfdl) {
this.loginFlag = true;
// this.getWdxxCount();
} else {
this.loginFlag = false;
}
// 初始化时根据当前路由更新菜单选中状态
this.updateCurPageByRoute();
},
watch: {
$route: {
handler() {
this.updateCurPageByRoute();
},
immediate: false,
},
},
beforeUnmount() { },
methods: {
// 切换移动端菜单
toggleMobileMenu() {
this.mobileMenuOpen = !this.mobileMenuOpen;
document.body.style.overflow = this.mobileMenuOpen ? 'hidden' : '';
},
// 关闭移动端菜单
closeMobileMenu() {
this.mobileMenuOpen = false;
document.body.style.overflow = '';
},
// 返回首页
goHome() {
this.$router.push('/home');
this.closeMobileMenu();
},
// 移动端子菜单点击
handleMobileDropdownClick(menu) {
this.handleDropdownClick(menu);
this.closeMobileMenu();
},
// 根据当前路由更新菜单选中状态
updateCurPageByRoute() {
const path = this.$route.path;
const routeName = this.$route.name;
// 优先精确匹配路径
if (this.routeToMenuMap[path]) {
this.curPage = this.routeToMenuMap[path];
return;
}
// 处理带query参数的路径如 /gxnlpt?anchor=content-1
const pathWithoutQuery = path.split('?')[0];
if (this.routeToMenuMap[pathWithoutQuery]) {
this.curPage = this.routeToMenuMap[pathWithoutQuery];
return;
}
// 尝试从路径中提取关键部分进行匹配
if (path.includes('tfwsc') || path.includes('txqsc') || path.includes('tjrsc') || path.includes('tsjsc')) {
this.curPage = 'fwsc';
return;
}
// 如果都匹配不到,默认选中首页
this.curPage = 'home';
},
//子菜单点击方法
handleDropdownClick(menu) {
this.gotoIfreamPage(menu); // 直接把子菜单项传入跳转方法
},
gotoIfreamPage(menu) {
console.log("当前菜单配置:", menu)
//判断页面是否开放
if (menu.disable) {
this.$dialog.alert({
header: '提示',
body: '该功能暂未开放。',
confirmBtn: null
})
return
}
//判断页面是否需要登录
console.log("当前页面是否需要登录:", menu.needLogin)
if (menu.needLogin) {
const sfdl = window.sessionStorage.getItem('sfdl'); //是否登录
console.log("是否已经登录登录:", sfdl)
if (!sfdl) {
this.$router.push("/login")
return
}
}
this.curPage = menu.name;
// 关闭移动端菜单
this.closeMobileMenu();
let iframeUrl = menu.iframeUrl;
if (iframeUrl) {
//调用login.js内的authorize方法
this.$emit('gotoIfreamPage', iframeUrl);
} else {
this.$emit('gotoPage', this.curPage);
}
},
gonewCenter() {
window.location.href = `/view/mhzc/yhzx?activeCompo=ggwhgl`;
},
async getWdxxCount() {
try {
// const res = await getMxjbxx(prame);
const { data } = await api.getWdxxCount();
this.xxtxCount = data;
console.log('res', data);
} catch (error) {
this.xxtxCount = 0;
console.error('数据加载失败', error);
}
},
async gettfwzxurl() {
try {
// const res = await getMxjbxx(prame);
const { data } = await api.tfwzxurl();
this.kxurl = data.kxtfwzx;
console.log('res', data);
} catch (error) {
console.error('数据加载失败', error);
}
},
gologin() {
this.closeMobileMenu();
this.$router.push("/login")
// window.location.href = `/view/mhzc/login`;
},
goyhzx() {
this.curPage = ""; //进入工作台之后nav菜单取消active
this.closeMobileMenu();
this.$router.push("/yhzx/gzt")
// window.location.href = `/view/mhzc/yhzx`;
},
goSelfChange(menuParams) {
const sfdl = window.sessionStorage.getItem('sfdl');
if (!sfdl) {
if (menuParams == this.kxurl) {
window.location.href = `/view/mhzc/login`;
return;
}
if (menuParams == '/view/gxzx/gxzx') {
window.location.href = `/view/mhzc/login`;
return;
}
}
console.log(11111, this.nowurl, menuParams);
this.nowurl = menuParams;
if (menuParams == '/view/mhzc/home') {
window.location.href = `/view/mhzc/home`;
return;
}
console.log('menuParams', menuParams);
// return
this.$router.replace({
path: '/mhsy/mhNewMain',
name: 'mhNewMain', // name为必填项没有则参数无法传递
query: {
newUrl: menuParams,
// parmasStr: menuParams.menuParmasStr,
},
});
// return;
if (this.newUrl) {
window.location.reload();
}
},
grxxisShow() {
if (!this.hoverxxzxTimeout) {
this.hoverxxzxTimeout = setTimeout(() => {
this.grxxShow = true;
}, 500);
}
},
headMouseLeave() {
clearTimeout(this.hoverxxzxTimeout);
this.hoverxxzxTimeout = null;
this.grxxShow = false;
},
async logoutHandler() {
this.closeMobileMenu();
const res = await logout();
const resVO = res.data;
if (resVO.dcdz) {
resVO.forEach((item) => {
const { token } = item;
const { dcdz } = item;
axios.get(
dcdz,
{},
{
headers: {
'Admin-Token': token,
},
},
);
});
}
sessionStorage.removeItem('sfdl');
sessionStorage.removeItem('yhxx');
window.location.href = `/view/mhzc/login`;
},
},
};
</script>
<style lang="css" scoped>
.nav-box {
position: fixed;
top: 0px;
width: 100%;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px);
border-radius: 0 0 12px 12px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 2fr 1fr;
place-items: center;
color: #003B1A;
z-index: 9999;
}
.logo-box {
text-align: center;
cursor: pointer;
}
.option-wrapper {
display: block;
}
.option-box {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
gap: 10px;
height: 64px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 16px;
leading-trim: NONE;
letter-spacing: 0%;
}
.option-box .gzt {
padding: 10px;
text-align: center;
cursor: pointer;
background: rgba(255, 255, 255, 0.3);
display: flex;
justify-content: space-around;
align-items: center;
gap: 10px;
border-radius: 6px;
}
.menu-box {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
height: 64px;
font-size: 16px;
gap: 10px;
}
.menu-title {
width: 96px;
height: 64px;
text-align: center;
line-height: 24px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.meun-title-active {
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.15) 100%);
border-bottom: 2px solid #003B1A;
font-weight: 600;
}
.meun-title-disable {
cursor: not-allowed !important;
}
/* 汉堡菜单按钮 */
.hamburger-btn {
display: none;
padding: 10px;
cursor: pointer;
}
.hamburger-icon {
position: relative;
width: 24px;
height: 18px;
}
.hamburger-icon span {
position: absolute;
left: 0;
width: 100%;
height: 2px;
background: #003B1A;
transition: all 0.3s ease;
}
.hamburger-icon span:nth-child(1) {
top: 0;
}
.hamburger-icon span:nth-child(2) {
top: 8px;
}
.hamburger-icon span:nth-child(3) {
top: 16px;
}
.hamburger-icon.active span:nth-child(1) {
top: 8px;
transform: rotate(45deg);
}
.hamburger-icon.active span:nth-child(2) {
opacity: 0;
}
.hamburger-icon.active span:nth-child(3) {
top: 8px;
transform: rotate(-45deg);
}
/* 移动端菜单 */
.mobile-menu {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10000;
width: 100%;
height: 100vh;
height: 100dvh;
visibility: hidden;
transition: visibility 0.3s ease;
}
.mobile-menu.open {
visibility: visible;
}
.mobile-menu-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.mobile-menu-content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
display: flex;
width: 280px;
max-width: 85%;
height: 100%;
background: #fff;
transform: translateX(100%);
transition: transform 0.3s ease;
flex-direction: column;
}
.mobile-menu.open .mobile-menu-content {
transform: translateX(0);
}
.mobile-menu-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
background: rgba(255, 255, 255, 0.9);
}
.mobile-menu-header img {
height: 32px;
}
.close-btn {
font-size: 32px;
line-height: 1;
color: #003B1A;
cursor: pointer;
}
.mobile-menu-list {
padding: 10px 0;
overflow-y: auto;
flex: 1;
}
.mobile-menu-item {
display: flex;
align-items: center;
padding: 14px 20px;
font-size: 15px;
color: #333;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
gap: 10px;
}
.mobile-menu-item img {
width: 20px;
height: 20px;
}
.mobile-menu-item .arrow {
margin-left: auto;
opacity: 0.5;
}
.mobile-menu-item.active {
color: #009a29;
background: #f0f9f0;
}
.mobile-menu-item.disable {
color: #999;
cursor: not-allowed;
}
.mobile-menu-footer {
padding: 16px 20px;
background: #fafafa;
border-top: 1px solid #eee;
}
.mobile-auth-btns {
display: flex;
gap: 10px;
}
.mobile-auth-btn {
padding: 10px;
font-size: 14px;
color: #fff;
text-align: center;
cursor: pointer;
background: #009a29;
border-radius: 6px;
flex: 1;
}
.mobile-auth-btn.activate {
color: #333;
background: #f0f0f0;
}
.mobile-auth-btn.logout {
color: #666;
background: #fff;
border: 1px solid #ddd;
}
/* 移动端适配 */
@media (max-width: 768px) {
.nav-box {
height: 56px;
grid-template-columns: 1fr auto auto;
padding: 0 16px;
border-radius: 0;
background: rgba(255, 255, 255, 0.95);
}
.menu-box {
display: none;
}
.option-wrapper {
display: none;
}
.hamburger-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 12px;
cursor: pointer;
}
.hamburger-icon {
position: relative;
width: 24px;
height: 18px;
}
.hamburger-icon span {
position: absolute;
left: 0;
width: 100%;
height: 2px;
background: #003B1A;
transition: all 0.3s ease;
}
.hamburger-icon span:nth-child(1) {
top: 0;
}
.hamburger-icon span:nth-child(2) {
top: 8px;
}
.hamburger-icon span:nth-child(3) {
top: 16px;
}
.hamburger-icon.active span:nth-child(1) {
top: 8px;
transform: rotate(45deg);
}
.hamburger-icon.active span:nth-child(2) {
opacity: 0;
}
.hamburger-icon.active span:nth-child(3) {
top: 8px;
transform: rotate(-45deg);
}
.logo-box {
text-align: left;
}
.logo-box img {
height: 32px;
}
}
@media (max-width: 480px) {
.nav-box {
padding: 0 12px;
}
.hamburger-btn {
padding: 10px;
}
.logo-box img {
height: 28px;
}
}
</style>