feat: MC Report System - MySQL + Express + Vanilla JS SPA
This commit is contained in:
88
public/js/pages/export-page.js
Normal file
88
public/js/pages/export-page.js
Normal file
@@ -0,0 +1,88 @@
|
||||
const ExportPage = {
|
||||
async render() { return '<div class="loading"><i class="fas fa-spinner"></i></div>'; },
|
||||
|
||||
mount() {
|
||||
const ct = document.getElementById('page-content');
|
||||
document.getElementById('page-title').textContent = '数据导出';
|
||||
document.getElementById('page-actions').innerHTML = '';
|
||||
|
||||
ct.innerHTML = `
|
||||
<div class="grid-2">
|
||||
<div class="card"><div class="card-h"><i class="fas fa-file-csv"></i> 导出工单</div><div class="card-b">
|
||||
<form id="exp-tickets">
|
||||
<div class="grid-2"><div class="form-group"><label>类型</label><select id="et-type"><option value="">全部</option>${Object.entries(U.TYPE).map(([k,v])=>`<option value="${k}">${v}</option>`).join('')}</select></div>
|
||||
<div class="form-group"><label>状态</label><select id="et-status"><option value="">全部</option>${Object.entries(U.STATUS).map(([k,v])=>`<option value="${k}">${v}</option>`).join('')}</select></div></div>
|
||||
<div class="grid-2"><div class="form-group"><label>开始日期</label><input type="date" id="et-start"></div><div class="form-group"><label>结束日期</label><input type="date" id="et-end"></div></div>
|
||||
<div class="form-group"><label>格式</label><select id="et-fmt"><option value="csv">CSV (Excel)</option><option value="json">JSON</option></select></div>
|
||||
<button type="submit" class="btn btn-p btn-sm"><i class="fas fa-download"></i> 导出</button>
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<div class="card"><div class="card-h"><i class="fas fa-user-slash"></i> 被举报人统计导出</div><div class="card-b">
|
||||
<p class="tm mb-4">导出所有被举报玩家列表,含被举报次数、处理结果、常见原因等</p>
|
||||
<form id="exp-reported">
|
||||
<div class="form-group"><label>格式</label><select id="er-fmt"><option value="csv">CSV (Excel)</option><option value="json">JSON</option></select></div>
|
||||
<button type="submit" class="btn btn-w btn-sm"><i class="fas fa-download"></i> 导出被举报人统计</button>
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<div class="card"><div class="card-h"><i class="fas fa-history"></i> 导出操作日志</div><div class="card-b">
|
||||
<form id="exp-logs">
|
||||
<div class="grid-2"><div class="form-group"><label>开始日期</label><input type="date" id="el-start"></div><div class="form-group"><label>结束日期</label><input type="date" id="el-end"></div></div>
|
||||
<div class="form-group"><label>格式</label><select id="el-fmt"><option value="csv">CSV (Excel)</option><option value="json">JSON</option></select></div>
|
||||
<button type="submit" class="btn btn-i btn-sm"><i class="fas fa-download"></i> 导出</button>
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<div class="card"><div class="card-h"><i class="fas fa-chart-bar"></i> 统计报表</div><div class="card-b">
|
||||
<p class="tm mb-4">查看系统整体统计和趋势数据</p>
|
||||
<button class="btn btn-p btn-sm" onclick="ExportPage.viewStats()"><i class="fas fa-chart-simple"></i> 查看统计</button>
|
||||
</div></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('exp-tickets').onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
const p = new URLSearchParams({
|
||||
format: document.getElementById('et-fmt').value,
|
||||
type: document.getElementById('et-type').value,
|
||||
status: document.getElementById('et-status').value,
|
||||
start_date: document.getElementById('et-start').value,
|
||||
end_date: document.getElementById('et-end').value,
|
||||
});
|
||||
try { await API.download(`/export/tickets?${p}`); } catch (ex) { alert(ex.message); }
|
||||
};
|
||||
|
||||
document.getElementById('exp-reported').onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
const p = new URLSearchParams({ format: document.getElementById('er-fmt').value });
|
||||
try { await API.download(`/export/reported-players?${p}`); } catch (ex) { alert(ex.message); }
|
||||
};
|
||||
|
||||
document.getElementById('exp-logs').onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
const p = new URLSearchParams({
|
||||
format: document.getElementById('el-fmt').value,
|
||||
start_date: document.getElementById('el-start').value,
|
||||
end_date: document.getElementById('el-end').value,
|
||||
});
|
||||
try { await API.download(`/export/audit-logs?${p}`); } catch (ex) { alert(ex.message); }
|
||||
};
|
||||
},
|
||||
|
||||
async viewStats() {
|
||||
try {
|
||||
const d = await API.get('/export/dashboard');
|
||||
U.modal('系统统计', `
|
||||
<div class="detail-section"><h4>概览</h4>
|
||||
<div class="detail-row"><span class="lbl">工单总数</span><span class="val fb">${d.total}</span></div>
|
||||
<div class="detail-row"><span class="lbl">今日新增</span><span class="val fb">${d.today}</span></div>
|
||||
<div class="detail-row"><span class="lbl">用户数</span><span class="val fb">${d.usersTotal}</span></div>
|
||||
</div>
|
||||
<div class="detail-section"><h4>状态分布</h4>${(d.byStatus||[]).map(r=>`<div class="detail-row"><span class="lbl">${U.STATUS[r.status]||r.status}</span><span class="val fb">${r.c}</span></div>`).join('')}</div>
|
||||
<div class="detail-section"><h4>类型分布</h4>${(d.byType||[]).map(r=>`<div class="detail-row"><span class="lbl">${U.TYPE[r.type]||r.type}</span><span class="val fb">${r.c}</span></div>`).join('')}</div>
|
||||
${d.monthly?.length?`<div class="detail-section"><h4>月度趋势</h4>${d.monthly.map(m=>`<div class="detail-row"><span class="lbl">${m.m}</span><span class="val fb">${m.c} 条</span></div>`).join('')}</div>`:''}
|
||||
`, '600px');
|
||||
} catch (e) { alert(e.message); }
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user