Files
hiderfong 6d70520e79 feat: 全量功能模块开发与集成测试修复
- 新增后端模块:Alert、APIAsset、Compliance、Lineage、Masking、Risk、SchemaChange、Unstructured、Watermark
- 新增前端模块页面与API接口
- 新增Alembic迁移脚本(002-014)覆盖全量业务表
- 新增测试数据生成脚本与集成测试脚本
- 修复metadata模型JSON类型导入缺失导致启动失败的问题
- 修复前端Alert/APIAsset页面request模块路径错误
- 更新docker-compose与开发计划文档
2026-04-25 08:51:38 +08:00

70 lines
3.7 KiB
HTML
Raw Permalink 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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>报告预览</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; color: #333; background: #f5f7fa; }
.page { max-width: 800px; margin: 0 auto; background: #fff; padding: 48px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); }
h1 { text-align: center; font-size: 24px; margin-bottom: 32px; }
h2 { font-size: 16px; border-left: 4px solid #409eff; padding-left: 8px; margin-top: 24px; }
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
th, td { border: 1px solid #dcdfe6; padding: 8px 12px; text-align: left; }
th { background: #f5f7fa; }
.highlight { background: #fde2e2; }
.info { color: #909399; font-size: 12px; margin-top: 4px; }
.print-btn { position: fixed; top: 20px; right: 20px; padding: 8px 16px; background: #409eff; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
@media print { .print-btn { display: none; } body { margin: 0; background: #fff; } .page { box-shadow: none; } }
</style>
</head>
<body>
<button class="print-btn" onclick="window.print()">打印 / 保存为PDF</button>
<div class="page">
<h1>数据分类分级项目报告</h1>
<div id="content">加载中...</div>
</div>
<script>
const params = new URLSearchParams(location.search);
const projectId = params.get('projectId');
const apiBase = '/api/v1';
async function load() {
if (!projectId) { document.getElementById('content').innerText = '缺少项目ID'; return; }
try {
const res = await fetch(`${apiBase}/reports/projects/${projectId}/summary`);
const json = await res.json();
const d = json.data;
let html = '';
html += '<h2>一、项目基本信息</h2>';
html += '<table><tr><th>项目名称</th><td>' + (d.project_name || '') + '</td></tr>';
html += '<tr><th>报告生成时间</th><td>' + (d.generated_at || '').slice(0,19).replace('T',' ') + '</td></tr>';
html += '<tr><th>项目状态</th><td>' + (d.status || '') + '</td></tr>';
html += '<tr><th>模板版本</th><td>' + (d.template_version || '') + '</td></tr></table>';
html += '<h2>二、分类分级统计</h2>';
html += '<p>总字段数: ' + d.total + ' | 自动识别: ' + d.auto + ' | 人工打标: ' + d.manual + '</p>';
html += '<h2>三、分级分布</h2><table><tr><th>分级</th><th>数量</th><th>占比</th></tr>';
d.level_distribution.forEach(item => {
const pct = d.total ? (item.count / d.total * 100).toFixed(1) + '%' : '0%';
const cls = item.name.includes('L4') || item.name.includes('L5') ? 'highlight' : '';
html += '<tr class="' + cls + '"><td>' + item.name + '</td><td>' + item.count + '</td><td>' + pct + '</td></tr>';
});
html += '</table>';
html += '<h2>四、高敏感数据清单(L4/L5</h2>';
if (d.high_risk && d.high_risk.length) {
html += '<table><tr><th>字段名</th><th>所属表</th><th>分类</th><th>分级</th><th>来源</th></tr>';
d.high_risk.forEach(r => {
html += '<tr class="highlight"><td>' + r.column_name + '</td><td>' + r.table_name + '</td><td>' + r.category_name + '</td><td>' + r.level_name + '</td><td>' + r.source + '</td></tr>';
});
html += '</table>';
} else {
html += '<p>暂无L4/L5级高敏感数据。</p>';
}
document.getElementById('content').innerHTML = html;
} catch (e) {
document.getElementById('content').innerText = '加载失败: ' + e.message;
}
}
load();
</script>
</body>
</html>