报表2
This commit is contained in:
parent
0398cf54a2
commit
f33d58af44
@ -35,34 +35,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
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)
|
||||
// Helper to format the final report
|
||||
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}
|
||||
XHS: ${stats.xhs} 回复: ${stats.xhs_reply}
|
||||
WS: ${stats.ws} 回复: ${stats.ws_reply}
|
||||
SMS: ${stats.sms} 回复: ${stats.sms_reply}
|
||||
总招呼量: ${stats.totalGreeting}
|
||||
总回复: ${stats.totalReply}
|
||||
再聊: ${stats.rechat}
|
||||
@ -70,7 +52,7 @@ SMS: ${stats.sms}
|
||||
语音: ${stats.voice}`;
|
||||
};
|
||||
|
||||
// Robust Parsing Logic
|
||||
// Improved Extraction Logic
|
||||
const parseBatchData = () => {
|
||||
const text = batchInput.value.trim();
|
||||
if (!text) {
|
||||
@ -84,68 +66,90 @@ SMS: ${stats.sms}
|
||||
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;
|
||||
const extractVal = (patterns, content) => {
|
||||
if (!Array.isArray(patterns)) patterns = [patterns];
|
||||
for (const p of patterns) {
|
||||
const match = content.match(p);
|
||||
if (match) {
|
||||
const cleanVal = match[1].replace(/,/g, '');
|
||||
return parseInt(cleanVal, 10) || 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Identify distinct reports by "总WS数量" delimiter
|
||||
const reportChunks = text.split(/总WS数量/);
|
||||
|
||||
reportChunks.forEach((chunk, index) => {
|
||||
if (!chunk.trim() && index === 0) return;
|
||||
const extractPlatformStats = (platformLabel, content) => {
|
||||
// Priority: specifically look for "Platform招呼量"
|
||||
// Second: look for "Platform" if not part of "总...数量" or "...封号"
|
||||
const regex = new RegExp('(总)?' + platformLabel + '(数量|今日封号|招呼量)?[^0-9]*([0-9,]+)', 'gi');
|
||||
let bestMatch = null;
|
||||
let m;
|
||||
|
||||
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);
|
||||
while ((m = regex.exec(content)) !== null) {
|
||||
const isTotal = !!m[1];
|
||||
const suffix = m[2] || '';
|
||||
const isMeta = suffix === '数量' || suffix === '今日封号';
|
||||
|
||||
// We want the one that is NOT "总WS数量" and NOT "WS今日封号"
|
||||
// Ideally it's "WS招呼量" or just "WS"
|
||||
if (!isTotal && !isMeta) {
|
||||
bestMatch = m;
|
||||
if (suffix === '招呼量') break; // Best possible match found
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
if (!bestMatch) return { count: 0, reply: 0 };
|
||||
|
||||
const count = parseInt(bestMatch[3].replace(/,/g, ''), 10) || 0;
|
||||
const afterMatch = content.substring(bestMatch.index + bestMatch[0].length);
|
||||
|
||||
// Look for "回复" after this count, but stop at next major label
|
||||
const stopLabel = /(XHS|WS|SMS|总招呼量|总回复|再聊|引流|语音|总WS数量|WS今日封号|总永封WS|总XHS数量|总SMS数量)/i.exec(afterMatch);
|
||||
const searchRange = afterMatch.substring(0, stopLabel ? stopLabel.index : 100);
|
||||
const rMatch = searchRange.match(/回复[^0-9]*([0-9,]+)/);
|
||||
|
||||
return {
|
||||
count: count,
|
||||
reply: rMatch ? (parseInt(rMatch[1].replace(/,/g, ''), 10) || 0) : 0
|
||||
};
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
// Split by "总WS数量"
|
||||
const reportChunks = text.split(/(?=总WS数量)/);
|
||||
|
||||
reportChunks.forEach((chunk) => {
|
||||
if (!chunk.trim()) return;
|
||||
|
||||
// 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);
|
||||
// Global Metrics
|
||||
totals.totalWS += extractVal([/总WS数量[::\s]*([0-9,]+)/, /WS数量[::\s]*([0-9,]+)/], chunk);
|
||||
totals.wsBanned += extractVal([/WS今日封号[::\s]*([0-9,]+)/, /今日封号[::\s]*([0-9,]+)/], chunk);
|
||||
totals.wsPermBanned += extractVal([/总永封WS[::\s]*([0-9,]+)/, /永封WS[::\s]*([0-9,]+)/], chunk);
|
||||
totals.totalXHS += extractVal([/总XHS数量[::\s]*([0-9,]+)/, /XHS数量[::\s]*([0-9,]+)/], chunk);
|
||||
totals.totalSMS += extractVal([/总SMS数量[::\s]*([0-9,]+)/, /SMS数量[::\s]*([0-9,]+)/], chunk);
|
||||
|
||||
// Platform Specifics
|
||||
const xData = extractPlatformStats('XHS', chunk);
|
||||
totals.xhs += xData.count;
|
||||
totals.xhs_reply += xData.reply;
|
||||
|
||||
const wData = extractPlatformStats('WS', chunk);
|
||||
totals.ws += wData.count;
|
||||
totals.ws_reply += wData.reply;
|
||||
|
||||
const sData = extractPlatformStats('SMS', chunk);
|
||||
totals.sms += sData.count;
|
||||
totals.sms_reply += sData.reply;
|
||||
|
||||
// Bottom Metrics
|
||||
totals.rechat += extractVal(/再聊[::\s]*([0-9,]+)/, chunk);
|
||||
totals.traffic += extractVal(/引流[::\s]*([0-9,]+)/, chunk);
|
||||
totals.voice += extractVal(/语音[::\s]*([0-9,]+)/, chunk);
|
||||
});
|
||||
|
||||
// Calculate Totals by Summing individual platform stats (More accurate than relying on member input)
|
||||
totals.totalGreeting = totals.xhs + totals.ws + totals.sms;
|
||||
totals.totalReply = totals.xhs_reply + totals.ws_reply + totals.sms_reply;
|
||||
|
||||
outputEl.textContent = formatReport(totals);
|
||||
btnCopy.disabled = false;
|
||||
showToast('报表汇总成功!');
|
||||
@ -154,7 +158,7 @@ SMS: ${stats.sms}
|
||||
// Events
|
||||
if (btnBatchParse) {
|
||||
btnBatchParse.addEventListener('click', () => {
|
||||
showToast('深度解析中...');
|
||||
showToast('解析中...');
|
||||
setTimeout(parseBatchData, 400);
|
||||
});
|
||||
}
|
||||
@ -173,9 +177,8 @@ SMS: ${stats.sms}
|
||||
const text = outputEl.textContent;
|
||||
if (text && !text.includes('在此处生成')) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
showToast('汇总报表已复制成功!');
|
||||
showToast('已复制成功!');
|
||||
}).catch(err => {
|
||||
console.error('Copy failed', err);
|
||||
showToast('复制失败', true);
|
||||
});
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user