38730-vm/assets/js/main.js
2026-02-24 14:03:15 +00:00

186 lines
7.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

document.addEventListener('DOMContentLoaded', () => {
// Elements
const clockEl = document.getElementById('real-time-clock');
const outputEl = document.getElementById('reportOutput');
const btnCopy = document.getElementById('btnCopy');
const btnBatchParse = document.getElementById('btnBatchParse');
const btnClearBatch = document.getElementById('btnClearBatch');
const batchInput = document.getElementById('batchInput');
const toastMessage = document.getElementById('toastMessage');
const toastEl = document.getElementById('liveToast');
const toast = new bootstrap.Toast(toastEl);
// Initialize Real-time Clock
const updateClock = () => {
const now = new Date();
const options = {
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
};
const formatted = now.toLocaleString('zh-CN', options).replace(/\//g, '-');
if (clockEl) clockEl.textContent = formatted;
};
setInterval(updateClock, 1000);
updateClock();
// Show Toast Helper
const showToast = (msg, isError = false) => {
toastMessage.textContent = msg;
const iconContainer = toastMessage.previousElementSibling;
if (iconContainer) {
const icon = isError ? 'fa-circle-xmark text-danger' : 'fa-circle-check text-success';
iconContainer.className = `fa-solid ${icon} me-2`;
}
toast.show();
};
// Global button click feedback
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', (e) => {
if (btn.id === 'btnBatchParse' || btn.id === 'btnClearBatch' || btn.id === 'btnCopy') return;
if (btn.classList.contains('carousel-control-prev') || btn.classList.contains('carousel-control-next')) {
showToast('切换轮播图');
} else if (btn.hasAttribute('data-bs-slide-to')) {
showToast('切换到幻灯片 ' + (parseInt(btn.getAttribute('data-bs-slide-to')) + 1));
} else if (!btn.classList.contains('btn-close')) {
showToast('功能已触达');
}
});
});
// Helper to format the final report (Exact format requested)
const formatReport = (stats) => {
return `总WS数量 ${stats.totalWS}
WS今日封号 ${stats.wsBanned}
总永封WS ${stats.wsPermBanned}
总XHS数量 ${stats.totalXHS}
总SMS数量 ${stats.totalSMS}
XHS ${stats.xhs}
回复: ${stats.xhs_reply}
WS ${stats.ws}
回复: ${stats.ws_reply}
SMS ${stats.sms}
回复: ${stats.sms_reply}
总招呼量: ${stats.totalGreeting}
总回复: ${stats.totalReply}
再聊: ${stats.rechat}
引流: ${stats.traffic}
语音: ${stats.voice}`;
};
// Robust Parsing Logic
const parseBatchData = () => {
const text = batchInput.value.trim();
if (!text) {
showToast('请先粘贴报表内容!', true);
return;
}
const totals = {
totalWS: 0, wsBanned: 0, wsPermBanned: 0, totalXHS: 0, totalSMS: 0,
xhs: 0, xhs_reply: 0, ws: 0, ws_reply: 0, sms: 0, sms_reply: 0,
totalGreeting: 0, totalReply: 0, rechat: 0, traffic: 0, voice: 0
};
// Helper to extract a single value from a chunk
const extractVal = (pattern, content) => {
const match = content.match(pattern);
return match ? parseInt(match[1], 10) : 0;
};
// Identify distinct reports by "总WS数量" delimiter
const reportChunks = text.split(/总WS数量/);
reportChunks.forEach((chunk, index) => {
if (!chunk.trim() && index === 0) return;
const fullChunk = (index === 0 && !text.startsWith('总WS数量')) ? chunk : '总WS数量' + chunk;
// Basic fields
totals.totalWS += extractVal(/总WS数量[:\s]+(\d+)/, fullChunk);
totals.wsBanned += extractVal(/WS今日封号[:\s]+(\d+)/, fullChunk);
totals.wsPermBanned += extractVal(/总永封WS[:\s]+(\d+)/, fullChunk);
totals.totalXHS += extractVal(/总XHS数量[:\s]+(\d+)/, fullChunk);
totals.totalSMS += extractVal(/总SMS数量[:\s]+(\d+)/, fullChunk);
// XHS & Reply (Targeted extraction)
const xhsMatch = fullChunk.match(/XHS招呼量[:\s]+(\d+)[\s\S]*?回复[:\s]+(\d+)/);
if (xhsMatch) {
totals.xhs += parseInt(xhsMatch[1], 10);
totals.xhs_reply += parseInt(xhsMatch[2], 10);
} else {
totals.xhs += extractVal(/XHS(?:招呼量)?[:\s]+(\d+)/, fullChunk);
const genericXhsReply = fullChunk.match(/XHS[\s\S]*?回复[:\s]+(\d+)/);
if (genericXhsReply) totals.xhs_reply += parseInt(genericXhsReply[1], 10);
}
// WS & Reply
const wsMatch = fullChunk.match(/WS招呼量[:\s]+(\d+)[\s\S]*?回复[:\s]+(\d+)/);
if (wsMatch) {
totals.ws += parseInt(wsMatch[1], 10);
totals.ws_reply += parseInt(wsMatch[2], 10);
} else {
totals.ws += extractVal(/WS(?:招呼量)?[:\s]+(\d+)/, fullChunk);
const genericWsReply = fullChunk.match(/WS[\s\S]*?回复[:\s]+(\d+)/);
if (genericWsReply) totals.ws_reply += parseInt(genericWsReply[1], 10);
}
// SMS & Reply
const smsMatch = fullChunk.match(/SMS招呼量[:\s]+(\d+)[\s\S]*?回复[:\s]+(\d+)/);
if (smsMatch) {
totals.sms += parseInt(smsMatch[1], 10);
totals.sms_reply += parseInt(smsMatch[2], 10);
} else {
totals.sms += extractVal(/SMS(?:招呼量)?[:\s]+(\d+)/, fullChunk);
const genericSmsReply = fullChunk.match(/SMS[\s\S]*?回复[:\s]+(\d+)/);
if (genericSmsReply) totals.sms_reply += parseInt(genericSmsReply[1], 10);
}
// Bottom fields
totals.totalGreeting += extractVal(/总招呼量[:\s]+(\d+)/, fullChunk);
totals.totalReply += extractVal(/总回复[:\s]+(\d+)/, fullChunk);
totals.rechat += extractVal(/再聊[:\s]+(\d+)/, fullChunk);
totals.traffic += extractVal(/引流[:\s]+(\d+)/, fullChunk);
totals.voice += extractVal(/语音[:\s]+(\d+)/, fullChunk);
});
outputEl.textContent = formatReport(totals);
btnCopy.disabled = false;
showToast('报表汇总成功!');
};
// Events
if (btnBatchParse) {
btnBatchParse.addEventListener('click', () => {
showToast('深度解析中...');
setTimeout(parseBatchData, 400);
});
}
if (btnClearBatch) {
btnClearBatch.addEventListener('click', () => {
batchInput.value = '';
outputEl.textContent = '数据结果将在此处生成...';
btnCopy.disabled = true;
showToast('输入区域已清空');
});
}
if (btnCopy) {
btnCopy.addEventListener('click', () => {
const text = outputEl.textContent;
if (text && !text.includes('在此处生成')) {
navigator.clipboard.writeText(text).then(() => {
showToast('汇总报表已复制成功!');
}).catch(err => {
console.error('Copy failed', err);
showToast('复制失败', true);
});
} else {
showToast('无可复制内容', true);
}
});
}
});