Files
m2pool_web_frontend/mining-pool/src/components/BackAdminLayout.vue
2025-07-04 13:46:11 +08:00

275 lines
6.9 KiB
Vue

<template>
<el-container class="back-admin-layout" style="height: 100vh">
<!-- 顶部导航栏 -->
<el-header height="10vh" class="admin-header">
<div class="logo">
<img src="@/assets/img/logo.png" alt="logo" class="logo-img" />
<div class="logo-title">
<div>{{ $t("backendSystem.title") }}</div>
</div>
</div>
<div class="admin-header-right">
<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>
<el-dropdown>
<span class="el-dropdown-link"
>{{ userEmail }}<i class="el-icon-arrow-down el-icon--right"></i
></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handelSignOut"
index="999999">{{
$t("backendSystem.logout")
}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-header>
<el-container>
<!-- 侧边栏 -->
<comAside></comAside>
<!-- 主体内容 -->
<el-main class="admin-main">
<router-view v-if="key !== '/zh' && key !== '/en' &&key !== '/zh/login' && key !== '/en/login' && key !== '/zh/register' && key !== '/en/register'" :key="key" />
<div v-else style="color: #333;font-size: 16px;text-align: center;line-height: 100vh;">
{{ $t("backendSystem.leftNavigation") }}
</div>
</el-main>
</el-container>
</el-container>
</template>
<script>
import { getLogout } from "../api/login";
export default {
computed: {
key() {
return this.$route.path;
},
},
components: {
comAside: () => import("./comAside.vue"),
},
data() {
return {
filters: {
emailOrOrderNo: "",
status: "",
minAmount: null,
maxAmount: null,
dateRange: [],
},
activeTab: "all",
tableData: [
// 示例数据
{
index: 1,
email: "user@example.com",
orderNo: "20230601001",
type: "技术支持",
machineCode: "K9-001",
createTime: "2023-06-01",
fault: "无法启动",
status: "处理中",
amount: 844.01,
},
],
totalAmount: 844.01,
userEmail: null,
};
},
mounted() {
let userEmail = localStorage.getItem("userEmail");
try {
userEmail = userEmail ? JSON.parse(userEmail) : "";
} catch (e) {
userEmail = "";
}
this.userEmail = userEmail;
window.addEventListener("setItem", () => {
let userEmail = localStorage.getItem("userEmail");
try {
userEmail = userEmail ? JSON.parse(userEmail) : "";
} catch (e) {
userEmail = "";
}
this.userEmail = userEmail;
});
//网络变化
window.addEventListener("online", this.handleNetworkChange);
},
methods: {
async fetchSignOut() {
const data = await getLogout();
if (data && data.code == 200) {
// 调用 Vuex 的 logout action 清除前端状态
await this.$store.dispatch('logout')
}
},
handelSignOut() {
const lang = this.$i18n.locale;
this.$router.push(`/${lang}/login`);
localStorage.removeItem(`token`);
localStorage.removeItem("username");
localStorage.removeItem("jurisdiction");
this.$addStorageEvent(1, `miningAccountList`, JSON.stringify(""));
this.fetchSignOut();
},
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"));
}
},
// 处理网络状态变化
handleNetworkChange() {
if (navigator.onLine) {
// === 强制重置状态,兜底 ===
location.reload(); // 重新加载当前页面
}
},
},
beforeDestroy() {
window.removeEventListener("online", this.handleNetworkChange);
},
};
</script>
<style scoped>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.back-admin-layout {
width: 100vw;
height: 100vh;
background: #f5f6fa;
overflow: hidden;
}
.admin-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 15vh;
background: #fff;
border-bottom: 1px solid #eee;
padding: 0 32px;
}
.logo {
display: flex;
align-items: center;
}
.logo-img {
width: 6vw;
height: auto;
margin-right: 12px;
}
.logo-title {
font-size: 1vw;
font-weight: bold;
color: rgba(0, 0, 0, 0.6);
}
.logo-sub {
font-size: 12px;
color: #888;
}
.admin-header-right {
display: flex;
align-items: center;
gap: 24px;
}
.lang {
color: #333;
font-size: 14px;
margin-left: 16px;
}
.admin-main {
background: #fff;
margin: 24px;
border-radius: 8px;
padding: 30px;
min-width: 0;
min-height: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
display: flex;
flex-direction: column;
/* background: palegoldenrod; */
height: 84vh ;
overflow: hidden;
/* overflow-y: auto; */
}
.main-title {
font-size: 22px;
font-weight: bold;
margin-bottom: 18px;
}
.main-filters {
margin-bottom: 18px;
}
/* ------------侧边栏----- */
</style>