1.添加alph币种(矿池分配及转账规则页面、费率页面、挖矿教程页面、起付额度限制、最新报块跳转、支付id跳转) 完成

2.api文档页面修改8个接口请求方式为post
3.优化代码币种添加通用币种信息及挖矿教程页面跳转通用
4.m2pool断网重连 60秒内重连  处理中
5.收益计算器显示值修改  取消四舍五入 直接保留10位小数 添加千位符分隔显示
6.coinbus 添加seo相关配置及站点地图 处理中
This commit is contained in:
2025-04-11 10:31:26 +08:00
parent ab78808aec
commit 915fc3d7a6
338 changed files with 65858 additions and 0 deletions

View File

@@ -0,0 +1,684 @@
<template>
<div class="MoveMain">
<header class="headerMove">
<img
@click="handelJump(`/`)"
src="../assets/mobile/login/LOGO.svg"
alt="logo"
/>
<!-- 页面名称 -->
<span style="font-size: 0.9rem">{{ $t(key) }}</span>
<!-- 菜单 -->
<el-dropdown trigger="click" :hide-on-click="false">
<span
class="el-dropdown-link"
style="font-size: 0.9rem; color: rgba(0, 0, 0, 1)"
>
<img src="../assets/mobile/login/menu.svg" alt="menu" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)">
<div class="menuItem" @click="handelJump(`/`)">
<img src="../assets/mobile/home/homeMenu.svg" alt="home" />
<span> {{ $t(`home.home`) }}</span>
</div>
</el-dropdown-item>
<!-- 最新报块 -->
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
@click.native="handelJump(`/reportBlock`)"
>
<div class="menuItem">
<img
src="../assets/mobile/home/reportBlock.svg"
alt="reportBlock"
/>
<span> {{ $t(`home.reportBlock`) }}</span>
</div>
</el-dropdown-item>
<el-dropdown-item style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)">
<el-collapse v-model="activeNames">
<el-collapse-item name="1">
<!-- 挖矿账户 -->
<template slot="title">
<div class="menuItem2">
<img src="../assets/mobile/home/mining.svg" alt="account" />
<span>{{ $t(`home.accountCenter`) }}</span>
</div>
</template>
<div
class="accountBox"
@click="handelJumpAccount(item)"
v-for="item in newMiningAccountList"
:key="item.id"
>
<div class="coinBox">
<img :src="item.img" alt="coin" />
<span class="coin">{{ item.coin }}</span>
</div>
<span class="account">{{ item.account }}</span>
</div>
</el-collapse-item>
</el-collapse>
</el-dropdown-item>
<!-- 个人中心 -->
<el-dropdown-item
@click.native="handelJump(`/personalCenter`)"
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
>
<div class="menuItem">
<img
src="../assets/mobile/home/personal.svg"
alt="personalCenter"
/>
<span> {{ $t(`home.personalCenter`) }}</span>
</div>
</el-dropdown-item>
<!-- 工单记录 -->
<el-dropdown-item
@click.native="handelJump(`/workOrderRecords`)"
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
>
<div class="menuItem">
<img
src="../assets/mobile/home/workRecord.svg"
alt="workRecord"
/>
<span> {{ $t(`personal.workOrderRecord`) }}</span>
</div>
</el-dropdown-item>
<!-- 工单管理 -->
<el-dropdown-item
v-show="ManagementShow"
@click.native="handelJump(`/workOrderBackend`)"
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
>
<div class="menuItem">
<img
src="../assets/mobile/home/workAdministration.svg"
alt="Work Order Management"
/>
<span> {{ $t(`work.WorkOrderManagement`) }}</span>
</div>
</el-dropdown-item>
<el-dropdown-item
@click.native="handelSignOut"
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
>
<div class="menuItem">
<img src="../assets/mobile/home/lgout.svg" alt="sign out" />
<span> {{ $t(`user.signOut`) }}</span>
</div>
</el-dropdown-item>
<el-dropdown-item style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)">
<div class="langBox">
<el-radio
fill="red"
@input="handelRadio"
v-model="radio"
label="zh"
>简体中文</el-radio
>
<el-radio
fill="#fff"
@input="handelRadio"
v-model="radio"
label="en"
>English</el-radio
>
</div>
</el-dropdown-item>
<el-dropdown-item
style="font-size: 0.8rem; color: rgba(0, 0, 0, 1)"
v-show="!isLogin"
>
<div class="menuLogin">
<el-button class="lgBTH" @click="handelJump(`/login`)">{{
$t(`home.MLogin`)
}}</el-button>
<el-button class="reBTH" @click="handelJump(`/register`)">{{
$t(`home.MRegister`)
}}</el-button>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</header>
</div>
</template>
<script>
import { getLogout, getAccountGradeList } from "../api/login";
export default {
data() {
return {
radio: "en",
data: [
{
label: "一级 1",
children: [
{
label: "二级 1-1",
children: [
{
label: "三级 1-1-1",
},
],
},
],
},
{
label: "一级 2",
children: [
{
label: "二级 2-1",
children: [
{
label: "三级 2-1-1",
},
],
},
{
label: "二级 2-2",
children: [
{
label: "三级 2-2-1",
},
],
},
],
},
{
label: "一级 3",
children: [
{
label: "二级 3-1",
children: [
{
label: "三级 3-1-1",
},
],
},
{
label: "二级 3-2",
children: [
{
label: "三级 3-2-1",
},
],
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
currencyList: [],
miningAccountList: [],
newMiningAccountList: [],
activeNames: "",
titleList: [
{
path: "/",
label: "home.home",
},
{
path: "/reportBlock",
label: "home.reportBlock",
},
{
//挖矿账户
path: "/miningAccount",
label: "home.accountCenter",
},
{
//只读页面
path: "/readOnlyDisplay",
label: "personal.readOnlyPage",
},
{
//个人中心
path: "/personalCenter",
label: "home.personalCenter",
},
{
//挖矿账户设置
path: "/personalCenter/personalMining",
label: "home.accountSettings",
},
{
//只读页面
path: "/personalCenter/readOnly",
label: "personal.readOnlyPage",
},
{
//安全设置
path: "/personalCenter/securitySetting",
label: "personal.securitySetting",
},
{
//API
path: "/personalCenter/personalAPI",
label: "home.API",
},
],
token: "",
isLogin: false,
jurisdiction: {
roleKey: "",
},
ManagementShow: false,
};
},
computed: {
key() {
let obj = this.titleList.find((item) => item.path == this.$route.path);
if (obj) {
return obj.label;
} else {
return "";
}
},
},
watch: {
token: {
handler(val) {
if (val) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
immediate: true,
deep: true,
},
},
mounted() {
this.radio = localStorage.getItem("lang")
? localStorage.getItem("lang")
: "en";
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
let miningAccountList = localStorage.getItem("miningAccountList");
this.miningAccountList = JSON.parse(miningAccountList);
let valueTaking = localStorage.getItem("token");
this.token = JSON.parse(valueTaking);
let jurisdiction = localStorage.getItem("jurisdiction");
this.jurisdiction = JSON.parse(jurisdiction);
window.addEventListener("setItem", () => {
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
let miningAccountList = localStorage.getItem("miningAccountList");
this.miningAccountList = JSON.parse(miningAccountList);
let valueTaking = localStorage.getItem("token");
this.token = JSON.parse(valueTaking);
if (this.miningAccountList[0]) {
this.newMiningAccountList = this.flattenArray(this.miningAccountList);
}
let jurisdiction = localStorage.getItem("jurisdiction");
this.jurisdiction = JSON.parse(jurisdiction);
if (this.jurisdiction && this.jurisdiction.roleKey == `admin`) {
console.log(565656);
this.ManagementShow = true;
} else {
this.ManagementShow = false;
}
});
if (this.miningAccountList[0]) {
this.newMiningAccountList = this.flattenArray(this.miningAccountList);
}
if (this.jurisdiction && this.jurisdiction.roleKey == `admin`) {
this.ManagementShow = true;
} else {
this.ManagementShow = false;
}
},
methods: {
handelJump(url) {
console.log(url, "及附件");
try {
const lang = this.$i18n.locale;
// 移除开头的斜杠
const cleanPath = url.startsWith("/") ? url.slice(1) : url;
// 处理根路径特殊情况
const path = cleanPath === "" ? `/${lang}` : `/${lang}/${cleanPath}`;
this.$router.push(path).catch((err) => {
if (err.name !== "NavigationDuplicated") {
console.error("Navigation failed:", err);
}
});
} catch (error) {
console.error("Navigation error:", error);
}
},
toggleDropdown() {
this.showDropdown = !this.showDropdown;
},
handelRadio(val) {
const oldLang = this.$i18n.locale;
this.$i18n.locale = val;
localStorage.setItem("lang", val);
// 更新当前路径的语言部分
const currentPath = this.$route.path;
const newPath = currentPath.replace(`/${oldLang}`, `/${val}`);
const query = this.$route.query;
this.$router
.push({
path: newPath,
query: query,
})
.catch((err) => {
if (err.name !== "NavigationDuplicated") {
console.error("Navigation failed:", err);
}
});
},
selectItem(item) {
this.selectedItem = item;
this.showDropdown = false;
// 更新菜单项的高亮状态
this.menuItems.forEach((menuItem) => {
menuItem.isHighlighted = menuItem.text === item;
});
},
handelJumpAccount(item) {
const lang = this.$i18n.locale;
let obj = {
ma: item.account,
coin: item.coin,
id: item.id,
img: item.img,
};
this.$addStorageEvent(1, "accountItem", JSON.stringify(obj));
this.$router.push({
path: `/${lang}/miningAccount`,
query: { ma: item.account + item.coin },
});
},
async fetchSignOut() {
const lang = this.$i18n.locale;
const data = await getLogout();
if (data && data.code == 200) {
this.$router.push(`/${lang}/login`);
}
},
handelSignOut() {
this.fetchSignOut();
localStorage.removeItem(`token`);
localStorage.removeItem("username");
this.$addStorageEvent(1, `miningAccountList`, JSON.stringify(""));
this.isLogin = false;
this.isDropdownVisible = false;
},
//扁平化数组币种数组
flattenArray(arr) {
console.log(arr, "进来的数组");
if (arr[0]) {
return arr.reduce((flat, item) => {
return flat.concat(
item.children.map((child) => ({
...child,
coin: item.coin,
img: item.img,
title: item.title,
}))
);
}, []);
}
},
},
};
</script>
<style scoped lang="scss">
.MoveMain {
width: 100%;
height: 100%;
position: relative;
z-index: 9999;
}
.headerMove {
width: 100%;
min-height: 60px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0px 20px;
z-index: 999;
img {
width: 30px;
}
.title {
font-weight: 600;
}
.menu {
width: 15%;
height: 100%;
display: flex;
align-items: center;
justify-content: right;
}
}
.menuItem {
background: #d2c4e8;
// padding: 0% 8%;
padding-left: 5%;
border-radius: 5px;
margin-top: 20px;
display: flex;
align-items: center;
justify-content: left;
img {
width: 15px;
margin-right: 5px;
}
}
.menuItem2 {
background: #d2c4e8;
padding-left: 5%;
border-radius: 5px;
display: flex;
align-items: center;
img {
width: 15px;
margin-right: 5px;
}
}
.menuLogin {
display: flex;
margin-top: 10px;
justify-content: space-around;
margin-bottom: 20px;
}
.langBox {
width: 100%;
display: flex;
font-size: 0.6em;
margin-top: 18px;
justify-content: space-around;
}
::v-deep .el-collapse-item__content {
max-height: 300px;
overflow-y: auto;
}
.el-radio {
margin: 0 !important;
margin-left: 2px !important;
font-size: 0.6em !important;
}
.lgBTH {
background: #651efe;
color: #fff;
padding: 8px 23px;
}
.reBTH {
padding: 8px 23px;
color: #fff;
background: #ff4181;
}
::v-deep.el-dropdown-menu {
left: 40% !important;
top: 48px !important;
padding-bottom: 30px;
}
.el-popper[x-placement^="bottom"] {
min-width: 60% !important;
}
::v-deep .el-collapse-item__header {
border: none !important;
height: 36px !important;
line-height: 36px !important;
background: #d2c4e8 !important;
margin-top: 20px;
border-radius: 5px;
}
::v-deep.el-dropdown-menu__item:focus,
.el-dropdown-menu__item:not(.is-disabled):hover {
padding: 0;
}
::v-deep.el-collapse {
border: none !important;
}
::v-deep .el-collapse-item__wrap {
border: none !important;
}
.currencyBox {
margin: 0;
padding: 0;
width: 88%;
display: flex;
min-height: 200px;
flex-wrap: wrap;
padding: 10px 20px;
margin: 0 auto;
li {
list-style: none;
// width: calc(100% / 5);
display: flex;
flex-direction: column;
align-items: center !important;
margin-left: 10px;
// background: #D2C4E8;
// align-items: center;
// overflow: hidden;
padding: 5px 5px;
box-sizing: border-box;
// background: palegoldenrod;
img {
width: 25px;
}
p {
min-width: 50px;
margin-top: 8px;
font-size: 0.85rem;
word-wrap: break-word;
word-break: break-all;
text-align: center;
text-transform: capitalize;
}
}
}
.accountBox {
display: flex;
align-items: center;
padding: 8px 12px;
font-size: 0.8rem;
justify-content: space-between;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
.coinBox {
display: flex;
align-items: center;
img {
width: 20px;
}
.coin {
margin-left: 5px;
}
}
.coin {
text-transform: capitalize;
}
}
.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;
background: transparent;
}
</style>
<style lang="scss">
.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;
}
.el-submenu.is-active {
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;
}
.el-dropdown-menu__item,
.el-menu-item {
padding: 0px 10px !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,931 @@
<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
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="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`) ,
},
};
},
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);
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)
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");
if (dropdown.classList.contains("show")) {
dropdown.classList.remove("show");
arrow.classList.remove("up");
}
});
},
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))
}
},
async fetchSignOut() {
const data = await getLogout();
if (data && data.code == 200) {
const lang = this.$i18n.locale;
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() {
this.fetchSignOut();
localStorage.removeItem(`token`);
localStorage.removeItem("username");
localStorage.removeItem("jurisdiction");
this.$addStorageEvent(1, `miningAccountList`, JSON.stringify(""));
this.isLogin = false;
this.isDropdownVisible = false;
},
},
};
</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;
align-items: center;
height: 100%;
width: 95%;
/* outline: 1px solid red; */
// outline: 1PX solid red;
// padding: 0px 5%;
// padding: 0 5%;
// background: #21A0FF;
}
.logo {
width: 18%;
height: 100%;
display: flex;
justify-content: right;
align-items: center;
font-size: 0.9rem;
img {
width: 100px;
}
}
.topMenu {
width: 80%;
height: 100%;
display: flex;
justify-content: end;
align-items: center;
// background: goldenrod;
.afterLoggingIn {
min-width: 50%;
display: flex;
justify-content: right;
align-items: center;
// 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 {
width: 40%;
li {
margin-left: 1%;
}
.langBox {
display: flex;
justify-content: space-around;
align-items: center;
width: 20%;
}
.register.register {
padding: 1px 30px;
}
.LangLine {
width: 1px;
height: 60%;
background: #ccc;
margin-right: 2%;
}
}
}
.menuBox {
min-width: 42% !important;
height: 100%;
display: flex;
justify-content: end;
align-items: center;
margin: 0%;
// background: #fff;
li {
list-style: none;
// width: calc(100% / 5);
height: 45%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
margin-left: 3%;
font-size: 0.9rem;
// transition: all 0.3s linear;
position: relative;
text-align: center;
min-width: 61px;
}
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" >
.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;
}
</style>

View File

@@ -0,0 +1,119 @@
<!--提示框组件-->
<template>
<transition name="fade">
<div
ref="tooltip"
class="m-tooltip"
v-show="showTooltip"
@mouseenter="onShow"
@mouseleave="onHide"
:style="`max-width: ${maxWidth}PX; top: ${top}PX; left: ${left}PX;`"
>
<div class="u-tooltip-content">
<slot>暂无内容</slot>
</div>
<!-- 底部三角形 -->
<div class="u-tooltip-arrow"></div>
</div>
</transition>
</template>
<script>
export default {
name: "Tooltip",
props: {
maxWidth: {
// 提示框内容最大宽度
type: Number,
default: 120,
},
},
data() {
return {
showTooltip: false,
hideTimer: null,
top: 0, // 提示框top定位
left: 0, // 提示框left定位
};
},
methods: {
show(target) {
clearTimeout(this.hideTimer);
const rect = target.getBoundingClientRect();
const targetTop = rect.top + window.pageYOffset;
const targetLeft = rect.left + window.pageXOffset;
const targetWidth = rect.width;
this.showTooltip = true;
this.$nextTick(() => {
const tipWidth = this.$refs.tooltip.offsetWidth; // 提示框元素宽度
const tipHeight = this.$refs.tooltip.offsetHeight; // 提示框元素高度
this.top = targetTop - tipHeight;
this.left = targetLeft - (tipWidth - targetWidth) / 2;
});
},
onShow() {
clearTimeout(this.hideTimer);
this.showTooltip = true;
},
onHide() {
this.hideTimer = setTimeout(() => {
this.showTooltip = false;
}, 100);
},
},
};
</script>
<style lang="less" scoped>
// 渐变过渡效果
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: scale(0.8); // 缩放变换
-ms-transform: scale(0.8); /* IE 9 */
-webkit-transform: scale(0.8); /* Safari and Chrome */
}
// 滑动渐变过渡效果
.slide-fade-enter-active {
transition: all 0.3s ease;
}
.slide-fade-leave-active {
transition: all 0.3s ease;
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateY(6PX); // 滑动变换
-ms-transform: translateY(6PX); /* IE 9 */
-webkit-transform: translateY(6PX); /* Safari and Chrome */
opacity: 0;
}
.m-tooltip {
position: absolute;
top: 0;
z-index: 999;
padding-bottom: 6PX;
.u-tooltip-content {
padding: 10PX;
margin: 0 auto;
word-break: break-all;
word-wrap: break-word;
border-radius: 4PX;
font-weight: 400;
font-size: 14PX;
background: rgba(0,0,0,0.5);//背景颜色
color: #fff;
// box-shadow: 0PX 2PX 8PX 0PX rgba(0, 121, 221, 0.3);//修改阴影显示
}
.u-tooltip-arrow {
margin: 0 auto;
width: 0;
height: 0;
border-left: 2PX solid transparent;
border-right: 2PX solid transparent;
border-top: 4PX solid rgba(0,0,0,0.5);
}
}
</style>