Files
DEMO-AGENT/apps/platform_ui/services.py

530 lines
24 KiB
Python
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.
from django.urls import reverse
from agent_core.governance import load_governance_config
def get_platform_demo_context():
batch = {
"name": "2026Q2-呼吸道多联检测试剂注册批次",
"product_name": "呼吸道病原体核酸联合检测试剂盒PCR-荧光探针法)",
"owner": "临床注册事务组",
"stage": "法规完整性复核中",
"completion": "74%",
"next_action": "补齐 CH1.11.5 沟通记录并确认产品列表版本",
}
metrics = [
{"label": "资料齐套率", "value": "82%", "note": "42 / 51 个目录项已命中"},
{"label": "法规命中率", "value": "89%", "note": "公告附件包 6 类规则已生效"},
{"label": "字段抽取完成度", "value": "67%", "note": "48 个核心字段已进入统一字段池"},
{"label": "高风险问题", "value": "03", "note": "2 个缺失项1 个跨文档冲突"},
]
workflow_overview = [
{"title": "资料进入系统", "detail": "批量上传 18 份申报资料与 6 份法规原文"},
{"title": "规则与知识装载", "detail": "按章-条-要求项-模板字段建立知识底座"},
{"title": "解析与切片", "detail": "页数统计、目录识别、表格抽取、Chroma 入库"},
{"title": "Agent 审核执行", "detail": "完整性检查、字段抽取、一致性核查"},
{"title": "结论输出", "detail": "形成风险清单、证据引用、责任人动作建议"},
]
risk_board = [
{"level": "", "title": "CH1.11.5 沟通记录缺失", "owner": "监管信息专员", "action": "补充 NMPA 沟通留痕"},
{"level": "", "title": "产品名称跨文档表述不一致", "owner": "产品资料负责人", "action": "统一申请表与说明书命名"},
{"level": "", "title": "2 份 Word 页数为估算值", "owner": "文控支持", "action": "补做版式校验"},
]
quick_links = [
{"title": "知识库配置", "url_name": "platform_ui:knowledge-base", "desc": "维护法规规则树与切片策略"},
{"title": "文件中心", "url_name": "documents:list", "desc": "查看上传、解析、切片与异常状态"},
{"title": "审核工作台", "url_name": "chat:index", "url_arg": "document_review", "desc": "发起审核、抽取与一致性核查演示"},
{"title": "工作台大屏", "url_name": "platform_ui:command-center", "desc": "面向演示的 Agent 流程解释大屏"},
]
knowledge_sources = [
{
"code": "KB-001",
"name": "公告附件包 / 资料要求说明",
"type": "法规依据",
"scope": "registration",
"updated_at": "今天 09:20",
"status": "已生效",
"owner": "法规专员",
},
{
"code": "KB-002",
"name": "批准证明文件格式要求",
"type": "模板规则",
"scope": "registration",
"updated_at": "今天 09:35",
"status": "已生效",
"owner": "模板管理员",
},
{
"code": "KB-003",
"name": "安全和性能基本原则清单",
"type": "原则规则",
"scope": "registration",
"updated_at": "今天 10:02",
"status": "待人工校订",
"owner": "法规专员",
},
{
"code": "KB-004",
"name": "CH1 监管信息目录样例",
"type": "业务资料",
"scope": "batch",
"updated_at": "今天 10:30",
"status": "已入库",
"owner": "文控专员",
},
]
rule_tree = [
{
"code": "RULE-001",
"chapter": "CH1 监管信息",
"item": "CH1.2 监管信息目录",
"requirement": "必须提供目录与页码映射",
"field": "目录文件 / 页码可信度",
"status": "启用",
},
{
"code": "RULE-002",
"chapter": "CH1 监管信息",
"item": "CH1.4 申请表",
"requirement": "申请表字段需与说明书一致",
"field": "产品名称 / 规格 / 申请人",
"status": "启用",
},
{
"code": "RULE-003",
"chapter": "CH1 监管信息",
"item": "CH1.11.5 沟通记录",
"requirement": "涉及沟通事项时需补齐记录",
"field": "沟通对象 / 时间 / 结论",
"status": "待校订",
},
{
"code": "RULE-004",
"chapter": "批准证明文件格式",
"item": "注册证输出模板",
"requirement": "字段映射需满足版式模板",
"field": "注册证字段池 / Word 模板",
"status": "启用",
},
]
knowledge_stats = [
{"label": "法规知识源", "value": "06"},
{"label": "结构化规则项", "value": "128"},
{"label": "业务资料切片", "value": "342"},
{"label": "最近人工校订", "value": "2 次"},
]
governance_sections = [
{"title": "法规规则包", "desc": "维护章节规则、要求项与模板字段映射。"},
{"title": "RAG 文档源", "desc": "统一管理法规资料、业务资料和模板来源。"},
{"title": "RAG 切片", "desc": "查看切片摘要、召回状态和证据命中历史。"},
{"title": "字段 Schema", "desc": "维护强一致字段、回填字段和来源优先级。"},
{"title": "责任人映射", "desc": "按章节和风险类型维护飞书责任人实体。"},
{"title": "飞书通知配置", "desc": "固定支持 task_completed / task_failed 两类通知。"},
]
rag_chunks = [
{
"chunk_id": "chunk-001",
"document_name": "资料要求说明",
"chapter": "CH1",
"summary": "CH1.11.5 沟通记录需保留可追溯留痕。",
"status": "已启用",
},
{
"chunk_id": "chunk-002",
"document_name": "批准证明文件格式要求",
"chapter": "CH1",
"summary": "注册证输出模板需满足固定版式字段映射。",
"status": "待重建",
},
]
field_schemas = [
{
"field_code": "product_name",
"field_name": "产品名称",
"field_type": "string",
"fillable": "",
"strict_consistency": "",
"status": "启用",
},
{
"field_code": "storage_condition",
"field_name": "储存条件",
"field_type": "string",
"fillable": "",
"strict_consistency": "",
"status": "待校订",
},
]
governance_config = load_governance_config()
owner_mappings = governance_config["owner_mappings"]
feishu_configs = governance_config["feishu_configs"]
template_mappings = governance_config["template_mappings"]
mcp_connectors = [
{"name": "飞书任务通知", "kind": "协同办公", "auth": "App Token", "status": "已连接", "sync": "5 分钟前"},
{"name": "法规规则源导入", "kind": "法规服务", "auth": "文件轮询", "status": "待验证", "sync": "今天 08:50"},
{"name": "Word 模板服务", "kind": "文档服务", "auth": "API Key", "status": "已连接", "sync": "刚刚"},
{"name": "企业主数据源", "kind": "业务系统", "auth": "MCP Bridge", "status": "未启用", "sync": "未同步"},
]
skills = [
{"name": "完整性检查 Skill", "trigger": "目录齐套性 / 章节点核查", "tools": "规则树 + RAG + 风险映射", "status": "发布中"},
{"name": "字段抽取 Skill", "trigger": "申请表 / 说明书 / 产品列表抽取", "tools": "表格抽取 + 字段池", "status": "已发布"},
{"name": "一致性核查 Skill", "trigger": "跨文档字段冲突检查", "tools": "字段比对 + 解释生成", "status": "灰度测试"},
{"name": "Word 回填 Skill", "trigger": "报送版 Word 输出", "tools": "模板映射 + 导出服务", "status": "待校验"},
]
workflow_steps = [
{"time": "09:32", "title": "载入批次资料", "detail": "识别 18 份业务资料与 6 份法规原文,建立本轮审核上下文。"},
{"time": "09:34", "title": "规则树装载", "detail": "按注册申报主流程装载 CH1 监管信息与批准证明文件格式规则。"},
{"time": "09:36", "title": "字段池初始化", "detail": "从申请表、说明书、产品列表抽取统一字段并建立来源映射。"},
{"time": "09:39", "title": "一致性检查", "detail": "检测到产品名称和样本类型存在跨文档冲突,升级为人工复核。"},
{"time": "09:42", "title": "风险输出", "detail": "生成 3 条风险项、2 条补件建议与 1 条责任人通知任务。"},
]
command_batch = {
"id": "2025IVD-CL-0520-001",
"status": "进行中",
"workflow": "境内第三类",
"class": "III 类",
"created_at": "2025-05-20",
"applicant": "某某生物科技有限公司",
"reviewer": "张审评员",
"role": "审评专家",
"standard": "《体外诊断试剂注册与备案管理办法》及配套技术指导原则",
"version": "V2.12025-04-01",
}
command_metrics = [
{
"key": "completeness",
"label": "资料包完整性得分",
"value": "68",
"suffix": "/100",
"level": "较差",
"detail": "上次得分 612025-05-19",
},
{
"key": "health",
"label": "资料包健康度",
"value": "62",
"suffix": "项检查项",
"segments": [
{"label": "完整", "value": "28", "hint": "45%"},
{"label": "部分缺失", "value": "18", "hint": "29%"},
{"label": "缺失", "value": "16", "hint": "26%"},
],
},
{
"key": "risk",
"label": "风险分布",
"value": "22",
"suffix": "项风险",
"segments": [
{"label": "高风险", "value": "3", "tone": "danger"},
{"label": "中风险", "value": "7", "tone": "warning"},
{"label": "低风险", "value": "12", "tone": "success"},
],
},
{
"key": "progress",
"label": "审核进度",
"value": "46",
"suffix": "%",
"detail": "已完成 24 / 52 项任务",
},
]
command_flow = [
{"step": "1", "title": "资料准备", "date": "2025-05-20", "state": "done"},
{"step": "2", "title": "形式审查", "date": "2025-05-21", "state": "done"},
{"step": "3", "title": "技术审评", "date": "进行中", "state": "active"},
{"step": "4", "title": "核查检验", "date": "待开始", "state": "todo"},
{"step": "5", "title": "综合评审", "date": "待开始", "state": "todo"},
{"step": "6", "title": "行政审批", "date": "待开始", "state": "todo"},
{"step": "7", "title": "制证发证", "date": "待开始", "state": "todo"},
]
command_tabs = [
{"id": "completeness", "label": "注册完整性核查"},
{"id": "consistency", "label": "字段一致性"},
{"id": "risk", "label": "风险准入结论"},
{"id": "evidence", "label": "证据引用"},
{"id": "feishu", "label": "飞书通知状态"},
]
command_checks = [
{
"chapter": "1.产品基本信息",
"item": "产品名称",
"rule": "办法 第十条",
"status": "完整",
"risk": "低风险",
"problem": "-",
},
{
"chapter": "1.产品基本信息",
"item": "预期用途",
"rule": "办法 第十条",
"status": "完整",
"risk": "低风险",
"problem": "-",
},
{
"chapter": "2.综述资料",
"item": "产品描述",
"rule": "指导原则4.2.1",
"status": "完整",
"risk": "低风险",
"problem": "-",
},
{
"chapter": "2.综述资料",
"item": "作用原理",
"rule": "指导原则4.2.2",
"status": "部分缺失",
"risk": "中风险",
"problem": "缺少关键原理图及验证数据说明",
},
{
"chapter": "3.研究资料",
"item": "分析性能评估",
"rule": "指导原则5.3.1",
"status": "部分缺失",
"risk": "中风险",
"problem": "线性范围验证数据不完整",
},
{
"chapter": "3.研究资料",
"item": "阳性判断值",
"rule": "指导原则5.3.2",
"status": "缺失",
"risk": "高风险",
"problem": "未提供阳性判断值确定依据",
},
{
"chapter": "4.临床评价资料",
"item": "临床试验方案",
"rule": "指导原则6.2.1",
"status": "完整",
"risk": "低风险",
"problem": "-",
},
{
"chapter": "4.临床评价资料",
"item": "临床试验报告",
"rule": "指导原则6.2.2",
"status": "部分缺失",
"risk": "中风险",
"problem": "有效性结果分析不完整",
},
{
"chapter": "4.临床评价资料",
"item": "不良事件汇总分析",
"rule": "指导原则6.2.4",
"status": "缺失",
"risk": "高风险",
"problem": "未提供不良事件汇总分析报告",
},
{
"chapter": "5.生产资料",
"item": "生产工艺验证",
"rule": "指导原则7.2.3",
"status": "完整",
"risk": "低风险",
"problem": "-",
},
]
key_risks = [
{"title": "阳性判断值确定依据缺失", "level": "高风险"},
{"title": "不良事件汇总分析报告缺失", "level": "高风险"},
{"title": "临床试验方案偏离未充分说明", "level": "中风险"},
]
next_actions = [
{"title": "退回企业补充资料", "detail": "需企业补充 3 项高风险资料", "state": "待处理", "tone": "danger"},
{"title": "补充说明或澄清", "detail": "需企业说明 7 项中风险问题", "state": "待处理", "tone": "warning"},
{"title": "进入核查检验环节(可选)", "detail": "风险可控后进入下一环节", "state": "待处理", "tone": "success"},
]
owners = [
{"role": "审评专家", "name": "张审评员", "status": "当前处理人"},
{"role": "审核组长", "name": "李组长", "status": "待确认"},
{"role": "法规专员", "name": "王法规", "status": "协同处理"},
{"role": "临床专家", "name": "陈专家", "status": "协同处理"},
]
operation_logs = [
{"time": "2025-05-21 10:24", "actor": "张审评员", "action": "发起完整性核查"},
{"time": "2025-05-21 10:26", "actor": "Agent Core", "action": "命中 62 项检查规则"},
{"time": "2025-05-21 10:28", "actor": "Agent Core", "action": "生成风险准入结论"},
]
knowledge_filters = [
{"label": "全部", "active": True},
{"label": "法规依据", "active": False},
{"label": "模板规则", "active": False},
{"label": "业务资料", "active": False},
]
knowledge_form = {
"title": "新增 / 编辑知识源",
"fields": [
{"label": "知识源名称", "value": "体外诊断试剂注册申报资料要求及说明"},
{"label": "知识源类型", "value": "法规依据"},
{"label": "适用流程", "value": "registration"},
{"label": "状态", "value": "已生效"},
{"label": "切片策略", "value": "按章条切片,保留条款编号"},
],
}
rule_form = {
"title": "新增 / 编辑规则项",
"fields": [
{"label": "规则编码", "value": "RULE-005"},
{"label": "所属章节", "value": "CH1 监管信息"},
{"label": "规则名称", "value": "申请表签章完整性检查"},
{"label": "模板字段", "value": "签章页 / 申请人签字"},
{"label": "规则说明", "value": "若申请表缺少签章,则标记为高优先级缺失项"},
],
}
return {
"batch": batch,
"metrics": metrics,
"workflow_overview": workflow_overview,
"risk_board": risk_board,
"quick_links": quick_links,
"knowledge_sources": knowledge_sources,
"rule_tree": rule_tree,
"knowledge_stats": knowledge_stats,
"governance_sections": governance_sections,
"rag_chunks": rag_chunks,
"field_schemas": field_schemas,
"owner_mappings": owner_mappings,
"feishu_configs": feishu_configs,
"template_mappings": template_mappings,
"knowledge_filters": knowledge_filters,
"knowledge_form": knowledge_form,
"rule_form": rule_form,
"mcp_connectors": mcp_connectors,
"skills": skills,
"workflow_steps": workflow_steps,
"command_batch": command_batch,
"command_metrics": command_metrics,
"command_flow": command_flow,
"command_tabs": command_tabs,
"command_checks": command_checks,
"key_risks": key_risks,
"next_actions": next_actions,
"owners": owners,
"operation_logs": operation_logs,
}
def build_knowledge_base_context(selected_view: str) -> dict:
"""
组装知识库治理台上下文。
页面层只负责展示,治理对象导航、当前对象说明和 CRUD 入口统一由服务层提供。
"""
context = get_platform_demo_context()
governance_objects = _build_governance_objects()
active_object = next(
(item for item in governance_objects if item["key"] == selected_view),
governance_objects[0],
)
context.update(
{
"governance_objects": governance_objects,
"active_governance_object": active_object,
"governance_action_hub": _build_governance_action_hub(active_object, context),
}
)
return context
def _build_governance_objects() -> list[dict]:
return [
{
"key": "rule_packages",
"title": "法规规则包",
"summary": "按章-条-要求项-模板字段维护规则包版本和启停状态。",
"detail_title": "法规规则包详情",
"detail_copy": "支持新增、编辑、复制新版本、启停和查看章节要求详情。",
"actions": ["新增规则包", "编辑规则包", "复制新版本", "启用 / 停用", "查看章节要求详情"],
"admin_url": reverse("admin:index"),
},
{
"key": "knowledge_sources",
"title": "RAG 文档源",
"summary": "维护法规资料、模板资料和业务资料的入库版本。",
"detail_title": "RAG 文档源详情",
"detail_copy": "支持上传新文档源、替换版本、编辑元数据、停用和重新入库。",
"actions": ["上传新文档源", "替换版本", "编辑元数据", "停用文档源", "重新入库"],
"admin_url": reverse("admin:index"),
},
{
"key": "rag_chunks",
"title": "RAG 切片",
"summary": "查看切片摘要、章节、召回状态和证据命中历史。",
"detail_title": "RAG 切片详情",
"detail_copy": "支持手工切片、摘要编辑、合并拆分、删除和重建向量。",
"actions": ["新增手工切片", "编辑切片摘要", "合并切片", "拆分切片", "重建向量"],
"admin_url": reverse("admin:index"),
},
{
"key": "field_schemas",
"title": "字段 Schema",
"summary": "维护回填字段、强一致字段和来源优先级。",
"detail_title": "字段 Schema 详情",
"detail_copy": "支持新增字段、编辑字段、版本复制和启停管理。",
"actions": ["新增字段", "编辑字段", "启停字段", "复制 schema 版本", "查看来源优先级"],
"admin_url": reverse("admin:index"),
},
{
"key": "template_mappings",
"title": "Word 模板与字段映射",
"summary": "管理输出模板版本、占位符映射和阻断条件影响范围。",
"detail_title": "Word 模板与字段映射详情",
"detail_copy": "支持上传模板、编辑占位符映射、启停版本和模板预览。",
"actions": ["上传模板", "编辑模板元数据", "编辑占位符映射", "启用 / 停用版本", "预览模板"],
"admin_url": reverse("admin:platform_ui_wordtemplatemapping_changelist"),
},
{
"key": "owner_mappings",
"title": "责任人映射",
"summary": "按章节和风险类型维护责任角色、责任人和飞书标识。",
"detail_title": "责任人映射详情",
"detail_copy": "支持新增、编辑、启停、删除以及批量导入责任人映射。",
"actions": ["新增映射", "编辑映射", "启停映射", "删除映射", "批量导入映射"],
"admin_url": reverse("admin:platform_ui_ownermapping_changelist"),
},
{
"key": "feishu_configs",
"title": "飞书通知配置",
"summary": "固定支持 task_completed / task_failed 两类通知并维护消息模板。",
"detail_title": "飞书通知配置详情",
"detail_copy": "支持新增配置、编辑消息模板、启停配置和发送测试消息。",
"actions": ["新增配置", "编辑配置", "切换消息模板", "启用 / 停用", "发送测试消息"],
"admin_url": reverse("admin:platform_ui_feishunotifyconfig_changelist"),
},
]
def _build_governance_action_hub(active_object: dict, context: dict) -> dict:
"""
为治理台提供当前对象聚焦信息与跨入口动作。
目标是把知识库从“静态配置展示页”收口为“治理入口”:
- 明确当前治理对象
- 提供固定通知策略口径
- 提供跳转到审核智能体 / 资料包 / 处理历史的快速入口
"""
owner_count = len(context.get("owner_mappings") or [])
template_count = len(context.get("template_mappings") or [])
feishu_count = len(context.get("feishu_configs") or [])
return {
"title": "治理动作总览",
"current_object": active_object["title"],
"current_summary": active_object["summary"],
"status_items": [
{"label": "责任人映射", "value": f"{owner_count}"},
{"label": "Word 模板版本", "value": f"{template_count}"},
{"label": "通知配置", "value": f"{feishu_count}"},
],
"quick_actions": [
{"label": "进入审核智能体", "url": reverse("chat:index")},
{"label": "查看资料包", "url": reverse("documents:list")},
{"label": "查看处理历史", "url": reverse("audit:list")},
{"label": "进入后台维护", "url": active_object["admin_url"]},
],
"notify_reasons": ["task_completed", "task_failed"],
}