新增后台系统 发布广播相关功能

This commit is contained in:
yaoqin 2025-06-25 17:08:47 +08:00
parent 0dbb43233a
commit 2111eedabb
51 changed files with 2347 additions and 844 deletions

Binary file not shown.

View File

@ -1,58 +1,98 @@
<template>
<div id="app">
<router-view class="page" />
<ChatWidget v-if="!$route.path.includes('/customerService') && !$isMobile" />
<ChatWidget v-if="!$route.path.includes('/customerService') && !$isMobile && jurisdiction.roleKey !== 'back_admin'" />
</div>
</template>
<script >
import ChatWidget from '../src/components/ChatWidget.vue';
import { Debounce, throttle } from '@/utils/publicMethods';
import Vue from 'vue'
import ChatWidget from "../src/components/ChatWidget.vue";
import { Debounce, throttle } from "@/utils/publicMethods";
import Vue from "vue";
export default {
name: 'App',
name: "App",
components: {
ChatWidget
ChatWidget,
},
data() {
return {
flag: false,
isMobile: false,
jurisdiction: {
roleKey: "",
},
};
},
created() {
window.addEventListener("resize", Debounce(this.updateWindowWidth, 10));
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction ? JSON.parse(jurisdiction) : { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
window.addEventListener("setItem", () => {
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction
? JSON.parse(jurisdiction)
: { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
});
},
mounted() {
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction ? JSON.parse(jurisdiction) : { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
window.addEventListener("setItem", () => {
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction
? JSON.parse(jurisdiction)
: { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
});
},
beforeDestroy() {
window.removeEventListener("resize", this.updateWindowWidth); //
},
methods: {
updateWindowWidth() {
console.log(window.innerWidth ||
console.log(
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth)
document.body.clientWidth
);
//
const screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
const screenWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
const isNarrowScreen = screenWidth < 1280;
Vue.prototype.$isMobile = isNarrowScreen
Vue.prototype.$isMobile = isNarrowScreen;
location.reload();
}
}
}
},
},
};
</script>
<style lang="scss">
:root {
--background-color: #ffffff;
--text-color: #000000;
@ -67,16 +107,14 @@ import Vue from 'vue'
padding: 0;
box-sizing: border-box;
}
html,body{
html,
body {
//
scrollbar-width: none;
-ms-overflow-style: none;
border-right: none;
box-sizing: border-box;
overflow: hidden;
}
#app {
// font-family: Avenir, Helvetica, Arial, sans-serif;
@ -90,16 +128,14 @@ html,body{
/* 滚动条整体部分 */
font-size: 1rem;
::-webkit-scrollbar {
width: 5PX; /* 宽度 */
width: 5px; /* 宽度 */
height: 6px; /* 高度 */
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background-color: #D2C3E9; /* 滑块颜色 */
border-radius: 20PX; /* 圆角 */
background-color: #d2c3e9; /* 滑块颜色 */
border-radius: 20px; /* 圆角 */
}
/* 滚动条轨道 */
@ -115,15 +151,12 @@ input::-webkit-inner-spin-button {
input[type="number"] {
-moz-appearance: textfield;
}
}
.el-message{ //
.el-message {
//
z-index: 99999 !important;
min-width: 300px !important;
}
</style>

View File

@ -0,0 +1,54 @@
import request from '../utils/request'
//用于获取m2pool广播数据 主页循环播放
export function getBroadcast(data) {
return request({
url: `manage/broadcast/find/data/by/id`,
method: 'post',
data
})
}
//新增广播
export function getAddBroadcast(data) {
return request({
url: `manage/broadcast/add`,
method: 'post',
data
})
}
//删除广播
export function DeleteBroadcast(data) {
return request({
url: `manage/broadcast/delete`,
method: 'post',
data
})
}
//分页查询所有广播信息
export function listBroadcast(data) {
return request({
url: `manage/broadcast/get/list/by/page`,
method: 'post',
data
})
}
//修改广播内容
export function updateBroadcast(data) {
return request({
url: `manage/broadcast/update`,
method: 'post',
data
})
}
//修改查看通知详情
export function dataInfo(data) {
return request({
url: `manage/broadcast/find/data/info`,
method: 'post',
data
})
}

View File

@ -0,0 +1,30 @@
import request from '../utils/request'
//根据条件 查询注册用户列表
export function getUserList(data) {
return request({
url: `manage/user/list/info`,
method: 'post',
data
})
}
//发送邮件给用户
export function sendMail(data) {
return request({
url: `manage/user/send/text/mail/message`,
method: 'post',
data
})
}
// //发送邮件给用户
// export function sendMail(data) {
// return request({
// url: `manage/user/get/user/info`,
// method: 'post',
// data
// })
// }

View File

@ -0,0 +1,255 @@
<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 !== '/'" :key="key" />
</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;
});
},
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"));
}
});
// HTMLlang
document.documentElement.lang = lang;
} catch (error) {
console.error("语言切换失败:", error);
this.$message.error(this.$t("common.langChangeFailed"));
}
},
},
};
</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>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
<template>
<el-aside
style="height: 100vh; background: #202940;width: 280px;padding: 0;"
class="admin-sidebar"
>
<el-menu
style="border: none;width: 280px;"
:default-active="activeIndex"
class="el-menu-vertical-demo"
background-color="#202940"
text-color="#fff"
active-text-color="#ffd04b"
>
<div v-for="item in menuList" :key="item.id">
<el-menu-item @click="handleClick(item)" v-show="!item.children" :index="item.id" style="padding-left: 20px !important;">
<i :class="item.icon"></i>
<span slot="title">{{ $t(item.label)}}</span>
</el-menu-item>
<el-submenu :index="item.id" v-if="item.children" >
<template slot="title">
<i :class="item.icon"></i>
<span>{{$t(item.label)}}</span>
</template>
<el-menu-item @click="handleClick(child)" v-for="child in item.children" :key="child.id" :index="child.id" style="padding-left: 40px !important;">
<i :class="child.icon"></i>
<span slot="title">{{$t(child.label)}}</span>
</el-menu-item>
</el-submenu>
</div>
</el-menu>
</el-aside>
</template>
<script>
export default {
data(){
return {
menuList:[
{//广
path:"broadcast",
label:`backendSystem.broadcast`,
icon:"el-icon-bell",
id:"1",
},
// {//
// path:"userManagement",
// label:`backendSystem.userManagement`,
// icon:"el-icon-user",
// id:"2",
// },
// {//
// path:"workOrderBackend",
// label:`backendSystem.workOrder`,
// icon:"el-icon-document-copy",
// id:"3",
// },
// {//
// path:"userComputingPower",
// label:`backendSystem.userComputingPower`,
// icon:"el-icon-finished",
// id:"4",
// },
],
activeIndex:"1",
}
},
mounted(){
if(localStorage.getItem("activeIndex")){
this.activeIndex = localStorage.getItem("activeIndex");
}else{
this.$addStorageEvent(1, "activeIndex", this.activeIndex);
this.activeIndex ="1"
}
},
methods:{
handleClick(item){
this.activeIndex = item.id;
this.$addStorageEvent(1, "activeIndex", item.id);
const lang = this.$i18n.locale;
this.$router.push(`/${lang}/${item.path}`);
}
}
};
</script>
<style scoped lang="scss">
.el-submenu .el-menu-item{
padding-left: 40px !important;
}
</style>

View File

@ -0,0 +1,69 @@
export const backendSystem_zh = {
backendSystem: {
title: "后台管理系统",
broadcast: "广播",
userManagement: "用户管理",
workOrder: "工单管理",
workOrderRecord: "工单记录",
userComputingPower: "用户算力",
addBroadcast: "新增广播",
editBroadcast: "修 改",
publishedBroadcast: "已发布广播",
createTime: "创建时间",
content: "内容",
createUser: "创建人",
updateTime: "修改时间",
updateUser: "修改人",
operation: "操作",
edit: "编辑",
exceedingInput:"超出输入最大限制",
deleteRemind:"确定删除该广播吗?",
deleteSuccess:"删除成功",
editSuccess:"修改成功",
addSuccess:"发布成功",
cancel:"取 消",
publish:"发 布",
logout:"退出",
editContent:"修改广播内容",
dialogTitle:"新增广播内容",
pleaseInputContent:"请输入广播内容",
newlineInvalid:"广播内容输入换行符无效",
}
}
export const backendSystem_en = {
backendSystem: {
title: "Backend System",
broadcast: "Broadcast",
userManagement: "User Management",
workOrder: "Work Order Management",
workOrderRecord: "Work Order Record",
userComputingPower: "User Computing Power",
addBroadcast: "Add Broadcast",
editBroadcast: "Modify",
publishedBroadcast: "Published Broadcast",
createTime: "Create Time",
content: "Content",
createUser: "Create User",
updateTime: "Update Time",
updateUser: "Update User",
operation: "Operation",
edit: "Edit",
exceedingInput:"Exceeding Input Maximum Limit",
deleteRemind:"Are you sure you want to delete this broadcast?",
deleteSuccess:"Delete Success",
editSuccess:"Edit Success",
addSuccess:"Add Success",
cancel:"Cancel",
publish:"Publish",
logout:"Logout",
editContent:"Edit Broadcast Content",
dialogTitle:"Add Broadcast Content",
pleaseInputContent:"Please input broadcast content",
newlineInvalid:"Invalid line break for broadcasting content input",
}
}

View File

@ -12,6 +12,8 @@ import {alerts_zh,alerts_en} from'./alerts'
import {seo_zh,seo_en} from'./seo'
import {chooseUs_zh,chooseUs_en} from'./dataDisplay'
import {ChatWidget_zh,ChatWidget_en} from'./ChatWidget'
import {backendSystem_zh,backendSystem_en} from'./backendSystem'
@ -32,6 +34,7 @@ export default {
...seo_zh,
...chooseUs_zh,
...ChatWidget_zh,
...backendSystem_zh,
},
@ -52,6 +55,7 @@ export default {
...seo_en,
...chooseUs_en,
...ChatWidget_en,
...backendSystem_en,

View File

@ -29,6 +29,8 @@ export const seo_zh = {
allocationExplanation: "M2Pool 矿池分配及转账说明页面,详细介绍各币种的成熟条件、出块间隔及预估时间,何时将挖矿收益分配及转账至用户账户,提供用户清晰的了解分配及转账指南。",
enxAccess: "Entropyx(enx) 接入页面,详细介绍如何接入 M2Pool 矿池进行 enx 币种挖矿,提供用户便捷的接入指南,轻松开启挖矿之旅。",
alphAccess: "Alephium(alph) 接入页面,详细介绍如何接入 M2Pool 矿池进行 Alephium(alph) 币种挖矿,提供用户便捷的接入指南,轻松开启挖矿之旅。",
broadcast: "M2Pool 矿池广播页面,管理员可在此查看已发布的广播信息,包括广播内容、发布时间、发布者等。",
userManagement: "M2Pool 矿池用户管理页面,管理员可在此查看所有用户信息,包括用户名、邮箱、注册时间、登录时间等。",
}
}
@ -53,5 +55,9 @@ export const seo_en = {
allocationExplanation: "The M2Pool mining pool allocation and transfer instructions page provides detailed information on the maturity conditions, block interval, and estimated time of each currency, as well as when to allocate and transfer mining profits to user accounts, providing users with a clear understanding of allocation and transfer guidelines.",
enxAccess: "Entropyx (enx) access page provides detailed instructions on how to access the M2Pool mining pool for enx currency mining, offering users a convenient access guide to easily start their mining journey.",
alphAccess: "The M2Pool Alephium(alph) access page provides detailed instructions on how to access the M2Pool mining pool for Alephium(alph) currency mining, offering users a convenient access guide to easily start their mining journey.",
broadcast: "M2Pool mining pool broadcast page, where administrators can view published broadcast information, including broadcast content, release time, publisher, etc.",
userManagement: "M2Pool mining pool user management page, where administrators can view all user information, including user name, email, registration time, login time, etc.",
}
}

View File

@ -1,5 +1,7 @@
<template>
<el-container style="width: 100vw;height: 100vh;" class="containerApp" >
<BackAdminLayout v-if="jurisdiction && jurisdiction.roleKey === 'back_admin'"> </BackAdminLayout>
<el-container v-else style="width: 100vw;height: 100vh;" class="containerApp" >
<el-header class="el-header" >
<MoveHead v-if="$isMobile"></MoveHead>
<comHeard v-else></comHeard>
@ -7,7 +9,6 @@
<el-main>
<appMain></appMain>
</el-main>
</el-container>
@ -19,8 +20,35 @@ export default {
comHeard: () => import("../components/header.vue"),
appMain: () => import("../components/content.vue"),
MoveHead: () => import("../components/MoveHead.vue"),
BackAdminLayout: () => import("../components/BackAdminLayout.vue"),
},
data(){
return {
jurisdiction: {
roleKey: "",
},
}
},
mounted(){
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction ? JSON.parse(jurisdiction) : { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
window.addEventListener("setItem", () => {
let jurisdiction = localStorage.getItem("jurisdiction");
try {
jurisdiction = jurisdiction ? JSON.parse(jurisdiction) : { roleKey: "" };
} catch (e) {
jurisdiction = { roleKey: "" };
}
this.jurisdiction = jurisdiction;
});
}
}
</script>

View File

@ -28,8 +28,8 @@ Vue.prototype.$axios = axios
console.log = ()=>{} //全局关闭打印
// 全局注册混入
Vue.mixin(loadingStateMixin);
Vue.mixin(networkRecoveryMixin);
Vue.mixin(loadingStateMixin);//loading状态管理
Vue.mixin(networkRecoveryMixin);//网络恢复后数据刷新
Vue.prototype.$baseApi = process.env.VUE_APP_BASE_URL //图片base路径
const screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

View File

@ -32,7 +32,7 @@ const childrenRoutes = [
component: () => import('../views/miningAccount/index.vue'),
meta: {title: '挖矿账户页面',
description:i18n.t(`seo.miningAccount`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool mining account, crypto mining stats, mining rewards, hashrate monitor, 矿池账户, 挖矿收益, 算力监控'
keywords:{
en: 'M2Pool mining account, crypto mining stats, mining rewards, hashrate monitor, 矿池账户, 挖矿收益, 算力监控',
@ -63,7 +63,7 @@ const childrenRoutes = [
component: () => import('../views/reportBlock/index.vue'),
meta: {title: '报块页面',
description:i18n.t(`seo.reportBlock`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,报块页面,幸运值,区块高度,Block page,Lucky Value,block height,Mining Pool'
keywords:{
en: 'Block page,Lucky Value,block height,Mining Pool',
@ -73,6 +73,34 @@ const childrenRoutes = [
}
},
{//报块页面
path: 'broadcast',
name: 'Broadcast',
component: () => import('../views/broadcast/index.vue'),
meta: {title: '广播页面',
description:i18n.t(`seo.broadcast`),
allAuthority:[`admin`,`back_admin`],
keywords:{
en: 'broadcast',
zh: '广播'
}
}
},
{//报块页面
path: 'userManagement',
name: 'UserManagement',
component: () => import('../views/userManagement/index.vue'),
meta: {title: '用户管理',
description:i18n.t(`seo.userManagement`),
allAuthority:[`admin`,`back_admin`],
keywords:{
en: 'userManagement',
zh: '用户管理'
}
}
},
{//费率
path: 'rate',
name: 'Rate',
@ -124,7 +152,7 @@ const childrenRoutes = [
component: () => import('../views/customerService/index.vue'),
meta: {title: '在线客服',
description:i18n.t(`seo.apiFile`),
allAuthority:[`customer_service`],//客服权限
allAuthority:[`customer_service`,`admin`,],//客服权限
// keywords: 'M2Pool 矿池,API 文档,认证 token,接口调用,API file,authentication token,Interface call'
keywords:{
en: 'API file,authentication token,Interface call',
@ -308,7 +336,7 @@ const childrenRoutes = [
component: () => import('../views/submitWorkOrder/index.vue'),
meta: {title: '提交工单页面',
description:i18n.t(`seo.submitWorkOrder`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,提交工单,技术支持,问题处理,Mining Pool,Work Order Submission, Technical Support, Troubleshooting'
keywords:{
en: 'Mining Pool,Work Order Submission, Technical Support, Troubleshooting',
@ -322,7 +350,7 @@ const childrenRoutes = [
component: () => import('../views/workOrderRecords/index.vue'),
meta: {title: '工单记录页面(用户)',
description:i18n.t(`seo.workOrderRecords`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,用户工单记录,处理状态,问题进度,User Work Order Records, Processing Status, Issue Progress'
keywords:{
en: 'User Work Order Records, Processing Status, Issue Progress',
@ -336,7 +364,7 @@ const childrenRoutes = [
component: () => import('../views/userWorkDetails/index.vue'),
meta: {title: '工单详情页面(用户)',
description:i18n.t(`seo.userWorkDetails`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,用户工单详情,问题描述,补充提交,User Work Order Details, Problem Description, Additional Submissions'
keywords:{
en: 'User Work Order Details, Problem Description, Additional Submissions',
@ -350,7 +378,7 @@ const childrenRoutes = [
component: () => import('../views/workOrderBackend/index.vue'),
meta: {title: '工单管理页面(后台)',
description:"M2Pool 矿池后台工单管理页面,供 M2Pool 管理员查看和管理用户提交的工单记录,确保问题及时处理,提升用户体验。",
allAuthority:[`admin`],
allAuthority:[`admin`,`back_admin`],
// keywords: 'M2Pool 矿池,后台工单管理,用户工单,及时处理,Back-office work order management, user work orders, timely processing'
keywords:{
en: 'Back-office work order management, user work orders, timely processing',
@ -364,7 +392,7 @@ const childrenRoutes = [
component: () => import('../views/BKWorkDetails/index.vue'),
meta: {title: '工单详情页面(后台)',
description:"M2Pool 矿池后台工单详情页面,管理员可在此查看提交工单的详细情况,包括提交时间、详细问题描述以及处理过程,并通过本页面对该工单进行回复处理。",
allAuthority:[`admin`],
allAuthority:[`admin`,`back_admin`],
// keywords: 'M2Pool 矿池,后台工单详情,问题处理,回复工单,Backend Work Order Details, Problem Handling, Responding to Work Orders'
keywords:{
en: 'Backend Work Order Details, Problem Handling, Responding to Work Orders',
@ -392,7 +420,7 @@ const childrenRoutes = [
component: () => import('../views/alerts/index.vue'),
meta: {title: '警报通知',
description:i18n.t(`seo.alerts`),
allAuthority:[`admin`,`registered`],
allAuthority:[`admin`,`registered`,`back_admin`],
// keywords: 'M2Pool, 矿池,离线告警设置,矿机离线,Mining Pool,Offline Alarm Setting,Mining Machine Offline'
keywords:{
en: 'Mining Pool,Offline Alarm Setting,Mining Machine Offline',
@ -408,7 +436,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/index.vue'),
meta: {title: '个人中心页面',
description:i18n.t(`seo.personalCenter`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人中心,挖矿账户,只读页面设置安全设置API密钥生成,Personal Center,Mining Account,Read-Only Page Setup,Security Settings,API Key Generation'
keywords:{
en: 'Personal Center,Mining Account,Read-Only Page Setup,Security Settings,API Key Generation',
@ -422,7 +450,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/personalMining/index.vue'),
meta: {title: '挖矿账户设置页面',
description:i18n.t(`seo.personalMining`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人中心,挖矿账户设置,币种账户,Personal Center,Mining Account Settings,Coin Accounts'
keywords:{
en: 'Personal Center,Mining Account Settings,Coin Accounts',
@ -436,7 +464,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/readOnly/index.vue'),
meta: {title: '只读页面设置',
description:i18n.t(`seo.readOnly`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人中心,只读页面设置,矿池分享,Personal Center,Read-Only Page Setting,Mining Pool Sharing'
keywords:{
en: 'Personal Center,Read-Only Page Setting,Mining Pool Sharing',
@ -450,7 +478,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/securitySetting/index.vue'),
meta: {title: '安全设置页面',
description:i18n.t(`seo.securitySetting`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,安全设置,密码修改,Security settings, password change'
keywords:{
en: 'Security settings, password change',
@ -464,7 +492,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/personal/index.vue'),
meta: {title: '个人信息页面',
description:i18n.t(`seo.personal`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人信息,登录历史,Personal Information, Login History'
keywords:{
en: 'Personal Information, Login History',
@ -478,7 +506,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/miningReport/index.vue'),
meta: {title: '挖矿报告页面',
description:i18n.t(`seo.miningReport`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人中心,挖矿报告,订阅服务,Mining Report, Subscription Service'
keywords:{
en: 'Mining Report, Subscription Service',
@ -493,7 +521,7 @@ const childrenRoutes = [
component: () => import('../views/personalCenter/personalAPI/index.vue'),
meta: {title: 'API页面',
description:i18n.t(`seo.personalAPI`),
allAuthority:[`admin`,`registered`,`customer_service`],
allAuthority:[`admin`,`registered`,`customer_service`,`back_admin`],
// keywords: 'M2Pool 矿池,个人中心,API 页面,API密钥生成,API Page,API Key Generation'
keywords:{
en: 'API Page,API Key Generation',

View File

@ -1962,7 +1962,7 @@ a{
transition: 0.3s all;
}
.rateBox {
width: 75%;
width: 90%;
height: 830px;
margin: 0 auto;
display: flex;
@ -2063,13 +2063,16 @@ a{
height: 35px;
line-height: 35px;
font-weight: bold;
overflow: hidden;
}
div {
width: 75%;
box-sizing: border-box;
width: 95%;
display: flex;
height: 120px;
font-size: 0.9rem;
align-items: center;
overflow-y: auto;
span {
width: 100%;

View File

@ -0,0 +1,192 @@
import { listBroadcast, getAddBroadcast, updateBroadcast, DeleteBroadcast, getBroadcast,dataInfo } from '../../api/broadcast'
export default {
data() {
return {
tableData: [
// {
// id: 1,
// createTime: "2025-06-24 10:00:00",
// content: "内isjisjfidjfjfjffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff容",
// createUser: "创建人",
// updateTime: "2025-06-24 10:00:00",
// updateUser: "修改人",
// },
// {
// id: 2,
// createTime: "2025-06-24 10:00:00",
// content: "内容",
// createUser: "创建人",
// updateTime: "2025-06-24 10:00:00",
// updateUser: "修改人",
// },
],
listParams: {
pageNum: 1,
pageSize: 50
},
addParams: {
content: "",
},
editParams: {
content: "",
id: "",
},
dialogVisible: false,
bthLoading: false,
broadcastLoading: false,
editDialogVisible: false,
editLoading: false,
byteCount: "",
isOverLimit: false,
}
},
mounted() {
let token
try{
token =JSON.parse(localStorage.getItem('token'))
}catch(e){
console.log(e);
}
if (token) {
this.fetchList(this.listParams);
}
},
methods: {
async fetchList(params) {
this.setLoading('broadcastLoading', true);
const res = await listBroadcast(params)
if (res.code === 200) {
this.tableData = res.rows
}
this.setLoading('broadcastLoading', false);
},
async addBroadcast(params) {
this.setLoading('bthLoading', true);
const res = await getAddBroadcast(params)
if (res.code === 200) {
this.$message.success(this.$t("backendSystem.addSuccess"))
this.dialogVisible = false;
this.fetchList(this.listParams);
}
this.setLoading('bthLoading', false);
},
async getBroadcast(params) {
this.setLoading('editLoading', true);
const res = await dataInfo(params)
if (res.code === 200) {
this.editParams = res.data
this.editDialogVisible = true;
}
this.setLoading('editLoading', false);
},
async editBroadcast(params) {
this.setLoading('editLoading', true);
const res = await updateBroadcast(params)
if (res.code === 200) {
this.$message.success(this.$t("backendSystem.editSuccess"))
this.editDialogVisible = false;
this.fetchList(this.listParams);
}
this.setLoading('editLoading', false);
},
async deleteBroadcast(params) {
const res = await DeleteBroadcast(params)
if (res.code === 200) {
this.$message.success(this.$t("backendSystem.deleteSuccess"))
this.fetchList(this.listParams);
}
},
handelAddBroadcast() {
this.dialogVisible = true;
},
handleClose() {
this.dialogVisible = false;
this.addParams.content = ""
},
sureAddBroadcast() {
this.addParams.content = this.addParams.content.trim()
this.addParams.content = this.addParams.content.replace(/[\r\n]/g, '');
if (!this.addParams.content) {
this.$message.warning(this.$t("backendSystem.pleaseInputContent"))
return
}
this.addBroadcast(this.addParams);
},
sureEditBroadcast() {
this.editParams.content=this.editParams.content.trim()
this.editParams.content = this.editParams.content.replace(/[\r\n]/g, '');
if (!this.editParams.content) {
this.$message.warning(this.$t("backendSystem.pleaseInputContent"))
return
}
this.editBroadcast(this.editParams);
},
handleEdit(row) {
this.getBroadcast({ id: row.id });
},
handleEditClose() {
this.editDialogVisible = false;
this.editParams.content = ""
},
handelDelete(row) {
this.deleteBroadcast({ id: row.id });
},
getUtf8Bytes(str) {
let bytes = 0;
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (code <= 0x7f) bytes += 1;
else if (code <= 0x7ff) bytes += 2;
else if (code <= 0xffff) bytes += 3;
else bytes += 4;
}
return bytes;
},
handleInput(val, type = 'add') {
let bytes = this.getUtf8Bytes(val);
if (bytes > 100) {
this.isOverLimit = true;
// 截断到100字节
let newVal = '';
let total = 0;
for (let ch of val) {
let chBytes = this.getUtf8Bytes(ch);
if (total + chBytes > 100) break;
newVal += ch;
total += chBytes;
}
if (type === 'add') {
this.addParams.content = newVal;
} else {
this.editParams.content = newVal;
}
bytes = total;
} else {
this.isOverLimit = false;
if (type === 'add') {
this.addParams.content = val;
} else {
this.editParams.content = val;
}
}
this.byteCount = bytes;
},
handelTime(time) {
return `${time.split("T")[0]} ${time.split("T")[1]}`
}
}
}

View File

@ -0,0 +1,153 @@
<template>
<div v-loading="broadcastLoading">
<div class="main-title-box">
<div class="main-title">{{$t("backendSystem.publishedBroadcast")}}</div>
<el-button class="add-btn" @click="handelAddBroadcast">{{$t("backendSystem.addBroadcast")}} <i class="iconfont icon-youjiantou1 arrow"></i></el-button>
</div>
<el-table
:data="tableData"
border
style="width: 100%; margin-bottom: 18px"
:header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }"
>
<el-table-column prop="id" label="ID" width="60" show-overflow-tooltip />
<el-table-column prop="createTime" :label="$t('backendSystem.createTime')" width="160" show-overflow-tooltip>
<template slot-scope="scope">
{{ handelTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column prop="content" :label="$t('backendSystem.content')" show-overflow-tooltip/>
<el-table-column prop="createUser" :label="$t('backendSystem.createUser')" width="160" show-overflow-tooltip/>
<el-table-column prop="updateTime" :label="$t('backendSystem.updateTime')" width="160" show-overflow-tooltip>
<template slot-scope="scope">
{{ handelTime(scope.row.updateTime) }}
</template>
</el-table-column>
<el-table-column prop="updateUser" :label="$t('backendSystem.updateUser')" width="160" show-overflow-tooltip/>
<el-table-column :label="$t('backendSystem.operation')" width="160" >
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.row)">{{$t("backendSystem.edit")}}</el-button>
<el-popconfirm
:confirm-button-text='$t(`work.confirm`)'
:cancel-button-text='$t(`work.cancel`)'
icon="el-icon-info"
icon-color="red"
:title="$t(`alerts.deleteRemind`)"
@confirm="handelDelete(scope.row)"
>
<el-button class="elBtn" size="mini" slot="reference">{{ $t(`personal.delete`) }}</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 新增广播弹窗 -->
<el-dialog
:title="$t('backendSystem.dialogTitle')"
:visible.sync="dialogVisible"
width="50%"
:before-close="handleClose"
:close-on-click-modal="false"
>
<el-form :model="addParams" >
<!-- v-if="isOverLimit" -->
<el-form-item >
<el-input resize="none" v-model="addParams.content" type="textarea" :rows="5" @input="val => handleInput(val, 'add')" />
<div style="color: #999; font-size: 12px; margin-top: 4px;display: flex;align-items: center;justify-content: space-between;">
<span v-if="isOverLimit"> {{$t("backendSystem.exceedingInput")}}</span>
<span> {{$t("backendSystem.newlineInvalid")}}</span>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">{{$t("backendSystem.cancel")}}</el-button>
<el-button type="primary" :loading="bthLoading" @click="sureAddBroadcast">{{$t("backendSystem.publish")}}</el-button>
</div>
</el-dialog>
<!-- 修改广播弹窗 -->
<el-dialog
:title="$t('backendSystem.editContent')"
:visible.sync="editDialogVisible"
width="50%"
:before-close="handleEditClose"
:close-on-click-modal="false"
>
<el-form :model="editParams" >
<el-form-item >
<el-input resize="none" v-model="editParams.content" type="textarea" :rows="5" @input="val => handleInput(val, 'edit')" />
<div style="color: #999; font-size: 12px; margin-top: 4px;display: flex;align-items: center;justify-content: space-between;">
<span v-if="isOverLimit"> {{$t("backendSystem.exceedingInput")}}</span>
<span> {{$t("backendSystem.newlineInvalid")}}</span>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleEditClose">{{$t("backendSystem.cancel")}}</el-button>
<el-button type="primary" :loading="editLoading" @click="sureEditBroadcast">{{$t("backendSystem.editBroadcast")}}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import Index from './index'
export default {
mixins:[Index],
}
</script>
<style scoped lang="scss">
.main-title-box{
display: flex;
align-items: center;
margin-bottom: 20px;
.add-btn{
background: #661FFB;
color: #fff;
border:none;
margin-left: 28px;
border-radius: 20px;
padding: 10px 20px;
transition: all 0.3s ease;
.arrow{
margin-left: 10px;
}
}
.add-btn:hover{
transform: scale(1.05);
}
}
.main-title{
font-size: 24px;
font-weight: bold;
color: #333;
}
.elBtn{
background: #e60751;
color: #fff;
border:none;
margin-left: 18px;
}
</style>

View File

@ -123,6 +123,7 @@
v-else-if="currentContact"
size="small"
type="info"
style="cursor: pointer;"
@click="
toggleImportant(
currentContact.roomId,
@ -279,6 +280,7 @@
:rows="3"
:maxlength="400"
:disabled="!currentContact"
resize="none"
:placeholder="
$t(`chat.inputMessage`) ||
`请输入消息按Enter键发送按Ctrl+Enter键换行`

View File

@ -1,6 +1,6 @@
import { watch } from "vue";
import { getCoinInfo, getPoolPower, getMinerCount, getLuck, getBlockInfo, getNetPower, getParam } from "../../api/home"
import { listBroadcast,getBroadcast} from "../../api/broadcast"
import { line } from "../../utils/echarts";
import * as echarts from "echarts";
import { Debounce, throttle } from "../../utils/publicMethods";
@ -768,13 +768,29 @@ export default {
},
isInternalChange: false,
broadcastList: [
{ id: `b1`, content: this.$t(`home.describe`) },
],
currentBroadcastIndex: 0,
scrollTimer: null,
isTransition: true,
};
},
computed: {
// 末尾加一条"克隆的第一条"用于无缝滚动
broadcastListForLoop() {
if (this.broadcastList.length === 0) return [];
if (this.broadcastList.length === 1) return this.broadcastList;
return [...this.broadcastList, this.broadcastList[0]];
},
scrollStyle() {
return {
transform: `translateY(-${this.currentBroadcastIndex * 30}px)`,
transition: this.isTransition ? 'transform 0.5s cubic-bezier(.4,0,.2,1)' : 'none',
};
},
},
watch: {
"$i18n.locale": (val) => {
location.reload();//刷新页面 刷新echarts
@ -792,9 +808,6 @@ export default {
}
},
mounted() {
this.lang = this.$i18n.locale; // 初始化语言值
this.$addStorageEvent(1, `activeItemCoin`, JSON.stringify(this.currencyList[0]))
this.minerChartLoading = true
@ -903,11 +916,38 @@ export default {
this.activeItemCoin = JSON.parse(value)
});
// this.getBroadcastList({pageNum:1,pageSize:100})
this.getBroadcastList()
this.startScroll();
this.$nextTick(() => {
this.startScroll();
});
window.addEventListener('resize', this.setItemHeight);
},
methods: {
//获取广播列表
async getBroadcastList(params){
// const data = await listBroadcast(params)
const data = await getBroadcast(params)
if (data && data.code == 200) {
this.broadcastList =[...this.broadcastList,...data.data]
this.currentBroadcastIndex = 0; // 新数据时重置索引
if(this.broadcastList.length > 1){
this.$nextTick(() => {
this.startScroll();
});
}
}
},
handelOptionYAxis(option){
const yAxis = option.yAxis[0]; // 第一个 Y 轴
@ -1100,6 +1140,8 @@ export default {
// let leftYMaxData = Math.max(...pvData);
// this.option.yAxis[0].max =leftYMaxData*2
this.option.xAxis.data = xData
this.option.yAxis[0].name = chartData[0].unit
this.option.series[0].data = pvData
// this.option.series[1].data = rejectRate
this.option.series[1].data = price
@ -1159,6 +1201,7 @@ export default {
this.minerOption.xAxis.data = xData
this.minerOption.yAxis[0].name = MinerCount[0].unit
this.minerOption.series[0].data = pvData
this.minerOption.series[1].data = price
this.$nextTick(() => {
@ -1683,10 +1726,27 @@ scrollRight() {
}
},
startScroll() {
if (this.scrollTimer) clearInterval(this.scrollTimer);
// 只有多于1条才滚动
if (this.broadcastList.length <= 1) return;
this.scrollTimer = setInterval(this.nextScroll, 3000);
},
nextScroll() {
if (this.broadcastList.length <= 1) return;
this.isTransition = true;
this.currentBroadcastIndex += 1;
// 如果到"克隆的第一条"0.5s后瞬间跳回真正的第一条
if (this.currentBroadcastIndex === this.broadcastList.length) {
setTimeout(() => {
this.isTransition = false;
this.currentBroadcastIndex = 0;
}, 500);
}
},
},
beforeDestroy() {
if (this.scrollTimer) clearInterval(this.scrollTimer);
},
}

View File

@ -1,16 +1,17 @@
<template>
<div>
<section v-if="$isMobile">
<div class="imgTop">
<img src="../../assets/mobile/home/home.png" alt="mining" loading="lazy" />
<img
src="../../assets/mobile/home/home.png"
alt="mining"
loading="lazy"
/>
<!--
<img v-if="lang == 'zh'" src="../../assets/img/enx推广.png" alt="mining" loading="lazy"/>
<img v-else src="../../assets/img/enx英文推广.png" alt="mining" loading="lazy"/> -->
</div>
<div class="currencySelect">
<el-menu class="el-menu-demo" mode="horizontal">
<el-submenu index="1" style="background: transparent">
@ -22,20 +23,21 @@
</template>
<ul class="moveCurrencyBox">
<li @click="clickCurrency(item)" v-for="item in currencyList" :key="item.value">
<li
@click="clickCurrency(item)"
v-for="item in currencyList"
:key="item.value"
>
<img :src="item.img" alt="coin" loading="lazy" />
<p>{{ item.label }}</p>
</li>
</ul>
</el-submenu>
</el-menu>
</div>
<div class="miningPoolLeft" v-loading="minerChartLoading">
<div class="interval">
<div class="chartBth">
<div class="slideBox">
<span
@ -70,11 +72,32 @@
<div
id="minerChart"
v-if="!powerActive"
style="width: 100%; height: 100%;min-width: 200px;min-height: 380px;"
style="width: 100%; height: 100%; min-width: 200px; min-height: 380px"
></div>
</div>
<section class="describeBox2">
<p> <i class="iconfont icon-tishishuoming "></i><span class="describeTitle">{{ $t(`home.describeTitle`) }}</span>{{ $t(`home.describe`) }} <span class="view" @click="handelJump(`/allocationExplanation`)"> {{ $t(`home.view`) }} </span> </p>
<section class="describeBox">
<p class="describe-row">
<i class="iconfont icon-tishishuoming"></i>
<span class="describeTitle">{{ $t(`home.describeTitle`) }}</span>
<span class="broadcast-scroll-wrap">
<div
class="broadcast-scroll-list"
:style="scrollStyle"
ref="scrollList"
>
<div
v-for="(item, idx) in broadcastListForLoop"
:key="item.id + '-' + idx"
class="broadcast-scroll-item"
>
{{ item.content }}
</div>
</div>
</span>
<span class="view" @click="handelJump(`/allocationExplanation`)">
{{ $t(`home.view`) }}
</span>
</p>
</section>
<div class="miningPoolRight">
<ul class="dataBlockBox">
@ -86,7 +109,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/power1.svg" alt="power" loading="lazy"/>
<img
src="../../assets/img/power1.svg"
alt="power"
loading="lazy"
/>
</div>
</li>
<li class="dataBlock" v-if="this.params.coin !== 'enx'">
@ -99,7 +126,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/算力.svg" alt="Computing power" loading="lazy"/>
<img
src="../../assets/img/算力.svg"
alt="Computing power"
loading="lazy"
/>
</div>
</li>
<li class="dataBlock" v-if="this.params.coin !== 'enx'">
@ -112,7 +143,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/难度.svg" alt="difficulty" loading="lazy"/>
<img
src="../../assets/img/难度.svg"
alt="difficulty"
loading="lazy"
/>
</div>
</li>
<!-- <li>
@ -147,7 +182,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/高度资源 26.svg" alt="height" loading="lazy"/>
<img
src="../../assets/img/高度资源 26.svg"
alt="height"
loading="lazy"
/>
</div>
</li>
@ -161,7 +200,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/币价资源 19.svg" alt="Currency price" loading="lazy"/>
<img
src="../../assets/img/币价资源 19.svg"
alt="Currency price"
loading="lazy"
/>
</div>
</li>
<li>
@ -174,7 +217,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/费率.svg" alt="Currency price" loading="lazy"/>
<img
src="../../assets/img/费率.svg"
alt="Currency price"
loading="lazy"
/>
</div>
</li>
<li
@ -188,7 +235,11 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/计算器.svg" alt="Profit Calculator" loading="lazy"/>
<img
src="../../assets/img/计算器.svg"
alt="Profit Calculator"
loading="lazy"
/>
</div>
</li>
<li
@ -202,7 +253,11 @@
<p class="content"></p>
</div>
<div class="imgIcon">
<img src="../../assets/img/接入矿池.svg" alt="Connect to the mining pool" loading="lazy"/>
<img
src="../../assets/img/接入矿池.svg"
alt="Connect to the mining pool"
loading="lazy"
/>
</div>
</li>
</ul>
@ -237,7 +292,6 @@
</div>
</div>
<!-- 收益计算器 -->
<section class="Calculator" v-show="showCalculator">
<div class="prop">
@ -273,7 +327,6 @@
</div>
</div>
<div class="content2">
<div class="item">
<p class="power">{{ $t(`home.Power`) }}:</p>
<el-input
@ -293,7 +346,6 @@
<el-option label="TH/s" value="TH/s"></el-option>
</el-select>
</el-input>
</div>
<div class="item">
<p class="time">{{ $t(`home.time`) }}:</p>
@ -319,22 +371,21 @@
:placeholder="$t(`mining.profit`)"
></el-input>
</div>
</div>
</div>
</section>
</section>
<div class="content" v-else v-loading="minerChartLoading">
<div class="bgBox">
<!--
<img v-if="lang == 'zh'" class="bgBoxImg2Img" src="../../assets/img/enx推广.png" alt="mining" loading="lazy"/>
<img v-else class="bgBoxImg2Img" src="../../assets/img/enx英文推广.png" alt="mining" loading="lazy"/> -->
<img class="bgImg" src="../../assets/img/home.png" alt="mining" loading="lazy"/>
<img
class="bgImg"
src="../../assets/img/home.png"
alt="mining"
loading="lazy"
/>
</div>
<el-row>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
@ -365,9 +416,32 @@
</el-card>
</el-col>
</el-row>
<!-- 广播 -->
<section class="describeBox">
<p> <i class="iconfont icon-tishishuoming "></i><span class="describeTitle">{{ $t(`home.describeTitle`) }}</span>{{ $t(`home.describe`) }} <span class="view" @click="handelJump(`/allocationExplanation`)"> {{ $t(`home.view`) }} </span> </p>
<div class="describe-row">
<div class="broadcast-scroll-wrap">
<div class="broadcast-scroll-list" :style="scrollStyle">
<div
v-for="item in broadcastList"
:key="item.id"
class="broadcast-scroll-item"
>
<i class="iconfont icon-tishishuoming"></i>
<span class="describeTitle">{{ $t(`home.describeTitle`) }}</span>
<span> {{ item.content }}</span>
<span
class="view"
v-show="item.id == 'b1'"
@click="handelJump(`/allocationExplanation`)"
>
{{ $t(`home.view`) }}
</span>
</div>
</div>
</div>
</div>
</section>
<div class="contentBox">
<!-- 算力图 -->
@ -375,10 +449,16 @@
<div class="currencyDescription2">
<section class="miningPoolBox">
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
<div class="miningPoolLeft" v-loading="minerChartLoading" v-loading-recovery="{ loading: 'minerChartLoading', recovery: ['getPoolPowerData', 'fetchNetPower'] }">
<div
class="miningPoolLeft"
v-loading="minerChartLoading"
v-loading-recovery="{
loading: 'minerChartLoading',
recovery: ['getPoolPowerData', 'fetchNetPower'],
}"
>
<div class="interval">
<div class="chartBth">
<div class="slideBox">
<span
@click="handelPower"
@ -391,12 +471,16 @@
>{{ $t(`home.networkPower`) }}</span
>
</div>
</div>
</div>
<div class="timeBox" style="text-align: right;padding-right: 35px;margin-bottom: 8px;">
<div
class="timeBox"
style="
text-align: right;
padding-right: 35px;
margin-bottom: 8px;
"
>
<span
:class="{ timeActive: timeActive == item.value }"
class="times"
@ -423,7 +507,7 @@
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
<div class="miningPoolRight">
<ul class="dataBlockBox">
<li :class="{'dataBlock': this.params.coin !== 'enx'}">
<li :class="{ dataBlock: this.params.coin !== 'enx' }">
<div class="text">
<p :title="$t(`home.power`)">{{ $t(`home.power`) }}</p>
<p class="content" :title="CoinData.poolPower">
@ -444,7 +528,10 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/算力.svg" alt="Computing power" />
<img
src="../../assets/img/算力.svg"
alt="Computing power"
/>
</div>
</li>
<li class="dataBlock" v-if="this.params.coin !== 'enx'">
@ -481,7 +568,10 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/算法资源 24.svg" alt="algorithm" />
<img
src="../../assets/img/算法资源 24.svg"
alt="algorithm"
/>
</div>
</li>
<li v-if="this.params.coin !== 'enx'">
@ -494,7 +584,10 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/高度资源 26.svg" alt="height" />
<img
src="../../assets/img/高度资源 26.svg"
alt="height"
/>
</div>
</li>
@ -504,10 +597,14 @@
{{ $t(`home.coinValue`) }}
</p>
<p :title="CoinData.price" class="content">
{{ CoinData.price }} </p>
{{ CoinData.price }}
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/币价资源 19.svg" alt="Currency price" />
<img
src="../../assets/img/币价资源 19.svg"
alt="Currency price"
/>
</div>
</li>
<li>
@ -515,12 +612,19 @@
<p :title="$t(`home.mode`)">
{{ $t(`home.mode`) }}
</p>
<p :title="CoinData.price" class="content" style="font-size: 0.8rem;margin-right: 5px;">
{{ CoinData.model }} / {{ CoinData.fee }}%</p>
<p
:title="CoinData.price"
class="content"
style="font-size: 0.8rem; margin-right: 5px"
>
{{ CoinData.model }} / {{ CoinData.fee }}%
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/费率.svg" alt="Profit Calculator" />
<img
src="../../assets/img/费率.svg"
alt="Profit Calculator"
/>
</div>
</li>
<li
@ -534,7 +638,10 @@
</p>
</div>
<div class="imgIcon">
<img src="../../assets/img/计算器.svg" alt="Profit Calculator" />
<img
src="../../assets/img/计算器.svg"
alt="Profit Calculator"
/>
</div>
</li>
<li
@ -548,7 +655,10 @@
<p class="content"></p>
</div>
<div class="imgIcon">
<img src="../../assets/img/接入矿池.svg" alt="Connect to the mining pool" />
<img
src="../../assets/img/接入矿池.svg"
alt="Connect to the mining pool"
/>
</div>
</li>
</ul>
@ -602,7 +712,14 @@
<el-row>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<div class="reportBlock">
<div class="reportBlockBox" v-loading="reportBlockLoading" v-loading-recovery="{ loading: 'reportBlockLoading', recovery: ['getBlockInfoData'] }">
<div
class="reportBlockBox"
v-loading="reportBlockLoading"
v-loading-recovery="{
loading: 'reportBlockLoading',
recovery: ['getBlockInfoData'],
}"
>
<div class="belowTable">
<ul>
<li class="table-title">
@ -616,7 +733,9 @@
$t(`home.blockHash`)
}}</span>
<div class="blockRewards" :title="$t(`home.blockRewards`)">
{{ $t(`home.blockRewards`) }} ({{ handelLabel2(params.coin) }})
{{ $t(`home.blockRewards`) }} ({{
handelLabel2(params.coin)
}})
<!-- <div
id="boxTitle2"
class="reward"
@ -647,7 +766,9 @@
<span>{{ item.height }}</span>
<span>{{ item.date }}</span>
<span class="hash" :title="item.hash">{{ item.hash }}</span>
<span :title="item.reward" class="reward">{{ item.reward }}</span>
<span :title="item.reward" class="reward">{{
item.reward
}}</span>
<!-- <span v-show="FeeShow">{{ item.fees }}</span> -->
</li>
</ul>
@ -748,14 +869,15 @@ export default {
metaInfo: {
meta: [
{
name: 'keywords',
content: 'M2Pool 矿池,首页,热门币种挖矿,稳定收益,Home,Popular Coins Mining,Stable Income Permission Levels,Account Privileges,Member Level Rates'
name: "keywords",
content:
"M2Pool 矿池,首页,热门币种挖矿,稳定收益,Home,Popular Coins Mining,Stable Income Permission Levels,Account Privileges,Member Level Rates",
},
{
name: 'description',
content:window.vm.$t(`seo.Home`)
}
]
name: "description",
content: window.vm.$t(`seo.Home`),
},
],
},
mixins: [IndexJs],
@ -786,7 +908,6 @@ export default {
width: 100%;
background: transparent;
padding-left: 8px;
}
i {
color: #5721e4;
@ -844,8 +965,6 @@ export default {
text-transform: capitalize;
}
}
}
.moveCurrencyBox li:hover {
transform: scale(1.05);
@ -876,10 +995,8 @@ export default {
margin-left: 5px;
}
}
}
.miningPoolLeft {
margin: 0 auto;
width: 95%;
@ -891,15 +1008,12 @@ export default {
background: #fff;
.interval {
padding: 0px 8px;
font-size: 0.7rem;
width: 100%;
display: block;
.timeBox {
padding: 0px 10px;
}
.times {
// background: #D2C3E9;
@ -916,7 +1030,6 @@ export default {
color: #5721e4;
}
.chartBth {
.slideBox {
// width: 30%;
@ -1140,7 +1253,6 @@ export default {
text-align: center;
font-size: 0.85rem;
line-height: 40px;
}
}
.currency-list2 {
@ -1185,8 +1297,6 @@ export default {
align-items: center;
justify-content: center;
.prop {
width: 98%;
height: 98%;
@ -1262,8 +1372,6 @@ export default {
margin-bottom: 8px;
font-size: 0.9rem;
}
}
}
}
@ -1278,7 +1386,6 @@ export default {
// .monitor-list{
// width: 100% !important;
// .left{
// width: 25px !important;
// }
@ -1297,9 +1404,6 @@ export default {
// font-size: 0.75rem !important;
// }
// }
}
@media screen and (min-width: 800px) and (max-width: 1279px) {
.imgTop {
@ -1324,7 +1428,6 @@ export default {
width: 100%;
background: transparent;
padding-left: 8px;
}
i {
color: #5721e4;
@ -1343,8 +1446,6 @@ export default {
}
}
.moveCurrencyBox {
margin: 0;
padding: 0;
@ -1384,10 +1485,8 @@ export default {
text-transform: capitalize;
}
}
}
.moveCurrencyBox li:hover {
transform: scale(1.05);
}
@ -1416,7 +1515,6 @@ export default {
margin-left: 5px;
}
}
}
.miningPoolLeft {
margin: 0 auto;
@ -1429,7 +1527,6 @@ export default {
background: #fff;
.interval {
padding: 0px 8px;
font-size: 0.7rem;
width: 100%;
@ -1452,7 +1549,6 @@ export default {
color: #5721e4;
}
.chartBth {
.slideBox {
// width: 30%;
@ -1675,7 +1771,6 @@ export default {
text-align: center;
font-size: 0.85rem;
line-height: 40px;
}
}
.currency-list2 {
@ -1720,8 +1815,6 @@ export default {
align-items: center;
justify-content: center;
.prop {
width: 98%;
height: 98%;
@ -1797,8 +1890,6 @@ export default {
margin-bottom: 8px;
font-size: 0.9rem;
}
}
}
}
@ -1813,7 +1904,6 @@ export default {
// .monitor-list{
// width: 100% !important;
// .left{
// width: 25px !important;
// }
@ -1832,13 +1922,9 @@ export default {
// font-size: 0.75rem !important;
// }
// }
}
@media screen and (min-width: 500px) and (max-width: 800px) {
.Calculator {
width: 100%;
min-height: 400px;
@ -1852,9 +1938,6 @@ export default {
align-items: center;
justify-content: center;
.prop {
width: 80%;
background: #fafbff;
@ -1929,16 +2012,12 @@ export default {
margin-bottom: 8px;
font-size: 0.9rem;
}
}
}
}
}
}
/*修改提示框*/
#boxTitle2[data-title] {
position: relative;
@ -2096,7 +2175,6 @@ export default {
// background-position: 50% 28%;
// background-size: cover;
position: relative;
// background: palegoldenrod;
// background-image: url(../../assets/img/enx广.png) !important;
@ -2193,7 +2271,6 @@ export default {
}
@media screen and (min-width: 220px) and (max-width: 1279px) {
::v-deep .el-input__inner {
height: 40px;
}
@ -2364,7 +2441,8 @@ export default {
flex-direction: column;
margin-top: 10px;
min-width: 300px;
.interval {//111
.interval {
//111
// background: fuchsia;
display: flex;
justify-content: space-between;
@ -2417,7 +2495,6 @@ export default {
}
}
.times {
// background: #D2C3E9;
width: 15%;
@ -2426,7 +2503,6 @@ export default {
font-size: 0.9rem;
// padding: 0PX 20PX;
line-height: 30px;
}
.times:hover {
color: #5721e4;
@ -2496,7 +2572,6 @@ export default {
text-overflow: ellipsis;
// white-space: nowrap;
margin-top: 5px;
}
}
.imgIcon {
@ -2916,7 +2991,7 @@ export default {
font-weight: 600;
font-size: 0.95em;
text-align: left;
margin-left: 1%
margin-left: 1%;
}
.transactionFee {
width: 18%;
@ -3252,7 +3327,6 @@ export default {
// }
.timeActive {
color: #5721e4;
}
.describeBox {
width: 100%;
@ -3274,10 +3348,10 @@ export default {
align-items: start;
.describeTitle {
font-weight: 600;
color: #6E3EDB;
color: #6e3edb;
}
i {
color: #6E3EDB;
color: #6e3edb;
margin-right: 5px;
line-height: 18px;
}
@ -3285,16 +3359,94 @@ export default {
.view {
cursor: pointer;
margin-left: 8px;
color: #6E3EDB;
color: #6e3edb;
// background: palegoldenrod;
}
.view:hover {
color: #000;
}
}
}
.describeBox {
margin: 16px 0;
// padding: 8px 16px;
border-radius: 8px;
font-size: 15px;
color: #333;
display: flex;
align-items: center;
min-height: 40px;
// background: pink;
}
.describe-row {
width: 73%;
margin: 0 auto;
background: #e7dff3;
border-radius: 8px;
// padding: 8px 20px;
display: flex;
justify-content: left;
// align-items: center;
// overflow: hidden;
padding: 5px 0px;
}
.describeTitle {
font-weight: bold;
margin-right: 8px;
color: #5721e4;
}
.broadcast-scroll-wrap {
display: inline-block;
min-width: 0;
height: 30px; /* 必须和JS一致 */
// overflow: hidden;
position: relative;
// background: palegoldenrod;
}
.broadcast-scroll-list {
display: flex;
flex-direction: column;
// background: paleturquoise;
// height: 28px;
text-align: left;
padding: 0;
// margin-left: 8px;
padding-left: 18px;
}
.broadcast-scroll-item {
width: 100%;
display: inline-block;
height: 30px;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
// background: papayawhip;
}
.describeTitle {
font-weight: 600;
color: #6e3edb;
}
i {
color: #6e3edb;
margin-right: 5px;
line-height: 18px;
}
// letter-spacing: 2px;
.view {
cursor: pointer;
margin-left: 8px;
color: #6e3edb;
// background: palegoldenrod;
}
.view:hover {
color: #000;
}
</style>
@ -3307,10 +3459,5 @@ export default {
.el-menu--horizontal {
width: 100%;
}
}
</style>

View File

@ -0,0 +1,34 @@
import { getUserList, sendMail } from '../../api/userManagement'
export default {
data(){
return {
userList:[],
userListLoading:false,
userListParams:{
coin:"nexa",
minerUser:"",
user:"",
pageNum:1,
pageSize:50
},
tableData:[],
userManagementLoading:false,
}
},
mounted(){
this.fetchUserList(this.userListParams);
},
methods:{
async fetchUserList(params){
this.userManagementLoading = true;
const data = await getUserList(params);
console.log(data,'data');
if(data && data.code == 200){
this.tableData = data.rows;
}
this.userManagementLoading = false;
}
}
}

View File

@ -0,0 +1,95 @@
<template>
<div v-loading="userManagementLoading">
<div class="main-title">注册用户管理</div>
<el-table
:data="tableData"
border
style="width: 100%; margin-bottom: 18px"
:header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }"
height="65vh"
>
<el-table-column prop="id" label="ID" width="60" />
<el-table-column prop="coin" label="币种" />
<el-table-column prop="user" label="用户邮箱" />
<el-table-column prop="status" label="用户状态" />
<el-table-column prop="minerUser" label="挖矿账号" />
<el-table-column :label="$t('backendSystem.operation')" width="200">
<el-button
size="mini"
>详情</el-button>
<el-button
size="mini"
>发送邮件</el-button>
</el-table-column>
</el-table>
<!-- 新增广播弹窗 -->
<!-- <el-dialog
:title="$t('backendSystem.dialogTitle')"
:visible.sync="dialogVisible"
width="50%"
:before-close="handleClose"
:close-on-click-modal="false"
>
<el-form :model="addParams" >
<el-form-item >
<el-input resize="none" v-model="addParams.content" type="textarea" :rows="5" @input="val => handleInput(val, 'add')" />
<div v-if="isOverLimit" style="color: #999; font-size: 12px; margin-top: 4px;">{{$t("backendSystem.exceedingInput")}}</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">{{$t("backendSystem.cancel")}}</el-button>
<el-button type="primary" :loading="bthLoading" @click="sureAddBroadcast">{{$t("backendSystem.publish")}}</el-button>
</div>
</el-dialog> -->
<!-- 修改广播弹窗 -->
<!-- <el-dialog
:title="$t('backendSystem.editContent')"
:visible.sync="editDialogVisible"
width="50%"
:before-close="handleEditClose"
:close-on-click-modal="false"
>
<el-form :model="editParams" >
<el-form-item >
<el-input resize="none" v-model="editParams.content" type="textarea" :rows="5" @input="val => handleInput(val, 'edit')" />
<div v-if="isOverLimit" style="color: #999; font-size: 12px; margin-top: 4px;">{{$t("backendSystem.exceedingInput")}}</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleEditClose">{{$t("backendSystem.cancel")}}</el-button>
<el-button type="primary" :loading="editLoading" @click="sureEditBroadcast">{{$t("backendSystem.editBroadcast")}}</el-button>
</div>
</el-dialog> -->
</div>
</template>
<script>
import Index from './index'
export default {
mixins:[Index],
}
</script>
<style lang="scss" scoped>
.main-title{
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 18px;
}
</style>

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><meta name=google-site-verification content=pKAZogQ0NQ6L4j9-V58WJMjm7zYCFwkJXSJzWu9UDM8><meta name=robots content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"><meta name=googlebot content="index, follow"><meta name=googlebot-news content="index, follow"><meta name=bingbot content="index, follow"><link rel=alternate hreflang=zh href=https://m2pool.com/zh><link rel=alternate hreflang=en href=https://m2pool.com/en><link rel=alternate hreflang=x-default href=https://m2pool.com/en><meta property=og:title content="M2pool - Stable leading high-yield mining pool"><meta property=og:description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining"><meta property=og:url content=https://m2pool.com/en><meta property=og:site_name content=M2Pool><meta property=og:type content=website><meta property=og:image content=https://m2pool.com/logo.png><link rel=icon href=/favicon.ico><link rel=stylesheet href=//at.alicdn.com/t/c/font_4582735_7i8wfzc0art.css><title>M2pool - Stable leading high-yield mining pool</title><meta name=keywords content="M2Pool, cryptocurrency mining pool,Entropyx(enx),entropyx, bitcoin mining, DGB mining, mining pool service, 加密货币矿池, 比特币挖矿, DGB挖矿"><meta name=description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining, including nexa, grs, mona, dgb, rxd, enx"><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><script defer src=/js/chunk-vendors-945ce2fe.648a91a9.js></script><script defer src=/js/chunk-vendors-aacc2dbb.d317c558.js></script><script defer src=/js/chunk-vendors-bc050c32.3f2f14d2.js></script><script defer src=/js/chunk-vendors-3003db77.d0b93d36.js></script><script defer src=/js/chunk-vendors-9d134daf.bb668c99.js></script><script defer src=/js/chunk-vendors-439af1fa.48a48f35.js></script><script defer src=/js/chunk-vendors-5c533fba.b9c00e08.js></script><script defer src=/js/chunk-vendors-96cecd74.a7d9b845.js></script><script defer src=/js/chunk-vendors-c2f7d60e.3710fdc2.js></script><script defer src=/js/chunk-vendors-89d5c698.2190b4ca.js></script><script defer src=/js/chunk-vendors-377fed06.159de137.js></script><script defer src=/js/chunk-vendors-5a805870.4cfc0ae8.js></script><script defer src=/js/chunk-vendors-cf2e0a28.c6e99da0.js></script><script defer src=/js/app-42f9d7e6.f413248c.js></script><script defer src=/js/app-d363ae0c.ec582e15.js></script><script defer src=/js/app-5c551db8.6b412dd5.js></script><script defer src=/js/app-01dc9ae1.e746f05c.js></script><script defer src=/js/app-8e0489d9.3811f71f.js></script><script defer src=/js/app-72600b29.11174efb.js></script><script defer src=/js/app-f035d474.92e1d288.js></script><script defer src=/js/app-113c6c50.56b97e4e.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/app-189e7968.908e0479.css rel=stylesheet><link href=/css/app-01dc9ae1.04da7d85.css rel=stylesheet><link href=/css/app-8e0489d9.c5f430f0.css rel=stylesheet><link href=/css/app-72600b29.37eab263.css rel=stylesheet><link href=/css/app-f035d474.0348646a.css rel=stylesheet><link href=/css/app-113c6c50.dfa1d227.css rel=stylesheet></head><body><div id=app></div></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><meta name=google-site-verification content=pKAZogQ0NQ6L4j9-V58WJMjm7zYCFwkJXSJzWu9UDM8><meta name=robots content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"><meta name=googlebot content="index, follow"><meta name=googlebot-news content="index, follow"><meta name=bingbot content="index, follow"><link rel=alternate hreflang=zh href=https://m2pool.com/zh><link rel=alternate hreflang=en href=https://m2pool.com/en><link rel=alternate hreflang=x-default href=https://m2pool.com/en><meta property=og:title content="M2pool - Stable leading high-yield mining pool"><meta property=og:description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining"><meta property=og:url content=https://m2pool.com/en><meta property=og:site_name content=M2Pool><meta property=og:type content=website><meta property=og:image content=https://m2pool.com/logo.png><link rel=icon href=/favicon.ico><link rel=stylesheet href=//at.alicdn.com/t/c/font_4582735_7i8wfzc0art.css><title>M2pool - Stable leading high-yield mining pool</title><meta name=keywords content="M2Pool, cryptocurrency mining pool,Entropyx(enx),entropyx, bitcoin mining, DGB mining, mining pool service, 加密货币矿池, 比特币挖矿, DGB挖矿"><meta name=description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining, including nexa, grs, mona, dgb, rxd, enx"><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><script defer src=/js/chunk-vendors-945ce2fe.648a91a9.js></script><script defer src=/js/chunk-vendors-aacc2dbb.d317c558.js></script><script defer src=/js/chunk-vendors-bc050c32.3f2f14d2.js></script><script defer src=/js/chunk-vendors-3003db77.d0b93d36.js></script><script defer src=/js/chunk-vendors-9d134daf.bb668c99.js></script><script defer src=/js/chunk-vendors-439af1fa.48a48f35.js></script><script defer src=/js/chunk-vendors-5c533fba.b9c00e08.js></script><script defer src=/js/chunk-vendors-96cecd74.a7d9b845.js></script><script defer src=/js/chunk-vendors-c2f7d60e.3710fdc2.js></script><script defer src=/js/chunk-vendors-89d5c698.2190b4ca.js></script><script defer src=/js/chunk-vendors-377fed06.159de137.js></script><script defer src=/js/chunk-vendors-5a805870.4cfc0ae8.js></script><script defer src=/js/chunk-vendors-cf2e0a28.c6e99da0.js></script><script defer src=/js/app-42f9d7e6.d6c55a75.js></script><script defer src=/js/app-d363ae0c.e4b98918.js></script><script defer src=/js/app-5c551db8.89dc18d2.js></script><script defer src=/js/app-b4c4f6ec.699d67bf.js></script><script defer src=/js/app-45954fd3.470dc9c3.js></script><script defer src=/js/app-72600b29.3e7e0df2.js></script><script defer src=/js/app-f035d474.92e1d288.js></script><script defer src=/js/app-113c6c50.bce0e5a7.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/app-189e7968.dab6fbf8.css rel=stylesheet><link href=/css/app-b4c4f6ec.b7a26d39.css rel=stylesheet><link href=/css/app-45954fd3.605105ff.css rel=stylesheet><link href=/css/app-72600b29.8bee31b9.css rel=stylesheet><link href=/css/app-f035d474.0348646a.css rel=stylesheet><link href=/css/app-113c6c50.5229e45e.css rel=stylesheet></head><body><div id=app></div></body></html>

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/en</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-06-17T02:57:34.126Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/en</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-06-25T08:37:39.425Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>

Binary file not shown.

View File

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/zh</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-06-17T02:57:34.114Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/zh</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-06-25T08:37:39.415Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>

Binary file not shown.