取消enx活动图片 费率改为1%
This commit is contained in:
@@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view class="page" />
|
<router-view class="page" />
|
||||||
|
<!-- <ChatWidget /> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script >
|
<script >
|
||||||
|
import ChatWidget from '../src/components/ChatWidget.vue';
|
||||||
import { Debounce, throttle } from '@/utils/publicMethods';
|
import { Debounce, throttle } from '@/utils/publicMethods';
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
ChatWidget
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
68
mining-pool/src/api/customerService.js
Normal file
68
mining-pool/src/api/customerService.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import request from '../utils/request'
|
||||||
|
|
||||||
|
//历史聊天记录查询 用户查询七天前的聊天信息
|
||||||
|
export function getHistory() {
|
||||||
|
return request({
|
||||||
|
url: `chat/message/find/history/message`,
|
||||||
|
method: 'get',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//历史聊天记录查询 查询七天内记录
|
||||||
|
export function getHistory7() {
|
||||||
|
return request({
|
||||||
|
url: `chat/message/find/recently/message`,
|
||||||
|
method: 'get',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//用户点击对话框默认已读
|
||||||
|
export function getReadMessage(data) {
|
||||||
|
return request({
|
||||||
|
url: `chat/message/read/message`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//聊天列表
|
||||||
|
export function getRoomList() {
|
||||||
|
return request({
|
||||||
|
url: `/chat/rooms/find/room/list`,
|
||||||
|
method: 'get',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//重要聊天标记
|
||||||
|
export function getUpdateRoom(data) {
|
||||||
|
return request({
|
||||||
|
url: `/chat/rooms/update/room`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//图片上传接口
|
||||||
|
export function getFileUpdate(data) {
|
||||||
|
return request({
|
||||||
|
url: `file/update`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//图根据当前用户邮箱查询聊天室id
|
||||||
|
export function getUserid() {
|
||||||
|
return request({
|
||||||
|
url: `chat/rooms/find/room/by/userid`,
|
||||||
|
method: 'get',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
893
mining-pool/src/components/ChatWidget.vue
Normal file
893
mining-pool/src/components/ChatWidget.vue
Normal file
@@ -0,0 +1,893 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chat-widget">
|
||||||
|
<!-- 聊天图标 -->
|
||||||
|
<div
|
||||||
|
class="chat-icon"
|
||||||
|
@click="toggleChat"
|
||||||
|
:class="{ active: isChatOpen }"
|
||||||
|
aria-label="打开客服聊天"
|
||||||
|
tabindex="0"
|
||||||
|
@keydown.enter="toggleChat"
|
||||||
|
@keydown.space="toggleChat"
|
||||||
|
>
|
||||||
|
<i class="el-icon-chat-dot-round"></i>
|
||||||
|
<span v-if="unreadMessages > 0" class="unread-badge">{{
|
||||||
|
unreadMessages
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 聊天对话框 -->
|
||||||
|
<transition name="chat-slide">
|
||||||
|
<div v-show="isChatOpen" class="chat-dialog">
|
||||||
|
<div class="chat-header">
|
||||||
|
<div class="chat-title">{{ $t("chat.title") || "在线客服" }}</div>
|
||||||
|
<div class="chat-actions">
|
||||||
|
<i class="el-icon-minus" @click="minimizeChat"></i>
|
||||||
|
<i class="el-icon-close" @click="closeChat"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-body" ref="chatBody">
|
||||||
|
<!-- 连接状态提示 -->
|
||||||
|
<div v-if="connectionStatus === 'connecting'" class="chat-status connecting">
|
||||||
|
<i class="el-icon-loading"></i>
|
||||||
|
<p>正在连接客服系统...</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="connectionStatus === 'error'" class="chat-status error">
|
||||||
|
<i class="el-icon-warning"></i>
|
||||||
|
<p>连接失败,请稍后重试</p>
|
||||||
|
<button @click="connectWebSocket" class="retry-button">重试连接</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 消息列表 -->
|
||||||
|
<template v-else>
|
||||||
|
<div v-if="messages.length === 0" class="chat-empty">
|
||||||
|
{{ $t("chat.welcome") || "欢迎使用在线客服,请问有什么可以帮您?" }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="(msg, index) in messages"
|
||||||
|
:key="index"
|
||||||
|
class="chat-message"
|
||||||
|
:class="{
|
||||||
|
'chat-message-user': msg.type === 'user',
|
||||||
|
'chat-message-system': msg.type === 'system',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="message-avatar">
|
||||||
|
<i v-if="msg.type === 'system'" class="el-icon-service"></i>
|
||||||
|
<i v-else class="el-icon-user"></i>
|
||||||
|
</div>
|
||||||
|
<div class="message-content">
|
||||||
|
<!-- 文本消息 -->
|
||||||
|
<div v-if="!msg.isImage" class="message-text">{{ msg.text }}</div>
|
||||||
|
|
||||||
|
<!-- 图片消息 -->
|
||||||
|
<div v-else class="message-image">
|
||||||
|
<img :src="msg.imageUrl" @click="previewImage(msg.imageUrl)" alt="聊天图片" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="message-time">{{ formatTime(msg.time) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-footer">
|
||||||
|
<div class="chat-toolbar">
|
||||||
|
<label for="imageUpload" class="image-upload-label" :class="{ 'disabled': connectionStatus !== 'connected' }">
|
||||||
|
<i class="el-icon-picture-outline"></i>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="imageUpload"
|
||||||
|
ref="imageUpload"
|
||||||
|
accept="image/*"
|
||||||
|
@change="handleImageUpload"
|
||||||
|
style="display: none;"
|
||||||
|
:disabled="connectionStatus !== 'connected'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="chat-input"
|
||||||
|
v-model="inputMessage"
|
||||||
|
@keyup.enter="sendMessage"
|
||||||
|
:placeholder="$t('chat.inputPlaceholder') || '请输入您的问题...'"
|
||||||
|
:disabled="connectionStatus !== 'connected'"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
class="chat-send"
|
||||||
|
@click="sendMessage"
|
||||||
|
:disabled="connectionStatus !== 'connected' || !inputMessage.trim()"
|
||||||
|
>
|
||||||
|
{{ $t("chat.send") || "发送" }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图片预览 -->
|
||||||
|
<div v-if="showImagePreview" class="image-preview-overlay" @click="closeImagePreview">
|
||||||
|
<div class="image-preview-container">
|
||||||
|
<img :src="previewImageUrl" class="preview-image" />
|
||||||
|
<i class="el-icon-close preview-close" @click="closeImagePreview"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Client } from '@stomp/stompjs';
|
||||||
|
import { getUserid } from '../api/customerService';
|
||||||
|
export default {
|
||||||
|
name: "ChatWidget",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isChatOpen: false,
|
||||||
|
inputMessage: "",
|
||||||
|
messages: [],
|
||||||
|
unreadMessages: 0,
|
||||||
|
// 图片预览相关
|
||||||
|
showImagePreview: false,
|
||||||
|
previewImageUrl: '',
|
||||||
|
// WebSocket 相关
|
||||||
|
stompClient: null,
|
||||||
|
connectionStatus: 'disconnected', // disconnected, connecting, connected, error
|
||||||
|
userType: 0, // 0 游客 1 登录用户 2 客服
|
||||||
|
userEmail: '', // 用户标识
|
||||||
|
// 自动回复配置
|
||||||
|
autoResponses: {
|
||||||
|
hello: "您好,有什么可以帮助您的?",
|
||||||
|
你好: "您好,有什么可以帮助您的?",
|
||||||
|
hi: "您好,有什么可以帮助您的?",
|
||||||
|
挖矿: "您可以查看我们的挖矿教程,或者直接创建矿工账户开始挖矿。",
|
||||||
|
算力: "您可以在首页查看当前的矿池算力和您的个人算力。",
|
||||||
|
收益: "收益根据您的算力贡献按比例分配,详情可以查看收益计算器。",
|
||||||
|
帮助: "您可以查看我们的帮助文档,或者提交工单咨询具体问题。",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
document.addEventListener("click", this.handleClickOutside);
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
async fetchUserid(){
|
||||||
|
const res = await getUserid();
|
||||||
|
if(res &&res.code == 200){
|
||||||
|
this.roomId = res.data;
|
||||||
|
console.log(res,"及附加覅");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化 WebSocket 连接
|
||||||
|
initWebSocket() {
|
||||||
|
this.determineUserType();
|
||||||
|
this.connectWebSocket();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 确定用户类型和邮箱
|
||||||
|
determineUserType() {
|
||||||
|
try {
|
||||||
|
const token = JSON.parse(localStorage.getItem('token') || '{}');
|
||||||
|
const userInfo = JSON.parse(localStorage.getItem('jurisdiction') || '{}');
|
||||||
|
const email = JSON.parse(localStorage.getItem('userEmail') || '{}');
|
||||||
|
if (token) {
|
||||||
|
if (userInfo.roleKey === 'customer_service') {
|
||||||
|
// 客服用户
|
||||||
|
this.userType = 2;
|
||||||
|
} else {
|
||||||
|
// 登录用户
|
||||||
|
this.userType = 1;
|
||||||
|
}
|
||||||
|
this.userEmail =email;
|
||||||
|
}else{//游客
|
||||||
|
this.userType = 0;
|
||||||
|
this.userEmail = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取用户信息失败:', error);
|
||||||
|
// 出错时默认为游客
|
||||||
|
this.userType = 0;
|
||||||
|
this.userEmail = `guest_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 连接 WebSocket
|
||||||
|
connectWebSocket() {
|
||||||
|
this.connectionStatus = 'connecting';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const wsUrl = `${process.env.VUE_APP_BASE_API}chat/ws`;
|
||||||
|
|
||||||
|
// 创建 STOMP 客户端
|
||||||
|
this.stompClient = new Client({
|
||||||
|
brokerURL: wsUrl,
|
||||||
|
connectHeaders: {
|
||||||
|
'email': this.userEmail,
|
||||||
|
'type': this.userType
|
||||||
|
},
|
||||||
|
debug: function(str) {
|
||||||
|
console.log('STOMP: ' + str);
|
||||||
|
},
|
||||||
|
reconnectDelay: 5000,
|
||||||
|
heartbeatIncoming: 4000,
|
||||||
|
heartbeatOutgoing: 4000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 连接成功回调
|
||||||
|
this.stompClient.onConnect = (frame) => {
|
||||||
|
console.log('连接成功: ' + frame);
|
||||||
|
this.connectionStatus = 'connected';
|
||||||
|
|
||||||
|
// 订阅个人消息频道
|
||||||
|
this.stompClient.subscribe(`${process.env.VUE_APP_BASE_API}user/queue/${this.userEmail}`, this.onMessageReceived);
|
||||||
|
|
||||||
|
// 根据用户类型显示不同的欢迎消息
|
||||||
|
let welcomeMessage = '';
|
||||||
|
switch(this.userType) {
|
||||||
|
case 0:
|
||||||
|
welcomeMessage = '您当前以游客身份访问,请问有什么可以帮您?';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
welcomeMessage = '欢迎回来,请问有什么可以帮您?';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
welcomeMessage = '您已以客服身份登录系统';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.addSystemMessage(welcomeMessage);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 连接错误回调
|
||||||
|
this.stompClient.onStompError = (frame) => {
|
||||||
|
console.error('连接错误: ' + frame.headers.message);
|
||||||
|
this.connectionStatus = 'error';
|
||||||
|
this.addSystemMessage('连接客服系统失败,请稍后重试。');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动连接
|
||||||
|
this.stompClient.activate();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('初始化 WebSocket 失败:', error);
|
||||||
|
this.connectionStatus = 'error';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 断开 WebSocket 连接
|
||||||
|
disconnectWebSocket() {
|
||||||
|
if (this.stompClient && this.stompClient.connected) {
|
||||||
|
this.stompClient.deactivate();
|
||||||
|
this.connectionStatus = 'disconnected';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 接收消息处理
|
||||||
|
onMessageReceived(message) {
|
||||||
|
console.log('收到消息:', message.body);
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(message.body);
|
||||||
|
|
||||||
|
// 添加客服消息
|
||||||
|
this.messages.push({
|
||||||
|
type: 'system',
|
||||||
|
text: data.content,
|
||||||
|
isImage: data.type === 'image',
|
||||||
|
imageUrl: data.type === 'image' ? data.content : null,
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果聊天窗口没有打开,显示未读消息数
|
||||||
|
if (!this.isChatOpen) {
|
||||||
|
this.unreadMessages++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析消息失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 切换聊天窗口
|
||||||
|
toggleChat() {
|
||||||
|
this.isChatOpen = !this.isChatOpen;
|
||||||
|
|
||||||
|
if (this.isChatOpen) {
|
||||||
|
this.unreadMessages = 0;
|
||||||
|
|
||||||
|
// 如果未连接,则连接 WebSocket
|
||||||
|
if (this.connectionStatus === 'disconnected') {
|
||||||
|
this.initWebSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
minimizeChat() {
|
||||||
|
this.isChatOpen = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
closeChat() {
|
||||||
|
this.isChatOpen = false;
|
||||||
|
this.messages = [];
|
||||||
|
this.disconnectWebSocket();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
sendMessage() {
|
||||||
|
if (!this.inputMessage.trim() || this.connectionStatus !== 'connected') return;
|
||||||
|
|
||||||
|
const messageText = this.inputMessage.trim();
|
||||||
|
|
||||||
|
// 添加用户消息到界面
|
||||||
|
this.messages.push({
|
||||||
|
type:0,// 0 文本 1图片
|
||||||
|
text: messageText,
|
||||||
|
isImage: false,
|
||||||
|
time: new Date(),
|
||||||
|
email:"",// 接收者邮箱?
|
||||||
|
receiveUserType:2,// 接受用户类型0 游客 1 登录用户 2 客服人员
|
||||||
|
sendUserType:this.userType,// 发送者类型0 游客 1 登录用户 2 客服人员
|
||||||
|
roomId:this.roomId,// 聊天室ID
|
||||||
|
});
|
||||||
|
|
||||||
|
// 通过 WebSocket 发送消息
|
||||||
|
if (this.stompClient && this.stompClient.connected) {
|
||||||
|
this.stompClient.publish({
|
||||||
|
destination: '/send/message',
|
||||||
|
body: JSON.stringify({
|
||||||
|
content: messageText,
|
||||||
|
type: 'text'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 如果连接失败,使用自动回复
|
||||||
|
this.handleAutoResponse(messageText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空输入框
|
||||||
|
this.inputMessage = "";
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 添加系统消息
|
||||||
|
addSystemMessage(text) {
|
||||||
|
this.messages.push({
|
||||||
|
type: "system",
|
||||||
|
text: text,
|
||||||
|
isImage: false,
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 自动回复 (仅在无法连接服务器时使用)
|
||||||
|
handleAutoResponse(message) {
|
||||||
|
setTimeout(() => {
|
||||||
|
let response = "抱歉,我暂时无法回答这个问题。请联系真人客服或提交工单。";
|
||||||
|
|
||||||
|
// 检查是否匹配自动回复关键词
|
||||||
|
for (const [keyword, reply] of Object.entries(this.autoResponses)) {
|
||||||
|
if (message.toLowerCase().includes(keyword.toLowerCase())) {
|
||||||
|
response = reply;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加系统回复
|
||||||
|
this.messages.push({
|
||||||
|
type: "system",
|
||||||
|
text: response,
|
||||||
|
isImage: false,
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.isChatOpen) {
|
||||||
|
this.unreadMessages++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
scrollToBottom() {
|
||||||
|
if (this.$refs.chatBody) {
|
||||||
|
this.$refs.chatBody.scrollTop = this.$refs.chatBody.scrollHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
formatTime(date) {
|
||||||
|
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClickOutside(event) {
|
||||||
|
if (this.isChatOpen) {
|
||||||
|
const chatElement = this.$el.querySelector('.chat-dialog');
|
||||||
|
const chatIcon = this.$el.querySelector('.chat-icon');
|
||||||
|
this.fetchUserid();
|
||||||
|
if (chatElement && !chatElement.contains(event.target) && !chatIcon.contains(event.target)) {
|
||||||
|
this.isChatOpen = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理图片上传
|
||||||
|
handleImageUpload(event) {
|
||||||
|
if (this.connectionStatus !== 'connected') return;
|
||||||
|
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
// 检查是否为图片
|
||||||
|
if (!file.type.startsWith('image/')) {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('chat.onlyImages') || '只能上传图片文件!',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件大小 (限制为5MB)
|
||||||
|
const maxSize = 5 * 1024 * 1024;
|
||||||
|
if (file.size > maxSize) {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('chat.imageTooLarge') || '图片大小不能超过5MB!',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
const imageUrl = e.target.result;
|
||||||
|
|
||||||
|
// 添加用户图片消息到界面
|
||||||
|
this.messages.push({
|
||||||
|
type:1,// 0 文本 1图片
|
||||||
|
text: "",
|
||||||
|
isImage: true,
|
||||||
|
imageUrl: imageUrl,
|
||||||
|
time: new Date(),
|
||||||
|
email:"",// 接收者邮箱?
|
||||||
|
receiveUserType:2,// 接受用户类型0 游客 1 登录用户 2 客服人员
|
||||||
|
sendUserType:this.userType,// 发送者类型0 游客 1 登录用户 2 客服人员
|
||||||
|
roomId:this.roomId,// 聊天室ID
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 通过 WebSocket 发送图片消息
|
||||||
|
if (this.stompClient && this.stompClient.connected) {
|
||||||
|
this.stompClient.publish({
|
||||||
|
destination: '/send/message',
|
||||||
|
body: JSON.stringify({
|
||||||
|
content: imageUrl,
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
this.$refs.imageUpload.value = '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 预览图片
|
||||||
|
previewImage(imageUrl) {
|
||||||
|
this.previewImageUrl = imageUrl;
|
||||||
|
this.showImagePreview = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 关闭图片预览
|
||||||
|
closeImagePreview() {
|
||||||
|
this.showImagePreview = false;
|
||||||
|
this.previewImageUrl = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.disconnectWebSocket();
|
||||||
|
document.removeEventListener("click", this.handleClickOutside);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.chat-widget {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 40px;
|
||||||
|
right: 60px;
|
||||||
|
z-index: 1000;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #AC85E0;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
background-color: #6E3EDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #6E3EDB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.unread-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -5px;
|
||||||
|
right: -5px;
|
||||||
|
background-color: #e74c3c;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-dialog {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80px;
|
||||||
|
right: 0;
|
||||||
|
width: 350px;
|
||||||
|
height: 450px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-header {
|
||||||
|
background-color: #AC85E0;
|
||||||
|
color: white;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-body {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-status {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 8px 0;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.connecting i {
|
||||||
|
color: #AC85E0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
i {
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-button {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #AC85E0;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #6E3EDB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-empty {
|
||||||
|
color: #777;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
&.chat-message-user {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
background-color: #AC85E0;
|
||||||
|
color: white;
|
||||||
|
border-radius: 18px 18px 0 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
text-align: right;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.chat-message-system {
|
||||||
|
.message-content {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 18px 18px 18px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
margin: 0 10px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
max-width: 70%;
|
||||||
|
padding: 10px 15px;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-text {
|
||||||
|
line-height: 1.4;
|
||||||
|
font-size: 14px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-image {
|
||||||
|
img {
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-footer {
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-toolbar {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-upload-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
&:hover:not(.disabled) {
|
||||||
|
color: #AC85E0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input {
|
||||||
|
flex: 1;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 8px 15px;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&:focus:not(:disabled) {
|
||||||
|
border-color: #AC85E0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-send {
|
||||||
|
background-color: #AC85E0;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 8px 15px;
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
background-color: #6E3EDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
.image-preview-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
z-index: 1100;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview-container {
|
||||||
|
position: relative;
|
||||||
|
max-width: 90%;
|
||||||
|
max-height: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 90vh;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-close {
|
||||||
|
position: absolute;
|
||||||
|
top: -40px;
|
||||||
|
right: 0;
|
||||||
|
color: white;
|
||||||
|
font-size: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画效果
|
||||||
|
.chat-slide-enter-active, .chat-slide-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-slide-enter, .chat-slide-leave-to {
|
||||||
|
transform: translateY(20px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动端适配
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.chat-widget {
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-dialog {
|
||||||
|
width: 300px;
|
||||||
|
height: 400px;
|
||||||
|
bottom: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-image img {
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
32
mining-pool/src/i18n/ChatWidget.js
Normal file
32
mining-pool/src/i18n/ChatWidget.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
export const ChatWidget_zh = {
|
||||||
|
chat:{
|
||||||
|
|
||||||
|
title: '在线客服',
|
||||||
|
welcome: '欢迎使用在线客服,请问有什么可以帮您?',
|
||||||
|
placeholder: '请输入您的消息...',
|
||||||
|
send: '发送',
|
||||||
|
close: '关闭',
|
||||||
|
inputPlaceholder:"请输入您的问题...",
|
||||||
|
onlyImages:"只能上传图片文件!",
|
||||||
|
imageTooLarge:"图片大小不能超过5MB!",
|
||||||
|
imageReceived:"已收到您的图片,我们会尽快处理您的问题。",
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ChatWidget_en = {
|
||||||
|
|
||||||
|
|
||||||
|
chat:{
|
||||||
|
title: 'Online Customer Service',
|
||||||
|
welcome: 'Welcome to the online customer service, what can I help you with?',
|
||||||
|
placeholder: 'Please enter your message...',
|
||||||
|
send: 'Send',
|
||||||
|
close: 'Close',
|
||||||
|
inputPlaceholder:"Please enter your question...",
|
||||||
|
onlyImages:"Only image files can be uploaded!",
|
||||||
|
imageTooLarge:"The image size cannot exceed 5MB!",
|
||||||
|
imageReceived:"We have received your image, and we will handle your question as soon as possible.",
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import {workOrder_zh,workOrder_en} from'./submitWorkOrder'
|
|||||||
import {alerts_zh,alerts_en} from'./alerts'
|
import {alerts_zh,alerts_en} from'./alerts'
|
||||||
import {seo_zh,seo_en} from'./seo'
|
import {seo_zh,seo_en} from'./seo'
|
||||||
import {chooseUs_zh,chooseUs_en} from'./dataDisplay'
|
import {chooseUs_zh,chooseUs_en} from'./dataDisplay'
|
||||||
|
import {ChatWidget_zh,ChatWidget_en} from'./ChatWidget'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ export default {
|
|||||||
...alerts_zh,
|
...alerts_zh,
|
||||||
...seo_zh,
|
...seo_zh,
|
||||||
...chooseUs_zh,
|
...chooseUs_zh,
|
||||||
|
...ChatWidget_zh,
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -50,7 +51,7 @@ export default {
|
|||||||
...alerts_en,
|
...alerts_en,
|
||||||
...seo_en,
|
...seo_en,
|
||||||
...chooseUs_en,
|
...chooseUs_en,
|
||||||
|
...ChatWidget_en,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,22 @@ const childrenRoutes = [
|
|||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{//在线客服
|
||||||
|
path: 'customerService',
|
||||||
|
name: 'CustomerService',
|
||||||
|
component: () => import('../views/customerService/index.vue'),
|
||||||
|
meta: {title: '在线客服',
|
||||||
|
description:i18n.t(`seo.apiFile`),
|
||||||
|
allAuthority:[`all`],
|
||||||
|
// keywords: 'M2Pool 矿池,API 文档,认证 token,接口调用,API file,authentication token,Interface call'
|
||||||
|
keywords:{
|
||||||
|
en: 'API file,authentication token,Interface call',
|
||||||
|
zh: 'M2Pool 矿池,API 文档,认证 token,接口调用'
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
{//接入矿池页面
|
{//接入矿池页面
|
||||||
path: '/:lang/AccessMiningPool',
|
path: '/:lang/AccessMiningPool',
|
||||||
name: 'AccessMiningPool',
|
name: 'AccessMiningPool',
|
||||||
|
|||||||
@@ -160,7 +160,10 @@ window.addEventListener('offline', () => {
|
|||||||
|
|
||||||
service.defaults.retry = 2;// 重试次数
|
service.defaults.retry = 2;// 重试次数
|
||||||
service.defaults.retryDelay = 2000;
|
service.defaults.retryDelay = 2000;
|
||||||
service.defaults.shouldRetry = (error) => true
|
service.defaults.shouldRetry = (error) => {
|
||||||
|
// 只有网络错误或超时错误才进行重试
|
||||||
|
return error.message === "Network Error" || error.message.includes("timeout");
|
||||||
|
};
|
||||||
|
|
||||||
localStorage.setItem('superReportError', "")
|
localStorage.setItem('superReportError', "")
|
||||||
let superReportError = localStorage.getItem('superReportError')
|
let superReportError = localStorage.getItem('superReportError')
|
||||||
@@ -286,7 +289,6 @@ service.interceptors.response.use(res => {
|
|||||||
|
|
||||||
|
|
||||||
let { message } = error;
|
let { message } = error;
|
||||||
|
|
||||||
if (message == "Network Error" || message.includes("timeout")) {
|
if (message == "Network Error" || message.includes("timeout")) {
|
||||||
if (!navigator.onLine) {
|
if (!navigator.onLine) {
|
||||||
// 断网状态,添加到重试队列
|
// 断网状态,添加到重试队列
|
||||||
@@ -324,15 +326,29 @@ service.interceptors.response.use(res => {
|
|||||||
|
|
||||||
console.log('请求已加入断网重连队列:', error.config.url);
|
console.log('请求已加入断网重连队列:', error.config.url);
|
||||||
}
|
}
|
||||||
} else if ((error.config.retry > 0 && error.config)) {
|
} else {
|
||||||
// 保留现有的重试逻辑
|
// 网络已连接,但请求失败,尝试重试
|
||||||
error.config.retry--;
|
// 确保 config 中有 __retryCount 字段
|
||||||
|
error.config.__retryCount = error.config.__retryCount || 0;
|
||||||
|
|
||||||
|
// 判断是否可以重试
|
||||||
|
if (error.config.__retryCount < service.defaults.retry && service.defaults.shouldRetry(error)) {
|
||||||
|
// 增加重试计数
|
||||||
|
error.config.__retryCount += 1;
|
||||||
|
|
||||||
|
console.log(`[请求重试] ${error.config.url} - 第 ${error.config.__retryCount} 次重试`);
|
||||||
|
|
||||||
|
// 创建新的Promise等待一段时间后重试
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve(service(error.config));
|
resolve(service(error.config));
|
||||||
}, 2000);
|
}, service.defaults.retryDelay);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 达到最大重试次数,不再重试
|
||||||
|
console.log(`[请求失败] ${error.config.url} - 已达到最大重试次数`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!superReportError) {
|
if (!superReportError) {
|
||||||
@@ -375,63 +391,11 @@ service.interceptors.response.use(res => {
|
|||||||
// 避免完全不提示,可以在控制台记录被抑制的错误
|
// 避免完全不提示,可以在控制台记录被抑制的错误
|
||||||
console.log('[错误提示] 已抑制重复错误:', message);
|
console.log('[错误提示] 已抑制重复错误:', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// let { message } = error;
|
|
||||||
// if (message == "Network Error") {
|
|
||||||
// // message = "后端接口网络连接异常,请刷新重试";
|
|
||||||
// const now = Date.now();
|
|
||||||
// if (now - lastNetworkErrorTime > NETWORK_ERROR_THROTTLE_TIME) {
|
|
||||||
// lastNetworkErrorTime = now; // 更新最后提示时间
|
|
||||||
// Message({
|
|
||||||
// message: window.vm.$i18n.t(`home.NetworkError`),
|
|
||||||
// type: 'error',
|
|
||||||
// duration: 4 * 1000,
|
|
||||||
// showClose: true
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else if (message.includes("timeout")) {
|
|
||||||
// // message = "系统接口请求超时,请刷新重试";
|
|
||||||
// Message({
|
|
||||||
// message: window.vm.$i18n.t(`home.requestTimeout`),
|
|
||||||
// type: 'error',
|
|
||||||
// duration: 5 * 1000,
|
|
||||||
// showClose: true
|
|
||||||
// })
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else if (message.includes("Request failed with status code")) {
|
|
||||||
// // message = "系统接口" + message.substr(message.length - 3) + "异常";
|
|
||||||
// Message({
|
|
||||||
// message: "系统接口" + message.substr(message.length - 3) + "异常",
|
|
||||||
// type: 'error',
|
|
||||||
// duration: 5 * 1000,
|
|
||||||
// showClose: true
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
|
|
||||||
// Message({
|
|
||||||
// message: message,
|
|
||||||
// type: 'error',
|
|
||||||
// duration: 5 * 1000,
|
|
||||||
// showClose: true
|
|
||||||
// })
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
0
mining-pool/src/views/customerService/index.js
Normal file
0
mining-pool/src/views/customerService/index.js
Normal file
1044
mining-pool/src/views/customerService/index.vue
Normal file
1044
mining-pool/src/views/customerService/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,10 @@
|
|||||||
<section v-if="$isMobile">
|
<section v-if="$isMobile">
|
||||||
|
|
||||||
<div class="imgTop">
|
<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-if="lang == 'zh'" src="../../assets/img/enx推广.png" alt="mining" loading="lazy"/>
|
||||||
<img v-else src="../../assets/img/enx英文推广.png" alt="mining" loading="lazy"/>
|
<img v-else src="../../assets/img/enx英文推广.png" alt="mining" loading="lazy"/> -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -329,13 +329,12 @@
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
<div class="content" v-else v-loading="minerChartLoading">
|
<div class="content" v-else v-loading="minerChartLoading">
|
||||||
|
|
||||||
<div class="bgBox">
|
<div class="bgBox">
|
||||||
|
<!--
|
||||||
<img v-if="lang == 'zh'" class="bgBoxImg2Img" src="../../assets/img/enx推广.png" alt="mining" loading="lazy"/>
|
<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 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="bgBoxImg" src="../../assets/img/enx推广.png" style="width: 100%;height: 100%;" alt="mining" loading="lazy"/> -->
|
|
||||||
</div>
|
</div>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
@@ -785,6 +784,7 @@ export default {
|
|||||||
p{
|
p{
|
||||||
width: 100% ;
|
width: 100% ;
|
||||||
background: transparent ;
|
background: transparent ;
|
||||||
|
padding-left: 8px;
|
||||||
|
|
||||||
}
|
}
|
||||||
i{
|
i{
|
||||||
@@ -1295,16 +1295,44 @@ export default {
|
|||||||
@media screen and (min-width:800px) and (max-width: 1279px) {
|
@media screen and (min-width:800px) and (max-width: 1279px) {
|
||||||
.imgTop {
|
.imgTop {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// padding-left: 10%;
|
padding-left: 20%;
|
||||||
text-align: center;
|
text-align: left;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: auto ;
|
||||||
|
height:300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#chart {
|
#chart {
|
||||||
height: 400px !important;
|
height: 400px !important;
|
||||||
}
|
}
|
||||||
|
.describeBox2{
|
||||||
|
width: 100%;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 0 auto;
|
||||||
|
p{
|
||||||
|
width: 100% ;
|
||||||
|
background: transparent ;
|
||||||
|
padding-left: 8px;
|
||||||
|
|
||||||
|
}
|
||||||
|
i{
|
||||||
|
color: #5721e4;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
.describeTitle{
|
||||||
|
color: #5721e4;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view{
|
||||||
|
color: #5721e4;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.moveCurrencyBox {
|
.moveCurrencyBox {
|
||||||
@@ -2046,7 +2074,7 @@ export default {
|
|||||||
.bgBox {
|
.bgBox {
|
||||||
// background: gold;
|
// background: gold;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// height: 380px;
|
height: 300px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
// background-position: 50% 28%;
|
// background-position: 50% 28%;
|
||||||
// background-size: cover;
|
// background-size: cover;
|
||||||
@@ -2059,12 +2087,20 @@ export default {
|
|||||||
// background-position: 13.2vw 0 ;
|
// background-position: 13.2vw 0 ;
|
||||||
// background-repeat: no-repeat;
|
// background-repeat: no-repeat;
|
||||||
// margin-top: 50px;
|
// margin-top: 50px;
|
||||||
margin: 30px 0px;
|
// margin: 30px 0px;
|
||||||
|
|
||||||
text-align: center;
|
text-align: left;
|
||||||
|
.bgImg{
|
||||||
|
height: 100%;
|
||||||
|
width: auto ;
|
||||||
|
position: absolute;
|
||||||
|
left: 25vw;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.bgBoxImg {
|
.bgBoxImg {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 23%;
|
left: 23%;
|
||||||
transition: all 0.3s linear;
|
transition: all 0.3s linear;
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export default {
|
|||||||
value:"enx",
|
value:"enx",
|
||||||
label:"Entropyx(Enx)",
|
label:"Entropyx(Enx)",
|
||||||
img:`${this.$baseApi}img/enx.svg`,
|
img:`${this.$baseApi}img/enx.svg`,
|
||||||
rate:"0",
|
rate:"1%",
|
||||||
address:"",
|
address:"",
|
||||||
mode:"PPLNS+PROPDIF",
|
mode:"PPLNS+PROPDIF",
|
||||||
quota:"5000",
|
quota:"5000",
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
<div class="collapseTitle">
|
<div class="collapseTitle">
|
||||||
<span ><img :src="item.img" alt="coin" loading="lazy"> {{item.label}}</span>
|
<span ><img :src="item.img" alt="coin" loading="lazy"> {{item.label}}</span>
|
||||||
<span v-if="item.value === 'enx'"> {{ $t(`course.timeLimited`) }} 0%</span>
|
<!-- <span v-if="item.value === 'enx'"> {{ $t(`course.timeLimited`) }} 0%</span> -->
|
||||||
<span v-else>{{item.rate}}</span>
|
<span >{{item.rate}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<section class="contentBox2">
|
<section class="contentBox2">
|
||||||
@@ -76,8 +76,8 @@
|
|||||||
<li v-for="item in rateList" :key="item.value">
|
<li v-for="item in rateList" :key="item.value">
|
||||||
<span class="coin"><img :src="item.img" alt="coin" loading="lazy"> {{item.label}}</span>
|
<span class="coin"><img :src="item.img" alt="coin" loading="lazy"> {{item.label}}</span>
|
||||||
<span>{{item.address}}</span>
|
<span>{{item.address}}</span>
|
||||||
<span v-if="item.value === 'enx'"> {{ $t(`course.timeLimited`) }} 0%</span>
|
<!-- <span v-if="item.value === 'enx'"> {{ $t(`course.timeLimited`) }} 0%</span> -->
|
||||||
<span v-else>{{item.rate}}</span>
|
<span >{{item.rate}}</span>
|
||||||
<span>{{item.mode}}</span>
|
<span>{{item.mode}}</span>
|
||||||
<span>{{item.quota}}</span>
|
<span>{{item.quota}}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,153 +1,397 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 1300px; height: 600px">
|
<div>
|
||||||
<div id="chart" style="width: 100%; height: 100%; min-width: 500px"></div>
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<!-- 用户ID输入部分 -->
|
||||||
|
<div class="user-input-container">
|
||||||
|
<div class="input-group" :class="{ 'disabled': isConnected }">
|
||||||
|
<input
|
||||||
|
v-model="email"
|
||||||
|
placeholder="请输入您的用户邮箱"
|
||||||
|
:disabled="isConnected"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="targetEmail"
|
||||||
|
placeholder="请输入目标用户邮箱"
|
||||||
|
:disabled="isConnected"
|
||||||
|
@keyup.enter="!isConnected && !isConnecting && connectWebSocket()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="button-group">
|
||||||
|
<button
|
||||||
|
@click="connectWebSocket"
|
||||||
|
:disabled="isConnected || isConnecting || !email || !targetEmail"
|
||||||
|
:class="{ 'disabled': isConnected || isConnecting || !email || !targetEmail }"
|
||||||
|
>
|
||||||
|
{{ isConnecting ? '连接中...' : '连接' }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="isConnected"
|
||||||
|
@click="disconnectWebSocket"
|
||||||
|
class="disconnect-btn"
|
||||||
|
>
|
||||||
|
断开连接
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="connectionError" class="error-message">
|
||||||
|
{{ connectionError }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="isConnected">
|
||||||
|
<!-- WebSocket 聊天部分 -->
|
||||||
|
<div class="chat-container">
|
||||||
|
<div class="message-list" ref="messageList">
|
||||||
|
<div v-for="(msg, index) in receivedMessages" :key="index" class="message"
|
||||||
|
:class="{ 'error-message': msg.error }">
|
||||||
|
<div v-if="typeof msg === 'string'">{{ msg }}</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="message-header">
|
||||||
|
<span class="message-sender">{{ msg.sender || 'Unknown' }}</span>
|
||||||
|
<span class="message-time">{{ formatTime(msg.timestamp) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="message-content">{{ msg.content }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
<textarea
|
||||||
|
v-model="message"
|
||||||
|
@keyup.enter="sendMessage"
|
||||||
|
placeholder="输入消息..."
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
<button @click="sendMessage" :disabled="!message.trim()">
|
||||||
|
发送
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import * as echarts from "echarts";
|
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
|
||||||
export default {
|
import { Stomp } from '@stomp/stompjs'
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
countDownTime: 60,
|
|
||||||
timer: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
const props = defineProps({
|
||||||
let base = +new Date(1968, 9, 3);
|
msg: {
|
||||||
let oneDay = 24 * 3600 * 1000;
|
type: String,
|
||||||
let date = [];
|
required: true
|
||||||
let data = [Math.random() * 300];
|
}
|
||||||
for (let i = 1; i < 20000; i++) {
|
})
|
||||||
var now = new Date((base += oneDay));
|
|
||||||
date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join("/"));
|
const message = ref('')
|
||||||
data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
|
const receivedMessages = ref([])
|
||||||
|
const email = ref('')
|
||||||
|
const targetEmail = ref('')
|
||||||
|
const isConnected = ref(false)
|
||||||
|
const isConnecting = ref(false)
|
||||||
|
const connectionError = ref('')
|
||||||
|
const messageList = ref(null)
|
||||||
|
|
||||||
|
// 创建一个响应式的 stompClient
|
||||||
|
const stompClient = ref(null)
|
||||||
|
|
||||||
|
// 添加连接时间变量
|
||||||
|
const connectTime = ref(null)
|
||||||
|
|
||||||
|
// 自动滚动到底部
|
||||||
|
const scrollToBottom = async () => {
|
||||||
|
await nextTick()
|
||||||
|
if (messageList.value) {
|
||||||
|
messageList.value.scrollTop = messageList.value.scrollHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听消息列表变化,自动滚动
|
||||||
|
watch(receivedMessages, () => {
|
||||||
|
scrollToBottom()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const formatTime = (timestamp) => {
|
||||||
|
if (!timestamp) return ''
|
||||||
|
try {
|
||||||
|
const date = new Date(timestamp)
|
||||||
|
return date.toLocaleTimeString()
|
||||||
|
} catch (e) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接WebSocket
|
||||||
|
const connectWebSocket = () => {
|
||||||
|
if (!email.value || !targetEmail.value) {
|
||||||
|
connectionError.value = '请输入用户邮箱和目标用户邮箱'
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 10 个空数据在前后
|
connectionError.value = ''
|
||||||
for (let i = 0; i < 100; i++) {
|
isConnecting.value = true
|
||||||
date.unshift(null);
|
connectTime.value = new Date() // 记录连接时间
|
||||||
data.unshift(null);
|
|
||||||
}
|
try {
|
||||||
for (let i = 0; i < 100; i++) {
|
stompClient.value = Stomp.client('ws://localhost:8101/chat/ws')
|
||||||
date.push(null);
|
stompClient.value.heartbeat.outgoing = 20000
|
||||||
data.push(null);
|
stompClient.value.heartbeat.incoming = 0
|
||||||
|
|
||||||
|
const connectHeaders = {
|
||||||
|
'email': email.value,
|
||||||
|
'type': 2 //0 游客 1 登录用户 2 客服
|
||||||
}
|
}
|
||||||
|
|
||||||
var option = {
|
stompClient.value.connect(
|
||||||
tooltip: {
|
connectHeaders,
|
||||||
trigger: "axis",
|
function(frame) {
|
||||||
position: function (pt) {
|
console.log('连接成功: ' + frame)
|
||||||
return [pt[0], "10%"];
|
console.log('连接时间:', connectTime.value?.toLocaleString())
|
||||||
},
|
isConnected.value = true
|
||||||
},
|
isConnecting.value = false
|
||||||
title: {
|
|
||||||
left: "center",
|
// 添加系统消息
|
||||||
text: "Large Area Chart",
|
receivedMessages.value.push({
|
||||||
},
|
sender: 'System',
|
||||||
toolbox: {
|
content: '已连接到聊天服务器',
|
||||||
feature: {
|
timestamp: new Date().toISOString(),
|
||||||
dataZoom: {
|
system: true
|
||||||
yAxisIndex: "none",
|
})
|
||||||
},
|
|
||||||
restore: {},
|
// 订阅自己管道的消息
|
||||||
saveAsImage: {},
|
stompClient.value.subscribe(`/user/queue/${email.value}`, function(message) {
|
||||||
},
|
console.log('收到消息:', message.body)
|
||||||
},
|
try {
|
||||||
xAxis: {
|
const parsedMessage = JSON.parse(message.body)
|
||||||
type: "category",
|
receivedMessages.value.push(parsedMessage)
|
||||||
// boundaryGap: [0.5, 0.5],
|
} catch (error) {
|
||||||
data: date,
|
console.error('消息解析失败:', error)
|
||||||
},
|
receivedMessages.value.push({
|
||||||
yAxis: [
|
sender: 'System',
|
||||||
{
|
content: `消息格式错误: ${message.body}`,
|
||||||
type: "value",
|
timestamp: new Date().toISOString(),
|
||||||
boundaryGap: [0, "100%"],
|
error: true
|
||||||
axisLine: {
|
})
|
||||||
show: true, // 显示 Y 轴线条
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
position: "right",
|
|
||||||
type: "value",
|
|
||||||
boundaryGap: [0, "100%"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
dataZoom: [
|
|
||||||
{
|
|
||||||
type: "inside",
|
|
||||||
start: 0,
|
|
||||||
end: 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
start: 0,
|
|
||||||
end: 10,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "Fake Data",
|
|
||||||
type: "line",
|
|
||||||
symbol: "none",
|
|
||||||
sampling: "lttb",
|
|
||||||
itemStyle: {
|
|
||||||
color: "rgb(255, 70, 131)",
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
this.myChart = echarts.init(document.getElementById("chart"));
|
|
||||||
this.myChart.setOption(option);
|
|
||||||
window.addEventListener(
|
|
||||||
"resize", () => {
|
|
||||||
if (this.myChart) this.myChart.resize();
|
|
||||||
}
|
}
|
||||||
);
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
function(error) {
|
||||||
//初始化图表
|
console.error('连接失败:', error)
|
||||||
inCharts() {
|
isConnected.value = false
|
||||||
if (this.myChart == null) {
|
isConnecting.value = false
|
||||||
this.myChart = echarts.init(document.getElementById("chart"));
|
connectionError.value = `连接失败: ${error.headers?.message || error.message || '未知错误'}`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('初始化WebSocket客户端失败:', error)
|
||||||
|
isConnected.value = false
|
||||||
|
isConnecting.value = false
|
||||||
|
connectionError.value = `初始化失败: ${error.message || '未知错误'}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加断开连接方法
|
||||||
|
const disconnectWebSocket = () => {
|
||||||
|
if (stompClient.value?.connected) {
|
||||||
|
stompClient.value.disconnect(() => {
|
||||||
|
const disconnectTime = new Date()
|
||||||
|
const duration = connectTime.value ?
|
||||||
|
Math.floor((disconnectTime.getTime() - connectTime.value.getTime()) / 1000) : 0
|
||||||
|
|
||||||
|
console.log('断开连接时间:', disconnectTime.toLocaleString())
|
||||||
|
console.log(`连接持续时间: ${Math.floor(duration / 60)}分${duration % 60}秒`)
|
||||||
|
|
||||||
|
isConnected.value = false
|
||||||
|
receivedMessages.value = []
|
||||||
|
connectTime.value = null
|
||||||
|
|
||||||
|
// 添加提示
|
||||||
|
connectionError.value = '已断开连接'
|
||||||
|
setTimeout(() => {
|
||||||
|
connectionError.value = ''
|
||||||
|
}, 3000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息方法
|
||||||
|
const sendMessage = () => {
|
||||||
|
if (!message.value.trim()) return
|
||||||
|
|
||||||
|
if (stompClient.value?.connected) {
|
||||||
|
try {
|
||||||
|
const messageObj = {
|
||||||
|
email: targetEmail.value,
|
||||||
|
content: message.value.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.option.series[0].name = this.$t(`home.computingPower`);
|
stompClient.value.send(
|
||||||
this.option.series[1].name = this.$t(`home.currencyPrice`);
|
`/point/send/message`,
|
||||||
|
{},
|
||||||
|
JSON.stringify(messageObj)
|
||||||
|
)
|
||||||
|
|
||||||
this.myChart.setOption(this.option);
|
// 添加自己发送的消息到显示列表
|
||||||
// 回调函数,在渲染完成后执行
|
receivedMessages.value.push({
|
||||||
this.myChart.on("finished", () => {
|
sender: email.value,
|
||||||
// 在这里执行显示给用户的操作
|
content: message.value.trim(),
|
||||||
// console.log('图表渲染完成,显示给用户');
|
timestamp: new Date().toISOString(),
|
||||||
this.minerChartLoading = false;
|
isSelf: true
|
||||||
});
|
})
|
||||||
// window.addEventListener("resize", () => {
|
|
||||||
// if (this.myChart) this.myChart.resize();
|
|
||||||
// });
|
|
||||||
|
|
||||||
window.addEventListener(
|
message.value = ''
|
||||||
"resize",
|
} catch (error) {
|
||||||
throttle(() => {
|
console.error('发送消息失败:', error)
|
||||||
if (this.myChart) this.myChart.resize();
|
|
||||||
}, 200)
|
receivedMessages.value.push({
|
||||||
);
|
sender: 'System',
|
||||||
},
|
content: `发送失败: ${error.message || '未知错误'}`,
|
||||||
startCountDown() {
|
timestamp: new Date().toISOString(),
|
||||||
this.timer = setInterval(() => {
|
error: true
|
||||||
if (this.countDownTime <= 0) {
|
})
|
||||||
//当监测到countDownTime为0时,清除计数器并且移除sessionStorage,然后执行提交试卷逻辑
|
|
||||||
clearInterval(this.timer);
|
|
||||||
sessionStorage.removeItem("exam_time");
|
|
||||||
alert("提交试卷");
|
|
||||||
} else if (this.countDownTime > 0) {
|
|
||||||
//每秒让countDownTime -1秒,并设置到sessionStorage中
|
|
||||||
this.countDownTime--;
|
|
||||||
window.sessionStorage.setItem("exam_time", this.countDownTime);
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
} else {
|
||||||
},
|
connectionError.value = '连接已断开,请重新连接'
|
||||||
},
|
isConnected.value = false
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件卸载时断开连接
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (stompClient.value?.connected) {
|
||||||
|
stompClient.value.disconnect()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-input-container {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-list {
|
||||||
|
height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 8px;
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-sender {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message[class*="isSelf"] {
|
||||||
|
background-color: #dcf8c6;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
background-color: #ffebee;
|
||||||
|
color: #d32f2f;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 10px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: inherit;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover:not(:disabled) {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disconnect-btn {
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disconnect-btn:hover {
|
||||||
|
background-color: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled, textarea:disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -105,9 +105,9 @@ export default {
|
|||||||
console.log(res,"文件返回");
|
console.log(res,"文件返回");
|
||||||
|
|
||||||
this.ruleForm.files = res.data.data.id
|
this.ruleForm.files = res.data.data.id
|
||||||
if (this.ruleForm.files) {//成功拿到返回ID
|
// if (this.ruleForm.files) {//成功拿到返回ID
|
||||||
this.fetchSubmitWork(this.ruleForm)
|
// this.fetchSubmitWork(this.ruleForm)
|
||||||
}
|
// }
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|||||||
1
mining-pool/test/css/app-113c6c50.af06316f.css
Normal file
1
mining-pool/test/css/app-113c6c50.af06316f.css
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/css/app-113c6c50.af06316f.css.gz
Normal file
BIN
mining-pool/test/css/app-113c6c50.af06316f.css.gz
Normal file
Binary file not shown.
1
mining-pool/test/css/app-42f9d7e6.23095695.css
Normal file
1
mining-pool/test/css/app-42f9d7e6.23095695.css
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/css/app-42f9d7e6.23095695.css.gz
Normal file
BIN
mining-pool/test/css/app-42f9d7e6.23095695.css.gz
Normal file
Binary file not shown.
1
mining-pool/test/css/app-72600b29.83c22f01.css
Normal file
1
mining-pool/test/css/app-72600b29.83c22f01.css
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/css/app-72600b29.83c22f01.css.gz
Normal file
BIN
mining-pool/test/css/app-72600b29.83c22f01.css.gz
Normal file
Binary file not shown.
1
mining-pool/test/css/app-b4c4f6ec.c96edfc1.css
Normal file
1
mining-pool/test/css/app-b4c4f6ec.c96edfc1.css
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/css/app-b4c4f6ec.c96edfc1.css.gz
Normal file
BIN
mining-pool/test/css/app-b4c4f6ec.c96edfc1.css.gz
Normal file
Binary file not shown.
BIN
mining-pool/test/img/home.2a3cb050.png
Normal file
BIN
mining-pool/test/img/home.2a3cb050.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 716 KiB |
BIN
mining-pool/test/img/home.4c2d8f62.png
Normal file
BIN
mining-pool/test/img/home.4c2d8f62.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
@@ -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_irzdjxdsrq8.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.d4a64849.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.454dc86a.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.b12571df.js></script><script defer src=/js/app-5c551db8.4db2eb93.js></script><script defer src=/js/app-01dc9ae1.188fe4f5.js></script><script defer src=/js/app-b4c4f6ec.025712d3.js></script><script defer src=/js/app-72600b29.5a5f9303.js></script><script defer src=/js/app-f035d474.30e8939b.js></script><script defer src=/js/app-113c6c50.96c3bebd.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/app-42f9d7e6.afc6aa48.css rel=stylesheet><link href=/css/app-01dc9ae1.825b7ca3.css rel=stylesheet><link href=/css/app-b4c4f6ec.fbcc1022.css rel=stylesheet><link href=/css/app-72600b29.4fd214e9.css rel=stylesheet><link href=/css/app-f035d474.0e6b8898.css rel=stylesheet><link href=/css/app-113c6c50.6cbc2492.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_irzdjxdsrq8.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.17cb0808.js></script><script defer src=/js/app-5c551db8.2b99b68c.js></script><script defer src=/js/app-01dc9ae1.188fe4f5.js></script><script defer src=/js/app-b4c4f6ec.bf0536f4.js></script><script defer src=/js/app-72600b29.6b68c3d1.js></script><script defer src=/js/app-f035d474.30e8939b.js></script><script defer src=/js/app-113c6c50.28d27f0c.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/app-42f9d7e6.23095695.css rel=stylesheet><link href=/css/app-01dc9ae1.825b7ca3.css rel=stylesheet><link href=/css/app-b4c4f6ec.c96edfc1.css rel=stylesheet><link href=/css/app-72600b29.83c22f01.css rel=stylesheet><link href=/css/app-f035d474.0e6b8898.css rel=stylesheet><link href=/css/app-113c6c50.af06316f.css rel=stylesheet></head><body><div id=app></div></body></html>
|
||||||
1
mining-pool/test/js/app-113c6c50.28d27f0c.js
Normal file
1
mining-pool/test/js/app-113c6c50.28d27f0c.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/app-113c6c50.28d27f0c.js.gz
Normal file
BIN
mining-pool/test/js/app-113c6c50.28d27f0c.js.gz
Normal file
Binary file not shown.
1
mining-pool/test/js/app-42f9d7e6.17cb0808.js
Normal file
1
mining-pool/test/js/app-42f9d7e6.17cb0808.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/app-42f9d7e6.17cb0808.js.gz
Normal file
BIN
mining-pool/test/js/app-42f9d7e6.17cb0808.js.gz
Normal file
Binary file not shown.
1
mining-pool/test/js/app-5c551db8.2b99b68c.js
Normal file
1
mining-pool/test/js/app-5c551db8.2b99b68c.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/app-5c551db8.2b99b68c.js.gz
Normal file
BIN
mining-pool/test/js/app-5c551db8.2b99b68c.js.gz
Normal file
Binary file not shown.
1
mining-pool/test/js/app-72600b29.6b68c3d1.js
Normal file
1
mining-pool/test/js/app-72600b29.6b68c3d1.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/app-72600b29.6b68c3d1.js.gz
Normal file
BIN
mining-pool/test/js/app-72600b29.6b68c3d1.js.gz
Normal file
Binary file not shown.
1
mining-pool/test/js/app-b4c4f6ec.bf0536f4.js
Normal file
1
mining-pool/test/js/app-b4c4f6ec.bf0536f4.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/app-b4c4f6ec.bf0536f4.js.gz
Normal file
BIN
mining-pool/test/js/app-b4c4f6ec.bf0536f4.js.gz
Normal file
Binary file not shown.
18
mining-pool/test/js/chunk-vendors-377fed06.159de137.js
Normal file
18
mining-pool/test/js/chunk-vendors-377fed06.159de137.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/chunk-vendors-377fed06.159de137.js.gz
Normal file
BIN
mining-pool/test/js/chunk-vendors-377fed06.159de137.js.gz
Normal file
Binary file not shown.
16
mining-pool/test/js/chunk-vendors-89d5c698.2190b4ca.js
Normal file
16
mining-pool/test/js/chunk-vendors-89d5c698.2190b4ca.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/chunk-vendors-89d5c698.2190b4ca.js.gz
Normal file
BIN
mining-pool/test/js/chunk-vendors-89d5c698.2190b4ca.js.gz
Normal file
Binary file not shown.
3
mining-pool/test/js/chunk-vendors-945ce2fe.648a91a9.js
Normal file
3
mining-pool/test/js/chunk-vendors-945ce2fe.648a91a9.js
Normal file
File diff suppressed because one or more lines are too long
BIN
mining-pool/test/js/chunk-vendors-945ce2fe.648a91a9.js.gz
Normal file
BIN
mining-pool/test/js/chunk-vendors-945ce2fe.648a91a9.js.gz
Normal file
Binary file not shown.
@@ -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-04-18T06:25:55.062Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-04-18T06:25:55.062Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-04-18T06:25:55.062Z</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-04-22T06:17:28.553Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-04-22T06:17:28.553Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
||||||
Binary file not shown.
@@ -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-04-18T06:25:55.043Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-04-18T06:25:55.052Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-04-18T06:25:55.053Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-04-18T06:25:55.053Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-04-18T06:25:55.053Z</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-04-22T06:17:28.543Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-04-22T06:17:28.543Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
||||||
Binary file not shown.
Reference in New Issue
Block a user