Files
m2pool_web_frontend/mining-pool/src/components/header.vue
2025-10-11 14:50:53 +08:00

1147 lines
31 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="headerBox" :class="{ whiteBg: key !== `/` }">
<div class="header">
<div class="logo" @click="handelJump('/')">
<img src="../assets/img/logo.png" alt="logo图片" />
</div>
<!--|| $route.path !== `/${$i18n.locale}` -->
<div class="topMenu">
<div class="nav" v-show="isLogin &&( $route.path.includes(`reportBlock`) || $route.name == `Home` ) ">
<div class="nav-item" id="menu1" @click.stop="toggleDropdown">
<img
class="itemImg"
:src="activeItem.imgUrl"
:alt="activeItem.label"
/>
<span style="text-transform: capitalize;"
>
{{ activeItem.label }}</span
>
<i class="arrow"></i>
<div class="dropdown">
<div
class="option"
v-for="item in currencyList"
:key="item.value"
@click.stop="changeMenuName($event, item)"
:class="{optionActive: item.value === activeItem.value}"
>
<img class="dropdownCoin" :src="item.imgUrl" :alt="item.label">
<div class="dropdownText">{{ item.label }}</div>
</div>
</div>
</div>
</div>
<ul class="menuBox afterLoggingIn" v-show="isLogin">
<li
class="home"
:class="{
active:
$route.path === `/${$i18n.locale}` ||
$route.path === `/${$i18n.locale}/`,
}"
@click="handelJump(`/`)"
>
{{ $t(`home.home`) }}
<div
class="horizontalLine"
:class="{
hidden:
$route.path === `/${$i18n.locale}` ||
$route.path === `/${$i18n.locale}/`,
}"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<li class="miningAccount" v-show="isLogin">
<el-menu
active-text-color="#6E3EDB"
class="el-menu-demo"
mode="horizontal"
>
<el-submenu index="888888">
<span
slot="title"
class="miningAccountTitle"
style="color: #000"
:class="{
active: $route.path.includes(
`/${$i18n.locale}/miningAccount`
),
}"
>{{ $t(`home.accountCenter`) }}</span
>
<el-submenu
:index="item.coin"
v-for="item in miningAccountList"
:key="item.coin"
>
<template slot="title">
<img style="width: 20px" :src="item.img" :alt="item.coin" />
{{ item.title }}</template
>
<el-menu-item
:index="subItem.id.toString()"
@click.native="handelJumpAccount(item, subItem, item.coin)"
v-for="subItem in item.children"
:key="subItem.id"
>
{{ subItem.account }}</el-menu-item
>
</el-submenu>
<el-menu-item
style="font-size: 0.9rem"
class="signOut"
@click.native="handelSignOut"
index="999999"
>
&nbsp;&nbsp; {{ $t(`user.signOut`) }}</el-menu-item
>
</el-submenu>
</el-menu>
<div
class="horizontalLine"
:class="{ hidden: $route.path == `/miningAccount` }"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<li
class="reportBlock"
:class="{
active: $route.path.includes(`/${$i18n.locale}/reportBlock`),
}"
@click="handelJump(`reportBlock`)"
>
{{ $t(`home.reportBlock`) }}
<div
class="horizontalLine"
:class="{
hidden: $route.path.includes(`/${$i18n.locale}/reportBlock`),
}"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<!-- <li>{{$t(`home.file`)}}</li> -->
<!-- <li>{{$t(`home.rate`)}}</li> -->
<li
class="personalCenter"
:class="{
active: $route.path.includes(`/${$i18n.locale}/personalCenter`),
}"
@click="handelJump('personalCenter')"
>
{{ $t(`home.personalCenter`) }}
<div
class="horizontalLine"
:class="{
hidden:
$route.path.includes(`/${$i18n.locale}/personalCenter`) ||
$route.path.includes(
`/${$i18n.locale}/personalCenter/personalMining`
),
}"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<li
class="personalCenter"
:class="{
active: $route.path.includes(`/${$i18n.locale}/workOrderRecords`),
}"
@click="handelJump('workOrderRecords')"
>
{{ $t(`personal.workOrderRecord`) }}
<div
class="horizontalLine"
:class="{ hidden: $route.path.includes(`workOrderRecords`) }"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<!-- 帮助中心 -->
<li
class="personalCenter"
:class="{
active: $route.path.includes(`/${$i18n.locale}/helpCenter`),
}"
@click="handelJump('helpCenter')"
>
{{ $t(`home.helpCenter`) }}
<div
class="horizontalLine"
:class="{ hidden: $route.path.includes(`helpCenter`) }"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<!-- 矿机租赁 -->
<!-- <li @click="handelMachineLease">
{{ $t(`home.machineLease`) }}
</li> -->
<!-- 工单管理 -->
<!-- <li
v-show="ManagementShow"
class="personalCenter"
:class="{
active: $route.path.includes(`/${$i18n.locale}/workOrderBackend`),
}"
@click="handelJump('workOrderBackend')"
>
{{ $t(`work.WorkOrderManagement`) }}
<div
class="horizontalLine"
:class="{ hidden: $route.path.includes(`workOrderBackend`) }"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li> -->
<li class="langBox">
<div class="LangLine"></div>
<el-dropdown>
<span
class="el-dropdown-link"
style="font-size: 0.9rem; color: rgba(0, 0, 0, 1)"
>
<img
style="width: 20px"
src="../assets/img/lang.svg"
alt="lang"
/>
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
@click.native="handelLang(`zh`)"
>简体中文</el-dropdown-item
>
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
@click.native="handelLang(`en`)"
>English</el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
</li>
<!-- <li @click="handelDarkMode">/浅模式</li> -->
</ul>
<ul class="menuBox notLoggedIn" v-show="!isLogin">
<li class="login" @click="handelLogin">{{ $t(`user.login`) }}</li>
<li class="register" @click="handelRegister">
{{ $t(`user.register`) }}
</li>
<!-- 帮助中心 -->
<li
class="personalCenter"
style="margin-left: 20px;"
:class="{
active: $route.path.includes(`/${$i18n.locale}/helpCenter`),
}"
@click="handelJump('helpCenter')"
>
{{ $t(`home.helpCenter`) }}
<div
class="horizontalLine"
:class="{ hidden: $route.path.includes(`helpCenter`) }"
>
<span class="circular"></span>
<span class="line"></span>
</div>
</li>
<li class="langBox">
<div class="LangLine"></div>
<el-dropdown>
<span
class="el-dropdown-link"
style="font-size: 0.9rem; color: rgba(0, 0, 0, 1)"
>
<img
style="width: 20px"
src="../assets/img/lang.svg"
alt="lang"
/>
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
@click.native="handelLang(`zh`)"
>简体中文</el-dropdown-item
>
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
@click.native="handelLang(`en`)"
>English</el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import { getLogout, getAccountGradeList } from "../api/login";
import { getAccountList } from "../api/personalCenter";
import { getImageUrl } from "../utils/publicMethods";
export default {
computed: {
key() {
return this.$route.path;
},
},
data() {
return {
isLogin: false,
bthText: "English",
token: "",
accountList: [],
miningAccountList: [],
isOrderKey: "",
activeIndex2: "",
isDropdownVisible: false,
activeIndex: "",
jurisdiction: {
roleKey: "",
},
ManagementShow: false,
currencyList: [],
activeItem: {
value: "nexa",
label: "nexa",
imgUrl:getImageUrl(`/img/nexa.png`) ,
},
customerIsOnline: false,
userEmail:"",
};
},
watch: {
token: {
handler(val) {
if (val) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
immediate: true,
deep: true,
},
accountList: {
handler(val) {},
immediate: true,
deep: true,
},
miningAccountList: {
handler(val) {},
immediate: true,
deep: true,
},
$route(to, from) {
if (to.path !== `/miningAccount`) {
this.activeIndex = "";
}
},
activeItemCoin:{
handler(val){
this.changeMenuName($event,this.activeItem)
},
deep:true,
}
},
mounted() {
this.$addStorageEvent(1, "activeItemCoin", JSON.stringify(this.activeItem));
let valueTaking = localStorage.getItem("token");
this.token = JSON.parse(valueTaking);
let list = localStorage.getItem("accountList");
this.accountList = JSON.parse(list);
let miningAccountList = localStorage.getItem("miningAccountList");
this.miningAccountList = JSON.parse(miningAccountList);
let jurisdiction = localStorage.getItem("jurisdiction");
this.jurisdiction = JSON.parse(jurisdiction);
let currencyList = localStorage.getItem("currencyList");
this.currencyList = JSON.parse(currencyList);
let userEmail = localStorage.getItem("userEmail");
this.userEmail = JSON.parse(userEmail);
window.addEventListener("setItem", () => {
let valueTaking = localStorage.getItem("token");
this.token = JSON.parse(valueTaking);
let list = localStorage.getItem("accountList");
this.accountList = JSON.parse(list);
let miningAccountList = localStorage.getItem("miningAccountList");
this.miningAccountList = JSON.parse(miningAccountList);
let jurisdiction = localStorage.getItem("jurisdiction");
this.jurisdiction = JSON.parse(jurisdiction);
let currencyList = localStorage.getItem("currencyList");
this.currencyList = JSON.parse(currencyList);
let active = localStorage.getItem(`activeItemCoin`)
this.activeItem = JSON.parse(active)
let userEmail = localStorage.getItem("userEmail");
this.userEmail = JSON.parse(userEmail);
if (this.jurisdiction && this.jurisdiction.roleKey == `admin`) {
this.ManagementShow = true;
} else {
this.ManagementShow = false;
}
});
if (this.jurisdiction && this.jurisdiction.roleKey == `admin`) {
this.ManagementShow = true;
} else {
this.ManagementShow = false;
}
// 点击页面其他地方关闭下拉菜单
document.addEventListener("click", function () {
const dropdown = document.querySelector(".dropdown");
const arrow = document.querySelector(".arrow");
try {
if (dropdown.classList.contains("show")) {
dropdown.classList.remove("show");
arrow.classList.remove("up");
}
} catch (error) {
console.log(error)
}
});
},
methods: {
toggleDropdown(e) {
if (!e) return;
const menuItem = e.currentTarget;
const dropdown = menuItem.querySelector(".dropdown");
const arrow = menuItem.querySelector(".arrow");
if (dropdown) {
dropdown.classList.toggle("show");
arrow?.classList.toggle("up");
}
},
changeMenuName(e, item) {
if (!e) return;
e.stopPropagation(); // 阻止事件冒泡
const menuItem = document.getElementById("menu1");
if (!menuItem) return;
this.activeItem = item;
const dropdown = menuItem.querySelector(".dropdown");
const arrow = menuItem.querySelector(".arrow");
dropdown?.classList.remove("show");
arrow?.classList.remove("up");
this.$addStorageEvent(1, "activeItemCoin", JSON.stringify(item));
},
handelDarkMode() {},
async fetchAccountGradeList() {
const data = await getAccountGradeList();
this.miningAccountList = data.data;
this.$addStorageEvent(
1,
`miningAccountList`,
JSON.stringify(this.miningAccountList)
);
},
async fetchAccountList(params) {
const data = await getAccountList(params);
if (data && data.code == 200) {
this.accountList = data.data;
this.$addStorageEvent(
1,
`accountList`,
JSON.stringify(this.accountList)
);
// localStorage.setItem(`accountList`,JSON.stringify(this.accountList))
}
},
// 修改 fetchUserid 方法,添加 token 检查
async fetchUserid(params) {
try {
const res = await getUserid(params);
if (res && res.code == 200) {
this.customerIsOnline = res.data.customerIsOnline;
localStorage.setItem(`customerIsOnline`,JSON.stringify(this.customerIsOnline))
}
} catch (error) {
console.error("获取用户ID失败:", error);
throw error;
}
},
async fetchSignOut() {
const data = await getLogout();
if (data && data.code == 200) {
// 调用 Vuex 的 logout action 清除前端状态
await this.$store.dispatch('logout')
const lang = this.$i18n.locale;
this.fetchUserid({email:this.userEmail})
this.$router.push(`/${lang}`);
}
},
handleDropdownClick() {
this.isDropdownVisible = true;
},
handleCommand(command) {
// 处理命令逻辑
},
handleSelect() {},
handelLogin() {
this.isLogin = true;
const lang = this.$i18n.locale;
this.$router.push(`/${lang}/login`);
},
handelRegister() {
const lang = this.$i18n.locale;
this.$router.push(`/${lang}/register`);
},
handelLogin222() {
this.isLogin = !this.isLogin;
},
handelJump(url) {
try {
const lang = this.$i18n.locale;
// 特殊处理 personalCenter 路由
if (url === "personalCenter") {
// 先跳转到 personalCenter
this.$router
.push(`/${lang}/personalCenter/personalMining`)
// .then(() => {
// // 成功后再跳转到子路由
// this.$router.push(`/${lang}/personalCenter/personalMining`);
// })
.catch((err) => {
if (err.name !== "NavigationDuplicated") {
console.error("Navigation failed:", err);
}
});
return;
}
// 其他路由的处理保持不变
const path = `/${lang}${url === "/" ? "" : "/" + url}`;
this.$router.push(path).catch((err) => {
if (err.name !== "NavigationDuplicated") {
console.error("Navigation failed:", err);
}
});
} catch (error) {
console.error("Navigation error:", error);
this.$message.error(this.$t("common.navigationError"));
}
},
handelJumpAccount(item, subItem, coin) {
const lang = this.$i18n.locale;
let obj = {
ma: subItem.account,
coin: coin,
id: subItem.id,
img: item.img,
};
this.$addStorageEvent(1, "accountItem", JSON.stringify(obj));
this.$router.push({
path: `/${lang}/miningAccount`,
query: { ma: subItem.account + coin },
});
this.isDropdownVisible = false;
},
handelLang(lang) {
try {
const currentPath = this.$route.path;
const oldLang = this.$i18n.locale;
const currentQuery = this.$route.query; // 获取当前的查询参数
// 检查是否是支持的语言
if (!["zh", "en"].includes(lang)) {
throw new Error("Unsupported language");
}
// 更新语言设置
this.$i18n.locale = lang;
localStorage.setItem("lang", lang || 'en');
// 构造新的路由配置
const newPath = currentPath.replace(`/${oldLang}`, `/${lang}`);
// 保持原有查询参数
this.$router.push({
path: newPath,
query: currentQuery // 保留原有的查询参数
}).catch((err) => {
if (err.name !== 'NavigationDuplicated') {
console.error("路由更新失败:", err);
this.$message.error(this.$t("common.langChangeFailed"));
}
});
// 更新HTML的lang属性
document.documentElement.lang = lang;
} catch (error) {
console.error("语言切换失败:", error);
this.$message.error(this.$t("common.langChangeFailed"));
}
},
handelSignOut() {
localStorage.setItem('cs_disconnect_all', Date.now().toString()); //告知客服页面断开连接
this.fetchSignOut();
localStorage.removeItem(`token`);
localStorage.removeItem("username");
localStorage.removeItem("userName");
localStorage.removeItem("userEmail");
localStorage.removeItem("jurisdiction");
this.$addStorageEvent(1, `miningAccountList`, JSON.stringify(""));
this.isLogin = false;
this.isDropdownVisible = false;
},
/**
* 简单的AES加密函数
* @param {string} text - 要加密的文本
* @param {string} secretKey - 密钥
* @returns {string} 加密后的字符串
*/
encryptData(text, secretKey) {
try {
// 使用简单的XOR加密生产环境建议使用更安全的加密库如crypto-js
let encrypted = '';
for (let i = 0; i < text.length; i++) {
encrypted += String.fromCharCode(text.charCodeAt(i) ^ secretKey.charCodeAt(i % secretKey.length));
}
return btoa(encrypted); // Base64编码
} catch (error) {
console.error('加密失败:', error);
return text; // 如果加密失败,返回原文
}
},
/**
* 处理机器租赁跳转,携带加密的用户参数
*/
handelMachineLease(){
try {
// 获取当前用户信息和其他需要传递的参数
const token =localStorage.getItem('token') || '';
const userEmail = localStorage.getItem('userEmail') || '';
const language = this.$i18n.locale || 'zh';
const username = localStorage.getItem('username') || '';
// 定义加密密钥(生产环境应该从环境变量或配置文件中获取)
const secretKey = 'mining-pool-secret-key-2024';
// 准备要加密的敏感数据
const sensitiveData = {
token: token,
userEmail: userEmail,
timestamp: Date.now()
};
// 加密敏感数据
const encryptedData = this.encryptData(JSON.stringify(sensitiveData), secretKey);
// 构建带参数的URL敏感数据加密其他数据明文
const baseUrl = "http://18.183.240.108:8080/";
const params = new URLSearchParams({
data: encryptedData, // 加密的敏感数据
language: language,
username: username,
source: 'mining-pool', // 标识来源项目
version: '1.0' // 数据版本,用于兼容性
});
const urlWithParams = `${baseUrl}?${params.toString()}`;
// 当前窗口打开
window.open(urlWithParams, "_self");
// 记录跳转日志(用于调试,不记录敏感信息)
console.log('跳转到机器租赁系统,携带参数:', {
userEmail: userEmail ? '***' : '',
language,
source: 'mining-pool',
encrypted: true
});
} catch (error) {
console.error('跳转机器租赁系统时发生错误:', error);
this.$message.error("加载系统失败 稍后重试");
}
}
},
};
</script>
<style scoped lang="scss">
// 币种下拉框
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.nav {
// position: absolute;
z-index: 1000;
// height: 60px;
// line-height: 60px;
margin-right: 8px;
font-size: 0.9rem;
}
.nav-item {
position: relative;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0 10px;
.itemImg{
width: 20px;
margin-right: 5px;
}
.arrow {
margin-left: 5px;
border: solid rgba(0,0,0,0.3);
border-width: 0 1px 1px 0;
display: inline-block;
padding: 3px;
transform: rotate(45deg);
transition: transform 0.3s;
&.up {
transform: rotate(-135deg);
}
}
}
.dropdown {
position: absolute;
top: 47px;
left: 0;
width: 392px;
background: white;
border: 1px solid #eee;
border-radius: 4px;
padding: 3px;
display: none;
flex-wrap: wrap;
gap: 1px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 999999;
&.show {
display: flex;
}
.option {
width: 76px;
height: 80px;
background: #f5f5f5;
// display: flex;
// align-items: center;
// justify-content: center;
cursor: pointer;
transition: all 0.3s;
border-radius: 4px;
// flex-direction: column;
// padding:5px;
// padding-top: 5%;
overflow: hidden;
text-align: center;
padding: 5px;
&:hover {
background: #e8e8e8;
color: #6e3edb;
border:1px solid #9d8ac9;
}
}
.optionActive{
background: #e8e8e8;
color: #6e3edb;
border:1px solid #9d8ac9;
}
}
.dropdownCoin{
width: 32px ;
margin: 0;
}
.dropdownText{
width: 100%;
font-size: 0.8rem;
// word-wrap: break-word;
text-align: center;
margin: 0;
word-break: break-word;
margin-top: 5px;
}
// --------------------------------
.headerBox {
// height: 60PX;
width: 100%;
/* outline: 1px solid red; */
font-size: 0.95rem;
// border-bottom:1PX solid #ccc;
// background-image: url(../assets/img/bktop.png);
// background-position: 60% 8%;
// background-size: cover;
display: flex;
justify-content: center;
}
.miningAccountTitle:hover {
color: #6e3edb !important;
}
.hidden {
display: block;
opacity: 1 !important;
}
.el-menu--horizontal > .el-submenu .el-submenu__title {
color: #000;
}
.el-menu--horizontal {
background: transparent;
}
.el-submenu:hover {
background-color: transparent !important; /* 例如,更改背景颜色 */
}
.el-submenu.is-active:after {
border-bottom: none !important;
border-bottom-color: transparent !important;
border: none !important;
outline: none !important;
}
// .el-menu--horizontal > .el-submenu:hover{
// background: red !important;
// }
.is-order {
background: #21a0ff;
}
.dropdownItem {
display: flex;
align-items: center;
img {
margin-right: 5px;
}
}
.active {
color: #6e3edb !important;
font-weight: 600;
}
.whiteBg {
// background-image: url(../assets/img/bktop.png);
// background-position: 60% 8%;
// background-size: cover;
background: rgba(255, 255, 255, 0.5);
}
.header {
display: flex;
justify-content: space-between; /* 保持logo在左导航在右 */
align-items: center;
height: 100%;
width: 100%;
margin: 0 auto; /* 居中显示 */
padding: 0 2.5%; /* 使用padding替代固定宽度 */
/* outline: 1px solid red; */
// outline: 1PX solid red;
// padding: 0px 5%;
// padding: 0 5%;
// background: #21A0FF;
}
.logo {
flex: 0 0 auto; /* 不伸缩,保持固定大小 */
height: 100%;
display: flex;
justify-content: flex-end; /* 右对齐 */
align-items: center;
font-size: 0.9rem;
width: 300px; /* 固定宽度,给导航留出更多空间 */
img {
width: 100px;
height: auto; /* 保持比例 */
}
}
.topMenu {
flex: 1; /* 占据剩余空间 */
height: 100%;
display: flex;
justify-content: flex-end; /* 右对齐 */
align-items: center;
min-width: 0; /* 允许收缩 */
// background: goldenrod;
.afterLoggingIn {
display: flex;
justify-content: flex-end; /* 右对齐 */
align-items: center;
flex-wrap: nowrap; /* 防止换行 */
width: auto; /* 自适应宽度 */
// background: #6E3EDB;
.langBox {
display: flex;
justify-content: space-around;
align-items: center;
width: 70px;
}
.LangLine {
width: 1px;
height: 60%;
background: #ccc;
margin-right: 8px;
}
li {
position: relative;
}
.horizontalLine {
width: 100%;
// height: 12%;
// background: #21A0FF;
position: absolute;
bottom: -10px;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
transition: all 0.3s linear;
.circular {
width: 5px;
height: 5px;
background: #6e3edb;
border-radius: 50%;
}
.line {
width: 20px;
height: 5px;
background: #6e3edb;
margin-left: 2px;
border-radius: 22px;
}
}
}
.notLoggedIn {
display: flex;
justify-content: flex-end; /* 右对齐 */
align-items: center;
gap: 12px; /* 增加间距 */
li {
flex: 0 0 auto; /* 不伸缩,保持内容大小 */
white-space: nowrap; /* 防止文字换行 */
padding: 0 6px; /* 减少内边距 */
}
.langBox {
display: flex;
justify-content: space-around;
align-items: center;
width: 20%;
}
.register.register {
padding: 5px 30px;
}
.LangLine {
width: 1px;
height: 60%;
background: #ccc;
margin-right: 2%;
}
}
}
.menuBox {
display: flex;
justify-content: flex-end; /* 右对齐 */
align-items: center;
margin: 0;
gap: 12px; /* 增加间距 */
flex-wrap: nowrap; /* 防止换行 */
// background: #fff;
li {
list-style: none;
height: 45%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 0.9rem;
position: relative;
text-align: center;
flex: 0 0 auto; /* 不伸缩,保持内容大小 */
white-space: nowrap; /* 防止文字换行 */
padding: 0 6px; /* 减少内边距 */
min-width: auto; /* 移除最小宽度限制 */
}
li:hover {
color: #6e3edb;
font-weight: 600;
}
.login {
padding: 2px 18px;
}
.login:hover {
color: #21a0ff;
border: 1px solid #21a0ff;
border-radius: 10px;
}
.register {
background: #d2c3ea;
border-radius: 25px;
padding: 0px 25px;
}
.register:hover {
color: #000;
color: #fe4886;
}
}
</style>
<style lang="scss" scoped>
.el-submenu__title:hover {
background-color: transparent !important;
background: transparent !important;
color: #6e3edb !important;
}
.el-menu-item.is-active:not(.is-index) {
border-bottom: none !important;
}
.el-submenu__title {
border: none !important;
border-bottom: none !important;
border-bottom-color: transparent !important;
margin-right: 10px;
}
.el-submenu.is-active {
// background: #FE4886;
// display: none !important;
border: none !important;
border-bottom: none !important;
border-bottom-color: transparent !important;
}
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 0px !important;
}
.el-submenu.is-active .el-submenu__title {
border-bottom-color: transparent !important;
}
.el-menu.el-menu--horizontal {
border-bottom: 0px !important;
}
/* 响应式设计 - 小屏幕适配 */
@media (max-width: 768px) {
.header {
padding: 0 1%; /* 减少内边距 */
}
.logo {
min-width: 80px; /* 减少logo最小宽度 */
img {
width: 80px; /* 减小logo尺寸 */
}
}
.menuBox {
gap: 4px; /* 减少间距 */
li {
font-size: 0.8rem; /* 减小字体 */
padding: 0 4px; /* 减少内边距 */
}
}
.topMenu .afterLoggingIn .langBox {
width: 50px; /* 减小语言选择框宽度 */
}
}
/* 超小屏幕 - 隐藏部分菜单项 */
@media (max-width: 480px) {
.menuBox li:not(.home):not(.langBox) {
display: none; /* 只显示首页和语言选择 */
}
.menuBox {
gap: 2px;
li {
font-size: 0.75rem;
padding: 0 2px;
}
}
}
</style>