- nav/index2: goyhzx 在当前已为 /yhzx/gzt 时直接 return,避免重复 push - footer: 联系列 / 友情链接列 row-gap 10→7,底部 padding 40→20 - sql: 新增 fix_gxnl_slxxb_wz_lj_20260609 收录数据修正脚本 Co-authored-by: Cursor <cursoragent@cursor.com>
1123 lines
27 KiB
Vue
1123 lines
27 KiB
Vue
<template>
|
||
<!-- 顶部菜单栏 -->
|
||
<div
|
||
v-show="!isIframeEmbedded"
|
||
class="nav-box"
|
||
:class="{ 'nav-box--mobile-menu-open': mobileMenuOpen }"
|
||
>
|
||
<div class="nav-figma-scale-viewport">
|
||
<div class="nav-figma-scale-stage">
|
||
<div class="nav-inner page-nav-inner">
|
||
<div class="logo-box" @click="goHome">
|
||
<span class="logo-mark">
|
||
<img class="logo-icon" :src="logoIconSrc" alt="" />
|
||
</span>
|
||
<span class="logo-title">可信碳信息网</span>
|
||
</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> -->
|
||
<span class="auth-text">
|
||
<span class="auth-link" @click="goyhzx">企业工作台</span>
|
||
<span class="auth-divider"> | </span>
|
||
<span class="auth-link" @click="logoutHandler">退出登录</span>
|
||
</span>
|
||
</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> -->
|
||
<span class="auth-link" @click="gologin">登录</span>
|
||
</div>
|
||
</div>
|
||
</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">
|
||
<div class="mobile-logo" @click="goHome">
|
||
<img class="logo-icon" :src="logoIconSrc" alt="" />
|
||
<span class="logo-title">可信碳信息网</span>
|
||
</div>
|
||
<div class="close-btn" @click="toggleMobileMenu">×</div>
|
||
</div>
|
||
<div class="mobile-menu-list">
|
||
<div v-for="(menu, index) in menuOptions" :key="index">
|
||
<!-- 有子菜单:移动端不用 t-dropdown(易被抽屉遮挡),改手风琴子项 -->
|
||
<div v-if="menu.child" class="mobile-menu-group">
|
||
<div
|
||
class="mobile-menu-item"
|
||
:class="{ active: curPage === menu.name }"
|
||
@click="toggleMobileSubmenu(menu.name)"
|
||
>
|
||
<img v-if="menu.icon" :src="menu.icon" width="20px" height="20px" alt="">
|
||
<span class="mobile-menu-item-label">{{ menu.title }}</span>
|
||
<img
|
||
class="arrow"
|
||
:class="{ 'arrow--open': expandedMobileMenu === menu.name }"
|
||
src="@/pages/index/assets/home-arrow-right.png"
|
||
width="16px"
|
||
height="16px"
|
||
alt=""
|
||
>
|
||
</div>
|
||
<div v-show="expandedMobileMenu === menu.name" class="mobile-submenu">
|
||
<button
|
||
v-if="hasMobileParentLink(menu)"
|
||
type="button"
|
||
class="mobile-submenu-item mobile-submenu-item--parent"
|
||
@click="gotoMobileParentPage(menu)"
|
||
>
|
||
{{ menu.name === 'fwsc' ? '服务中心首页' : `${menu.title}首页` }}
|
||
</button>
|
||
<button
|
||
v-for="(child, ci) in menu.child"
|
||
:key="`${menu.name}-${ci}`"
|
||
type="button"
|
||
class="mobile-submenu-item"
|
||
@click="handleMobileDropdownClick(child)"
|
||
>
|
||
{{ child.title || child.content }}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 无子菜单的项 -->
|
||
<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" alt="">
|
||
<span class="mobile-menu-item-label">{{ menu.title }}</span>
|
||
<img class="arrow" src="@/pages/index/assets/home-arrow-right.png" width="16px" height="16px" alt="">
|
||
</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 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 {
|
||
logoIconSrc: require('../../assets/logo-figma-icon.png'),
|
||
curPage: "home",
|
||
loginFlag: false, //是否已完成登录
|
||
mobileMenuOpen: false, //移动端菜单是否展开
|
||
expandedMobileMenu: null, // 移动端展开的子菜单 name
|
||
isIframeEmbedded: window.self !== window.top,
|
||
// 路由路径到菜单名的映射
|
||
routeToMenuMap: {
|
||
'/home': 'home',
|
||
'/fwsc': 'fwsc',
|
||
'/tfwsc': 'fwsc',
|
||
'/txqsc': 'fwsc',
|
||
'/tjrsc': 'fwsc',
|
||
'/tsjsc': 'fwsc',
|
||
'/yhzx': 'yhzx',
|
||
'/gxnlpt': 'gxnlpt',
|
||
'/qych': 'qych',
|
||
'/hyzt': 'hyzt',
|
||
'/login': 'login',
|
||
'/tzzx': 'tzzx',
|
||
},
|
||
|
||
menuOptions: [
|
||
{
|
||
name: 'home',
|
||
title: '首页',
|
||
// icon: require('@/pages/index/assets/nav-home.png'),
|
||
},
|
||
{
|
||
name: 'tzzx',
|
||
title: '碳证中心',
|
||
iframeUrl: '/web/carbon-index',
|
||
path:'/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: '/web/trustedCarbonQuery/index', //外部系统链接地址
|
||
path: '/trustedCarbonQuery/index',
|
||
// iframeUrl: '/web/trustedCarbonQuery/list?type=carbon-query', //外部系统链接地址
|
||
},
|
||
{
|
||
name: 'tsjfcg',
|
||
title: '碳数据防篡改',
|
||
value: 'tsjfcg',
|
||
content: '碳数据防篡改',
|
||
divider: true,
|
||
needLogin: true,
|
||
clientId: 'client_id_tfwzx',
|
||
iframeUrl: '/web/carbon-protection',
|
||
path: '/carbon-protection'
|
||
},
|
||
{
|
||
name: 'tzhy',
|
||
title: '碳证核验',
|
||
value: 'tzhy',
|
||
content: '碳证核验',
|
||
divider: true,
|
||
needLogin: true,
|
||
clientId: 'client_id_tfwzx',
|
||
iframeUrl: '/web/carbon-verify',
|
||
path: '/carbon-verify'
|
||
},
|
||
{
|
||
name: 'tgbcz',
|
||
title: '碳报告存证',
|
||
value: 'tgbcz',
|
||
content: '碳报告存证',
|
||
divider: true,
|
||
needLogin: true,
|
||
clientId: 'client_id_tfwzx',
|
||
iframeUrl: '/web/carbon-report-cert',
|
||
path: '/carbon-report-cert'
|
||
},
|
||
{
|
||
name: 'tbgtg',
|
||
title: '碳报告托管:',
|
||
value: 'tgbcz',
|
||
content: '碳报告托管',
|
||
divider: true,
|
||
needLogin: true,
|
||
clientId: 'client_id_tfwzx',
|
||
iframeUrl: '/web/carbon-report-hosting',
|
||
path: '/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;
|
||
this.expandedMobileMenu = null;
|
||
document.body.style.overflow = '';
|
||
},
|
||
toggleMobileSubmenu(name) {
|
||
this.expandedMobileMenu = this.expandedMobileMenu === name ? null : name;
|
||
},
|
||
hasMobileParentLink(menu) {
|
||
if (!menu || !menu.child) return false;
|
||
if (menu.name === 'fwsc') return true;
|
||
return Boolean(menu.path || menu.iframeUrl);
|
||
},
|
||
gotoMobileParentPage(menu) {
|
||
if (menu.disable) return;
|
||
this.curPage = menu.name;
|
||
this.closeMobileMenu();
|
||
if (menu.iframeUrl) {
|
||
this.$emit('gotoIfreamPage', menu.iframeUrl);
|
||
return;
|
||
}
|
||
this.$emit('gotoPage', menu.name);
|
||
},
|
||
// 返回首页
|
||
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;
|
||
|
||
// 更新 menuOptions 中所有 iframe 菜单的 iframeUrl
|
||
this.updateIframeUrl(this.menuOptions);
|
||
|
||
console.log('res', data);
|
||
} catch (error) {
|
||
console.error('数据加载失败', error);
|
||
}
|
||
},
|
||
updateIframeUrl(menus) {
|
||
if (!menus || !this.kxurl) return;
|
||
menus.forEach(menu => {
|
||
if (menu.path) {
|
||
menu.iframeUrl = `${this.kxurl}${menu.path}`;
|
||
}
|
||
if (menu.child && menu.child.length > 0) {
|
||
this.updateIframeUrl(menu.child);
|
||
}
|
||
});
|
||
},
|
||
gologin() {
|
||
this.closeMobileMenu();
|
||
this.$router.push("/login")
|
||
// window.location.href = `/view/mhzc/login`;
|
||
},
|
||
|
||
goyhzx() {
|
||
// this.curPage = ""; //进入工作台之后:nav菜单取消active
|
||
// this.closeMobileMenu();
|
||
// this.$router.push("src/pages/yhzx/gzt.vue")
|
||
// window.location.href = `/view/mhzc/yhzx`;
|
||
this.closeMobileMenu();
|
||
|
||
if (this.$route.path === '/yhzx/gzt') return;
|
||
|
||
this.$router.push('/yhzx/gzt');
|
||
},
|
||
|
||
|
||
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>
|
||
/* Figma 1:807 / 150512:4221 导航栏 */
|
||
.nav-box {
|
||
position: fixed;
|
||
top: 0;
|
||
z-index: 9999;
|
||
width: 100%;
|
||
height: var(--page-nav-height);
|
||
margin: 0 auto;
|
||
color: var(--page-nav-color);
|
||
background: #fff;
|
||
border-top: 1px solid var(--page-nav-color);
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
backdrop-filter: blur(20px);
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.nav-inner {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: var(--page-nav-height);
|
||
min-height: var(--page-nav-height);
|
||
}
|
||
|
||
.nav-figma-scale-viewport,
|
||
.nav-figma-scale-stage {
|
||
width: 100%;
|
||
}
|
||
|
||
.logo-box {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--page-nav-logo-gap, 12px);
|
||
cursor: pointer;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.logo-mark {
|
||
display: flex;
|
||
flex-shrink: 0;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: var(--page-nav-logo-icon-box, 34px);
|
||
height: var(--page-nav-logo-icon-box, 34px);
|
||
padding: 1px;
|
||
background: #fff;
|
||
border-radius: 100px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.logo-icon {
|
||
display: block;
|
||
width: 32px;
|
||
height: 32px;
|
||
object-fit: cover;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.logo-title {
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||
font-size: 28px;
|
||
font-weight: 600;
|
||
line-height: 28px;
|
||
color: var(--page-nav-color);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.option-wrapper {
|
||
display: flex;
|
||
flex-shrink: 0;
|
||
align-items: center;
|
||
margin-left: auto;
|
||
height: var(--page-nav-height);
|
||
}
|
||
|
||
.option-box {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 24px;
|
||
height: var(--page-nav-height);
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
line-height: normal;
|
||
color: var(--page-nav-color);
|
||
}
|
||
|
||
.auth-link {
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
|
||
&:hover {
|
||
opacity: 0.75;
|
||
}
|
||
}
|
||
|
||
.auth-text {
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
line-height: 24px;
|
||
color: var(--page-nav-color);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.auth-divider {
|
||
color: var(--page-nav-color);
|
||
user-select: none;
|
||
}
|
||
|
||
.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;
|
||
}
|
||
|
||
/* 菜单组:Figma Frame 3 居中,项间距 16px */
|
||
.menu-box {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex: 1;
|
||
flex-wrap: nowrap;
|
||
gap: var(--page-nav-item-gap);
|
||
height: var(--page-nav-height);
|
||
margin-left: 0;
|
||
min-width: 0;
|
||
}
|
||
|
||
.menu-box > div {
|
||
display: flex;
|
||
height: 100%;
|
||
}
|
||
|
||
.menu-box :deep(.t-dropdown) {
|
||
height: 100%;
|
||
}
|
||
|
||
.menu-title {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-sizing: border-box;
|
||
height: 100%;
|
||
padding: 0 var(--page-nav-item-padding-x);
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
line-height: 24px;
|
||
color: var(--page-nav-color);
|
||
white-space: nowrap;
|
||
cursor: pointer;
|
||
transition: font-weight 0.15s ease;
|
||
}
|
||
|
||
.meun-title-active {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.meun-title-active::after {
|
||
position: absolute;
|
||
right: var(--page-nav-item-padding-x);
|
||
bottom: 0;
|
||
left: var(--page-nav-item-padding-x);
|
||
height: var(--page-nav-active-bar-height);
|
||
background: var(--page-nav-color);
|
||
content: '';
|
||
}
|
||
|
||
.meun-title-disable {
|
||
cursor: not-allowed !important;
|
||
}
|
||
|
||
/* 抽屉已有关闭钮时,隐藏顶部汉堡(避免与 header × 叠成两个叉) */
|
||
.nav-box--mobile-menu-open .hamburger-btn {
|
||
visibility: hidden;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 汉堡菜单按钮 */
|
||
.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-logo {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.mobile-menu-header .logo-icon {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.mobile-menu-header .logo-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
line-height: 1.2;
|
||
color: var(--page-nav-color);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.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-label {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.mobile-menu-item .arrow {
|
||
margin-left: auto;
|
||
opacity: 0.5;
|
||
transition: transform 0.2s ease;
|
||
}
|
||
|
||
.mobile-menu-item .arrow--open {
|
||
transform: rotate(90deg);
|
||
opacity: 0.85;
|
||
}
|
||
|
||
.mobile-menu-group {
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.mobile-submenu {
|
||
padding: 0 0 8px;
|
||
background: #f8faf9;
|
||
}
|
||
|
||
.mobile-submenu-item {
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
min-height: 48px;
|
||
padding: 12px 20px 12px 40px;
|
||
font-size: 14px;
|
||
color: #333;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
background: transparent;
|
||
border: none;
|
||
border-bottom: 1px solid #eef2ef;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.mobile-submenu-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.mobile-submenu-item--parent {
|
||
font-weight: 600;
|
||
color: #009a29;
|
||
}
|
||
|
||
.mobile-submenu-item:active {
|
||
background: #eef8f0;
|
||
}
|
||
|
||
.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.logout {
|
||
color: #666;
|
||
background: #fff;
|
||
border: 1px solid #ddd;
|
||
}
|
||
|
||
/* 移动端适配 */
|
||
@media (max-width: 768px) {
|
||
.nav-box {
|
||
height: var(--page-nav-height);
|
||
background: #fff;
|
||
}
|
||
|
||
.nav-inner {
|
||
min-height: var(--page-nav-height);
|
||
}
|
||
|
||
.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-title {
|
||
display: block;
|
||
overflow: hidden;
|
||
max-width: calc(100vw - 96px);
|
||
font-size: 18px;
|
||
line-height: 1.2;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.logo-icon {
|
||
width: 28px;
|
||
height: 28px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.nav-box {
|
||
padding: 0;
|
||
}
|
||
|
||
.hamburger-btn {
|
||
padding: 10px;
|
||
}
|
||
|
||
.logo-title {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.logo-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
}
|
||
</style>
|