feat(原型设计): 新增知识库管理与流程状态卡片
This commit is contained in:
@@ -355,6 +355,21 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.task-status-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.task-note {
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.task-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -488,6 +503,155 @@
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.phase-board {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.phase-card {
|
||||
padding: 14px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: #f8fafb;
|
||||
border: 1px solid #dbe4eb;
|
||||
min-height: 142px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.phase-card.running {
|
||||
background: #eef4fb;
|
||||
border-color: #bfd2e3;
|
||||
box-shadow: inset 0 0 0 1px rgba(32, 74, 112, 0.06);
|
||||
}
|
||||
|
||||
.phase-card.completed {
|
||||
background: #eff8f2;
|
||||
border-color: #c8dfcf;
|
||||
}
|
||||
|
||||
.phase-card.blocked {
|
||||
background: #fff3ef;
|
||||
border-color: #efc7bc;
|
||||
}
|
||||
|
||||
.phase-card.pending {
|
||||
background: #f8fafb;
|
||||
border-color: #dbe4eb;
|
||||
}
|
||||
|
||||
.phase-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.phase-card strong {
|
||||
font-size: 15px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.phase-state {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: var(--muted);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.phase-note {
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.phase-card.running .phase-state {
|
||||
color: var(--navy);
|
||||
}
|
||||
|
||||
.phase-card.completed .phase-state {
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.phase-card.blocked .phase-state {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.knowledge-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.knowledge-card {
|
||||
padding: 16px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--panel-strong);
|
||||
border: 1px solid var(--line);
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.knowledge-card p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
line-height: 1.7;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.knowledge-stat {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
color: var(--navy-strong);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.knowledge-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.upload-zone {
|
||||
border: 1px dashed #a7bacb;
|
||||
background: linear-gradient(180deg, #f9fbfc 0%, #f3f7fa 100%);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.upload-zone strong {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.upload-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.upload-item {
|
||||
padding: 12px 14px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid #dbe4eb;
|
||||
background: #f8fafb;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.upload-item strong {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.upload-item .muted {
|
||||
color: #5f7285;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 14px 16px;
|
||||
border-radius: var(--radius-md);
|
||||
@@ -848,7 +1012,9 @@
|
||||
|
||||
.metric-grid,
|
||||
.task-grid,
|
||||
.copy-grid {
|
||||
.copy-grid,
|
||||
.phase-board,
|
||||
.knowledge-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
@@ -865,7 +1031,9 @@
|
||||
|
||||
.metric-grid,
|
||||
.task-grid,
|
||||
.copy-grid {
|
||||
.copy-grid,
|
||||
.phase-board,
|
||||
.knowledge-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -959,6 +1127,56 @@
|
||||
{ id: "risk", name: "风险预警", status: "已完成", metric: "高风险", detail: "综合结论不通过,建议先整改" },
|
||||
{ id: "word", name: "Word 回填导出", status: "已阻断", metric: "仅草稿可导出", detail: "正式版被高风险与冲突字段拦截" },
|
||||
],
|
||||
taskStatusMap: {
|
||||
pending: "待执行",
|
||||
running: "执行中",
|
||||
completed: "已完成",
|
||||
blocked: "已阻断"
|
||||
},
|
||||
processFlows: {
|
||||
import: [
|
||||
{ key: "upload", title: "资料上传", state: "completed", stateText: "上传完成", note: "18 份文件和 1 个压缩包已建立批次。" },
|
||||
{ key: "parse", title: "文档解析", state: "running", stateText: "解析中", note: "正在提取目录结构、页数与文档元数据。" },
|
||||
{ key: "recognize", title: "章节点识别", state: "pending", stateText: "待执行", note: "待文档解析完成后自动识别 CH 章节节点。" },
|
||||
{ key: "summary", title: "目录汇总", state: "pending", stateText: "待执行", note: "将生成 registration_overview_report 并写入工作台。" }
|
||||
],
|
||||
completeness: [
|
||||
{ key: "load-rules", title: "加载规则包", state: "completed", stateText: "已完成", note: "已装载 NMPA IVD 注册资料规则包。" },
|
||||
{ key: "compare-items", title: "必交项比对", state: "running", stateText: "核查中", note: "对照 CH1 资料要求检查缺失项与错放项。" },
|
||||
{ key: "evidence", title: "法规证据关联", state: "pending", stateText: "待执行", note: "待生成命中法规条款与证据摘要。" },
|
||||
{ key: "risk-tag", title: "完整性风险判定", state: "pending", stateText: "待执行", note: "将输出完整性风险等级和责任角色。" }
|
||||
],
|
||||
fields: [
|
||||
{ key: "ocr", title: "文本准备", state: "completed", stateText: "已完成", note: "OCR / 文本抽取结果已就绪。" },
|
||||
{ key: "extract", title: "字段抽取", state: "running", stateText: "抽取中", note: "按字段 Schema 从说明书与申请表中抽取字段。" },
|
||||
{ key: "pool", title: "字段池写入", state: "pending", stateText: "待执行", note: "将沉淀字段值、来源、置信度与回填标记。" },
|
||||
{ key: "review", title: "待复核标记", state: "pending", stateText: "待执行", note: "对低置信度字段追加人工复核状态。" }
|
||||
],
|
||||
consistency: [
|
||||
{ key: "load-pool", title: "加载字段池", state: "completed", stateText: "已完成", note: "已读取统一字段池和强一致字段定义。" },
|
||||
{ key: "compare", title: "来源对比", state: "running", stateText: "核查中", note: "正在比较说明书、申请表和章节文档取值。" },
|
||||
{ key: "mix-risk", title: "混档风险分析", state: "pending", stateText: "待执行", note: "将输出疑似混档与来源偏差解释。" },
|
||||
{ key: "conflict", title: "冲突结论生成", state: "pending", stateText: "待执行", note: "生成冲突字段列表和建议采用值。" }
|
||||
],
|
||||
risk: [
|
||||
{ key: "collect", title: "风险汇总", state: "completed", stateText: "已完成", note: "已汇总完整性、一致性和待复核结论。" },
|
||||
{ key: "grade", title: "风险评级", state: "running", stateText: "判定中", note: "按高 / 中 / 低规则综合判定当前批次。" },
|
||||
{ key: "rectify", title: "整改建议生成", state: "pending", stateText: "待执行", note: "将结合责任角色输出整改动作。" },
|
||||
{ key: "gate", title: "导出闸门决策", state: "pending", stateText: "待执行", note: "将决定是否允许正式版回填导出。" }
|
||||
],
|
||||
word: [
|
||||
{ key: "mapping", title: "模板映射加载", state: "completed", stateText: "已完成", note: "已读取 Word 模板占位符和字段映射。" },
|
||||
{ key: "fill", title: "字段回填", state: "running", stateText: "回填中", note: "正在把可回填字段写入草稿模板。" },
|
||||
{ key: "block", title: "拦截校验", state: "blocked", stateText: "已阻断", note: "正式版被高风险和冲突字段命中拦截。" },
|
||||
{ key: "download", title: "导出结果生成", state: "pending", stateText: "待执行", note: "仅草稿下载入口会在拦截后继续保留。" }
|
||||
],
|
||||
notification: [
|
||||
{ key: "compose", title: "消息编排", state: "completed", stateText: "已完成", note: "已生成飞书交互卡片内容。" },
|
||||
{ key: "mention", title: "责任人映射", state: "running", stateText: "匹配中", note: "正在匹配章节责任人与风险责任人账号。" },
|
||||
{ key: "link", title: "Web 详情链接", state: "pending", stateText: "待执行", note: "待拼装批次详情跳转链接。" },
|
||||
{ key: "send", title: "发送回执", state: "pending", stateText: "待执行", note: "发送后将写入 message_id 和 sent_at。" }
|
||||
]
|
||||
},
|
||||
importTimeline: [
|
||||
{ step: "创建批次", status: "已完成", detail: "创建 SUB-20260603-001,来源角色为 submission。" },
|
||||
{ step: "文件校验", status: "已完成", detail: "18 份文件通过校验,1 份 DOC 标记待复核。" },
|
||||
@@ -973,6 +1191,28 @@
|
||||
{ path: "第1章 监管信息/CH1.9 产品申报前沟通的说明.doc", type: "DOC", pages: "待复核", confidence: "低", chapter: "CH1.9", name: "沟通说明", status: "待复核", hit: "是" },
|
||||
{ path: "说明书/目标产品说明书.docx", type: "DOCX", pages: "18", confidence: "精确", chapter: "CH3", name: "产品说明书", status: "已汇总", hit: "是" },
|
||||
],
|
||||
knowledgeBase: {
|
||||
summary: [
|
||||
{ label: "知识库资料数", value: "27", note: "法规、模板、示例资料统一管理" },
|
||||
{ label: "待入库任务", value: "3", note: "含 1 个法规包更新和 2 个业务资料" },
|
||||
{ label: "有效切片数", value: "486", note: "支持 RAG 召回与规则辅助解释" },
|
||||
{ label: "启用规则包", value: "4", note: "注册审核与一致性规则均已启用" }
|
||||
],
|
||||
uploadQueue: [
|
||||
{ name: "体外诊断试剂注册申报资料要求及说明_2026修订版.docx", type: "法规资料", owner: "法规管理员", state: "文档解析中", detail: "已上传,正在提取章节标题与法规条款。" },
|
||||
{ name: "说明书模板映射补充包.zip", type: "模板资料", owner: "数据治理专员", state: "解析完成", detail: "已识别 12 个占位符映射,待进入数据处理。" },
|
||||
{ name: "注册申报常见问题汇编.docx", type: "业务知识", owner: "注册经理", state: "数据处理中", detail: "正在生成切片、关键词和召回标签。" },
|
||||
{ name: "临床评价参考示例.pdf", type: "示例资料", owner: "医学专员", state: "处理完成", detail: "已入知识库并开放检索使用。" }
|
||||
],
|
||||
cards: [
|
||||
{ title: "法规规则包", value: "4", desc: "维护完整性检查、一致性判断和风险等级规则。", actions: ["新增规则包", "上传新版", "停用旧版"] },
|
||||
{ title: "RAG 文档源", value: "27", desc: "手动上传法规原文、模板文档、示例资料和内部 SOP。", actions: ["上传文档", "编辑标签", "重新入库"] },
|
||||
{ title: "切片与召回", value: "486", desc: "查看切片状态、命中场景、阈值和是否可召回。", actions: ["新增切片", "拆分切片", "重建向量"] },
|
||||
{ title: "字段 Schema", value: "38", desc: "统一字段标准、是否可回填、强一致约束和来源优先级。", actions: ["新增字段", "编辑字段", "复制版本"] },
|
||||
{ title: "模板与映射", value: "9", desc: "维护 Word 模板、占位符映射和导出阻断约束。", actions: ["上传模板", "编辑映射", "预览模板"] },
|
||||
{ title: "通知与责任人", value: "12", desc: "维护责任角色映射、飞书群聊、机器人和消息模板。", actions: ["新增映射", "发送测试", "查看回执"] }
|
||||
]
|
||||
},
|
||||
completeness: {
|
||||
summary: [
|
||||
{ label: "必交项", value: "8" },
|
||||
@@ -1263,6 +1503,7 @@
|
||||
|
||||
const navConfig = [
|
||||
{ id: "workspace", name: "审核任务工作台", subtitle: "7 个流程任务卡片和执行状态" },
|
||||
{ id: "knowledge", name: "知识库管理页", subtitle: "手动上传资料、入库状态、治理动作" },
|
||||
{ id: "import", name: "资料包导入页", subtitle: "上传、目录、页数、章节点" },
|
||||
{ id: "completeness", name: "法规完整性检查页", subtitle: "缺失项、错放项、法规依据" },
|
||||
{ id: "fields", name: "字段抽取与字段池页", subtitle: "字段表、来源、置信度、待复核" },
|
||||
@@ -1279,6 +1520,7 @@
|
||||
const pageTitle = document.getElementById("pageTitle");
|
||||
const governanceDrawer = document.getElementById("governanceDrawer");
|
||||
const overlay = document.getElementById("overlay");
|
||||
let activePageId = "workspace";
|
||||
|
||||
function metricCards(items) {
|
||||
return `<div class="metric-grid">${items.map(item => `
|
||||
@@ -1373,7 +1615,76 @@
|
||||
`;
|
||||
}
|
||||
|
||||
function renderProcessFlow(flowKey) {
|
||||
const items = data.processFlows[flowKey] || [];
|
||||
return `
|
||||
<div class="phase-board">
|
||||
${items.map(item => `
|
||||
<div class="phase-card ${item.state}">
|
||||
<div class="phase-head">
|
||||
<strong>${item.title}</strong>
|
||||
<span class="phase-state">${item.stateText}</span>
|
||||
</div>
|
||||
<span class="tag ${item.state === "blocked" ? "high" : item.state === "running" ? "medium" : item.state === "completed" ? "low" : ""}">
|
||||
${data.taskStatusMap[item.state] || item.stateText}
|
||||
</span>
|
||||
<div class="phase-note">${item.note}</div>
|
||||
</div>
|
||||
`).join("")}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function buildLiveTasks(currentPageId) {
|
||||
return data.tasks.map(task => {
|
||||
const flow = data.processFlows[task.id];
|
||||
if (!flow) {
|
||||
return task;
|
||||
}
|
||||
|
||||
const blocked = flow.find(item => item.state === "blocked");
|
||||
const running = currentPageId === task.id ? flow.find(item => item.state === "running") : null;
|
||||
const pendingCount = flow.filter(item => item.state === "pending").length;
|
||||
const completedCount = flow.filter(item => item.state === "completed").length;
|
||||
|
||||
if (blocked) {
|
||||
return {
|
||||
...task,
|
||||
status: "已阻断",
|
||||
metric: blocked.stateText,
|
||||
detail: blocked.note
|
||||
};
|
||||
}
|
||||
|
||||
if (running) {
|
||||
return {
|
||||
...task,
|
||||
status: running.stateText,
|
||||
metric: `${completedCount}/${flow.length} 已完成`,
|
||||
detail: running.note
|
||||
};
|
||||
}
|
||||
|
||||
if (pendingCount === 0) {
|
||||
return {
|
||||
...task,
|
||||
status: "已完成",
|
||||
metric: `${flow.length}/${flow.length} 已完成`,
|
||||
detail: task.detail
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...task,
|
||||
status: "待执行",
|
||||
metric: `${completedCount}/${flow.length} 已完成`,
|
||||
detail: task.detail
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function renderWorkspacePage() {
|
||||
const liveTasks = buildLiveTasks(activePageId);
|
||||
return `
|
||||
<section class="page active" data-page="workspace">
|
||||
<div class="hero">
|
||||
@@ -1413,17 +1724,20 @@
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>七个流程任务卡片</h3>
|
||||
<p>点击卡片可以直接切换到对应页面。</p>
|
||||
<p>点击卡片切换流程页面后,状态会实时更新为当前动作。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-grid">
|
||||
${data.tasks.map(task => `
|
||||
<div class="task-card ${task.id === "risk" ? "active" : ""}" data-page-jump="${task.id}">
|
||||
<span class="tag ${task.status === "已阻断" ? "high" : ""}">${task.status}</span>
|
||||
${liveTasks.map(task => `
|
||||
<div class="task-card ${task.id === activePageId ? "active" : ""}" data-page-jump="${task.id}">
|
||||
<div class="task-status-line">
|
||||
<span class="tag ${task.status === "已阻断" ? "high" : task.status.includes("中") ? "medium" : ""}">${task.status}</span>
|
||||
<span class="muted">${task.metric}</span>
|
||||
</div>
|
||||
<h4>${task.name}</h4>
|
||||
<p>${task.detail}</p>
|
||||
<div class="task-note">${task.detail}</div>
|
||||
<div class="task-meta">
|
||||
<span>${task.metric}</span>
|
||||
<span>进入流程</span>
|
||||
<span>查看详情</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1521,6 +1835,98 @@
|
||||
`;
|
||||
}
|
||||
|
||||
function renderKnowledgePage() {
|
||||
return `
|
||||
<section class="page" data-page="knowledge">
|
||||
${metricCards(data.knowledgeBase.summary)}
|
||||
<div class="hero">
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>知识库管理</h3>
|
||||
<p>手动上传法规、模板、示例资料和内部业务知识,统一进入 Agent 可用知识库。</p>
|
||||
</div>
|
||||
<button class="secondary-btn" data-open-governance="sources">打开治理中心</button>
|
||||
</div>
|
||||
<div class="upload-zone">
|
||||
<strong>手动上传知识库资料</strong>
|
||||
<div class="lead">支持批量上传 <code>pdf / docx / doc / zip</code>,并按“法规资料 / 模板资料 / 示例资料 / 内部 SOP”进行分类。</div>
|
||||
<div class="split-actions">
|
||||
<button class="primary-btn">上传法规资料</button>
|
||||
<button class="secondary-btn">上传业务资料</button>
|
||||
<button class="secondary-btn">导入模板压缩包</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>入库处理状态</h3>
|
||||
<p>通过卡片实时展示每份资料的处理动作。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload-list">
|
||||
${data.knowledgeBase.uploadQueue.map(item => `
|
||||
<div class="upload-item">
|
||||
<div>
|
||||
<strong>${item.name}</strong>
|
||||
<div class="muted">${item.type} · 责任人:${item.owner}<br />${item.detail}</div>
|
||||
</div>
|
||||
<span class="tag ${item.state.includes("处理中") || item.state.includes("解析中") ? "medium" : item.state.includes("完成") ? "low" : ""}">${item.state}</span>
|
||||
</div>
|
||||
`).join("")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>知识库能力卡片</h3>
|
||||
<p>原有治理内容收拢为卡片式入口,适合演示 Agent 依赖的知识管理能力。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="knowledge-grid">
|
||||
${data.knowledgeBase.cards.map(card => `
|
||||
<div class="knowledge-card">
|
||||
<div class="muted">${card.title}</div>
|
||||
<div class="knowledge-stat">${card.value}</div>
|
||||
<p>${card.desc}</p>
|
||||
<div class="knowledge-actions">
|
||||
${card.actions.map(action => `<button class="mini-btn">${action}</button>`).join("")}
|
||||
</div>
|
||||
</div>
|
||||
`).join("")}
|
||||
</div>
|
||||
</div>
|
||||
<div class="two-col" style="margin-top: 18px;">
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>入库动作流</h3>
|
||||
<p>模拟上传后的后台流水线动作。</p>
|
||||
</div>
|
||||
</div>
|
||||
${renderProcessFlow("import")}
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>Agent 如何使用知识库</h3>
|
||||
<p>上传并入库后,后续页面会自动引用这些知识进行解释和核查。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="check-list">
|
||||
<div class="check-item">法规资料进入 RAG 文档源,用于完整性检查时的法规依据解释。</div>
|
||||
<div class="check-item">模板资料进入模板映射中心,用于 Word 回填与导出拦截。</div>
|
||||
<div class="check-item">业务示例进入示例知识库,用于字段抽取提示和冲突解释增强。</div>
|
||||
<div class="check-item">责任人和通知配置会驱动飞书通知中的 @ 与 Web 详情链接。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderImportPage() {
|
||||
return `
|
||||
<section class="page" data-page="import">
|
||||
@@ -1553,21 +1959,10 @@
|
||||
<div class="section-title">
|
||||
<div>
|
||||
<h3>处理流水线</h3>
|
||||
<p>展示导入后每个环节的处理状态。</p>
|
||||
<p>进入本流程后,状态卡片会切换到当前执行动作。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline">
|
||||
${data.importTimeline.map((item, idx) => `
|
||||
<div class="timeline-step">
|
||||
<div class="step-no">${idx + 1}</div>
|
||||
<div>
|
||||
<strong>${item.step}</strong>
|
||||
<div class="muted" style="margin-top: 6px;">${item.detail}</div>
|
||||
</div>
|
||||
<span class="tag ${item.status.includes("部分") ? "medium" : ""}">${item.status}</span>
|
||||
</div>
|
||||
`).join("")}
|
||||
</div>
|
||||
${renderProcessFlow("import")}
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="section-title">
|
||||
@@ -2142,6 +2537,7 @@
|
||||
|
||||
const pageTemplates = {
|
||||
workspace: renderWorkspacePage,
|
||||
knowledge: renderKnowledgePage,
|
||||
import: renderImportPage,
|
||||
completeness: renderCompletenessPage,
|
||||
fields: renderFieldsPage,
|
||||
@@ -2206,6 +2602,8 @@
|
||||
}
|
||||
|
||||
function setActivePage(pageId) {
|
||||
activePageId = pageId;
|
||||
renderPages();
|
||||
document.querySelectorAll(".page").forEach(page => {
|
||||
page.classList.toggle("active", page.dataset.page === pageId);
|
||||
});
|
||||
@@ -2275,34 +2673,34 @@
|
||||
panel.classList.toggle("active", panel.dataset.governancePanel === id);
|
||||
});
|
||||
}
|
||||
|
||||
if (event.target.closest("#draftBtn")) {
|
||||
document.getElementById("downloadBox").innerHTML = `
|
||||
<div>
|
||||
<strong>注册申报表格_回填草稿_v2.docx</strong>
|
||||
<div class="muted" style="margin-top: 8px;">状态:草稿已重新生成 · 版式校验:通过 · 时间:2026-06-03 10:42</div>
|
||||
</div>
|
||||
<button class="primary-btn">下载新草稿</button>
|
||||
`;
|
||||
}
|
||||
|
||||
if (event.target.closest("#formalBtn")) {
|
||||
alert("正式导出已被阻断:当前批次存在高风险和冲突字段,请先完成整改。");
|
||||
}
|
||||
|
||||
if (event.target.closest("#sendBtn")) {
|
||||
document.getElementById("receiptBox").className = "alert success";
|
||||
document.getElementById("receiptBox").innerHTML = `
|
||||
已发送至飞书群聊 oc_demo_chat<br />
|
||||
message_id:${data.notification.receipt.id}<br />
|
||||
sent_at:${data.notification.receipt.time}
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("openDrawerBtn").addEventListener("click", () => openGovernance("rules"));
|
||||
document.getElementById("closeDrawerBtn").addEventListener("click", closeGovernance);
|
||||
overlay.addEventListener("click", closeGovernance);
|
||||
|
||||
document.getElementById("draftBtn")?.addEventListener("click", () => {
|
||||
document.getElementById("downloadBox").innerHTML = `
|
||||
<div>
|
||||
<strong>注册申报表格_回填草稿_v2.docx</strong>
|
||||
<div class="muted" style="margin-top: 8px;">状态:草稿已重新生成 · 版式校验:通过 · 时间:2026-06-03 10:42</div>
|
||||
</div>
|
||||
<button class="primary-btn">下载新草稿</button>
|
||||
`;
|
||||
});
|
||||
|
||||
document.getElementById("formalBtn")?.addEventListener("click", () => {
|
||||
alert("正式导出已被阻断:当前批次存在高风险和冲突字段,请先完成整改。");
|
||||
});
|
||||
|
||||
document.getElementById("sendBtn")?.addEventListener("click", () => {
|
||||
document.getElementById("receiptBox").className = "alert success";
|
||||
document.getElementById("receiptBox").innerHTML = `
|
||||
已发送至飞书群聊 oc_demo_chat<br />
|
||||
message_id:${data.notification.receipt.id}<br />
|
||||
sent_at:${data.notification.receipt.time}
|
||||
`;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user