#!/usr/bin/env python3 """ 根据 anyuan_docs_maker 的 Dataset001Parser 真实逻辑, 为 lingyue project 10 创建准确的规则映射。 """ import requests, json BASE = "http://47.108.80.98:8001" PROJECT_ID = 10 # ── 1. 登录 ───────────────────────────────────────────────── r = requests.post(f"{BASE}/api/v1/auth/login", json={"username": "admin", "password": "admin123"}) TOKEN = r.json()["data"]["accessToken"] HDR = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"} # ── 2. lingyue 附件 ID 映射 ────────────────────────────────── # anyuan 附件编号 → lingyue attachment id + 名称 ATT = { "001001": (400, "核心要素评审情况记录表"), "001002": (401, "现场评审分工表"), "001003": (402, "安全生产标准化复审实施方案"), "001004": (403, "材料真实性说明"), "001005": (404, "在建项目一览表"), "001006": (405, "安全管理制度清单"), "001007": (406, "现场评审末次会签到表"), "001008": (407, "工作方案"), "001010": (408, "复审问题建议表"), } def inp(code): """构建 inputs 数组""" aid, name = ATT[code] return [{"sourceNodeId": str(aid), "inputKey": "attachment", "inputType": "ATTACHMENT", "inputName": name}] def inps(*codes): """多来源""" result = [] for c in codes: aid, name = ATT[c] result.append({"sourceNodeId": str(aid), "inputKey": "attachment", "inputType": "ATTACHMENT", "inputName": name}) return result # ── 3. 规则定义(按 Dataset001Parser 解析阶段) ──────────────── # 格式: (elementKey, ruleName, actionType, dslContent/描述, 来源附件编号列表) RULES = [ # ═══════════════════════════════════════════════ # 阶段2: 工作方案 (001008) → 评审对象、简称、日期、人员等 # ═══════════════════════════════════════════════ ("project.reviewObject", "评审对象全称", "summary", "从工作方案PDF中通过AI提取评审对象全称。解析工作方案的每个PDF文件,从中识别被评审企业的完整名称。", ["001008"]), ("project.reviewObjectAlias", "评审对象简称", "summary", "从工作方案PDF中通过AI提取评审对象简称。例如「中国电建集团成都勘测设计研究院有限公司」简称「成都院」。", ["001008"]), ("project.workStartAt", "评审开始日期", "quote", "从工作方案PDF中直接提取评审工作开始日期。格式为:yyyy年M月d日。多个工作方案时取最早的开始日期。", ["001008"]), ("project.workEndAt", "评审结束日期", "quote", "从工作方案PDF中直接提取评审工作结束日期。格式为:yyyy年M月d日。多个工作方案时取最晚的结束日期。", ["001008"]), ("project.reviewRange", "复审范围", "summary", "从工作方案PDF中提取所有复审项目(单位和在建项目),按类型排序后拼接。格式如:成都院本部、大邑地勘项目(简称:大邑项目)。", ["001008"]), ("project.workProcess", "复审工作过程", "summary", "根据工作方案中提取的评审开始/结束日期、评审对象简称、复审项目列表,按固定模板生成复审工作过程描述。包含评审组工作会议、现场评审、具体评审时间表等内容。", ["001008"]), ("+SPSRRReviewProject", "现场复审项目", "table_extract", "从工作方案PDF中提取复审项目列表,包含项目名称、简称、类型(单位/在建项目)、排序等信息。", ["001008"]), ("+SPSRRReviewer", "现场复审人员", "table_extract", "从工作方案PDF中提取评审人员列表,包含姓名、专业分工等。多个工作方案中的同名人员会合并专业。", ["001008"]), # ═══════════════════════════════════════════════ # 阶段4: 核心要素评审记录表 (001001) → 各核心要素得分与评审意见 # ═══════════════════════════════════════════════ ("project.resultScore", "评审得分", "table_extract", "从核心要素评审情况记录表(docx)中提取各评审项的标准分和实得分,汇总计算总评审得分。公式:总实得分/总标准分×100。", ["001001"]), ("project.resultLevel", "评审结论级别", "table_extract", "根据评审得分自动判定。≥90分为一级,≥80分为二级。", ["001001"]), ("project.target", "目标", "summary", "从核心要素评审记录表中提取评审代码5.1.1.1~5.1.1.3的评审意见(remark),经AI总结生成目标描述。", ["001001"]), ("project.duty", "职责", "summary", "从核心要素评审记录表中提取评审代码5.1.2.1的评审意见(remark),经AI总结生成职责描述。", ["001001"]), ("project.fullParticipation", "全员参与", "summary", "从核心要素评审记录表中提取评审代码5.1.3的评审意见(remark),经AI总结生成全员参与描述。", ["001001"]), ("project.safetyInvestment", "安全投入", "summary", "从核心要素评审记录表中提取评审代码5.1.4的评审意见(remark),经AI总结生成安全投入描述。", ["001001"]), ("project.safetyCulture", "安全文化", "summary", "从核心要素评审记录表中提取评审代码5.1.5的评审意见(remark),经AI总结生成安全文化描述。", ["001001"]), ("project.systematicManagement", "体系化管理", "summary", "从核心要素评审记录表中提取评审代码5.2.*的评审意见(remark),经AI总结生成体系化管理描述。", ["001001"]), ("project.employeeTraining", "人员教育培训", "summary", "从核心要素评审记录表中提取评审代码5.3.2.*的评审意见(remark),经AI总结生成人员教育培训描述。", ["001001"]), ("project.assetManagement", "设备设施管理", "summary", "从核心要素评审记录表中提取评审代码5.4.1.*的评审意见(remark),经AI总结生成设备设施管理描述。", ["001001"]), ("project.jobSafety", "作业安全", "summary", "从核心要素评审记录表中提取评审代码5.4.2.1的评审意见(remark),经AI总结生成作业安全描述。", ["001001"]), ("project.positionQualified", "岗位达标", "summary", "从核心要素评审记录表中提取评审代码5.4.2.3的评审意见(remark),经AI总结生成岗位达标描述。", ["001001"]), ("project.partner", "相关方", "summary", "从核心要素评审记录表中提取评审代码5.4.2.4的评审意见(remark),经AI总结生成相关方管理描述。", ["001001"]), ("project.occupationalHealth", "职业健康", "summary", "从核心要素评审记录表中提取评审代码5.4.3.1的评审意见(remark),经AI总结生成职业健康描述。", ["001001"]), ("project.riskAssessment", "风险辨识与评价", "summary", "从核心要素评审记录表中提取评审代码5.5.1.1和5.5.1.2的评审意见(remark),经AI总结生成风险辨识与评价描述。", ["001001"]), ("project.majorHazardManagement", "重大危险源管理", "summary", "从核心要素评审记录表中提取评审代码5.5.2.1的评审意见(remark),经AI总结生成重大危险源管理描述。", ["001001"]), ("project.hazardInspection", "隐患排查", "summary", "从核心要素评审记录表中提取评审代码5.5.3.1的评审意见(remark),经AI总结生成隐患排查描述。", ["001001"]), ("project.changeManagement", "变更管理", "summary", "从核心要素评审记录表中提取评审代码5.5.1.4的评审意见(remark),经AI总结生成变更管理描述。", ["001001"]), ("project.earlyWarning", "预测预警", "summary", "从核心要素评审记录表中提取评审代码5.5.4的评审意见(remark),经AI总结生成预测预警描述。", ["001001"]), ("project.emergencyResponse", "应急救援", "summary", "从核心要素评审记录表中提取评审代码5.6.1.1的评审意见(remark),经AI总结生成应急救援描述。", ["001001"]), ("project.incidentManagement", "事故管理", "summary", "从核心要素评审记录表中提取评审代码5.7.1的评审意见(remark),经AI总结生成事故管理描述。", ["001001"]), ("project.continuousImprovement", "持续改进", "summary", "从核心要素评审记录表中提取评审代码5.8.2.*的评审意见(remark),经AI总结生成持续改进描述。", ["001001"]), ("project.safetyStandardizationStatus", "标准化建设运行情况", "summary", "从核心要素评审记录表中提取评审代码5.8.1.*和5.8.2.*的评审意见(remark),经AI总结生成标准化建设运行情况描述。", ["001001"]), ("project.safetyHighlight", "安全生产管理亮点", "summary", "综合核心要素评审记录表中目标职责(5.1)各子项的评审意见,经AI提炼安全生产管理亮点。", ["001001"]), ("+target_responsibility", "目标职责详情", "table_extract", "从核心要素评审记录表中筛选评审代码为5.1.*的所有检查项,按模板渲染目标职责章节详情。包含各子项的评审标准、标准分、实得分、存在问题及扣分情况。", ["001001"]), ("+institutionalized_management", "制度化管理详情", "table_extract", "从核心要素评审记录表中筛选评审代码为5.2.*的所有检查项,按模板渲染制度化管理章节详情。", ["001001"]), ("+review_status", "现场复审情况", "table_extract", "从核心要素评审记录表中汇总所有8个核心要素的评审结果,渲染现场复审情况总览表。", ["001001"]), ("+review_result", "复审结果", "table_extract", "根据核心要素评审记录表的评分汇总,按8个核心要素计算实际评审项数、标准分、实得分、扣分项数等,生成复审结果表。", ["001001"]), ("+site_reaudit_score_analysis", "现场复审得分分析", "table_extract", "根据核心要素评审记录表的评分结果,计算各核心要素的得分率(实得分/标准分×100),生成得分分析表和分析文字描述。", ["001001"]), # ═══════════════════════════════════════════════ # 阶段6: 复审问题建议表 (001010) → 整改建议 # ═══════════════════════════════════════════════ ("+SPSRRSuggestion", "现场复审发现的问题及整改", "table_extract", "主体数据从核心要素评审记录表(001001)中提取有扣分的检查项(问题描述),整改建议从复审问题建议表(001010)中按评审代码匹配补充。", ["001001", "001010"]), # ═══════════════════════════════════════════════ # 阶段7: 安全生产标准化复审实施方案 (001003) → 自评过程、工作依据 # ═══════════════════════════════════════════════ ("project.reviewObjectSelfAssessmentProcess", "自评过程", "summary", "从安全生产标准化复审实施方案(PDF)中OCR提取全文,通过AI按参考模板总结自评过程内容。包含前期策划、专题培训、自查自纠、内审整改、报告撰写、持续改进6个阶段。", ["001003"]), ("project.moreWorkReference", "其他工作依据", "quote", "从安全生产标准化复审实施方案(PDF)中OCR提取文件编号和文件名称。格式如:《xxx管理办法》(蓉设安质〔2024〕20号)。", ["001003"]), # ═══════════════════════════════════════════════ # 用户输入字段(来源为用户手工填写的元数据,不依赖附件) # ═══════════════════════════════════════════════ ("basicInfo.projectCode", "项目编号", "use_entity_value", "用户手工输入的项目编号,如 PRJ-2024-001。", []), ("basicInfo.requestLevel", "申请级别", "use_entity_value", "用户手工输入的申请标准化复审级别,如「一级」。", []), ("basicInfo.applyAt", "复审申请日期", "use_entity_value", "用户手工输入的复审申请日期。格式为:yyyy年M月d日。", []), ("basicInfo.reviewObjectCertificateGetAt", "获证日期", "use_entity_value", "用户手工输入的电力安全生产标准化企业证书获取日期。格式为:yyyy年M月d日。", []), ("basicInfo.reviewObjectCertificateCode", "证书编号", "use_entity_value", "用户手工输入的电力安全生产标准化企业证书编号。", []), ("basicInfo.reviewObjectCertificate2GetAt", "通过评审日期", "use_entity_value", "用户手工输入的国家能源局安全生产标准化达标证书获取日期。", []), # ═══════════════════════════════════════════════ # 渲染阶段:附件直接嵌入(附件1~7的原始内容嵌入到报告附录) # ═══════════════════════════════════════════════ # 这些不需要创建规则,因为是直接将附件内容渲染到报告末尾 ] # ── 4. 批量创建 ────────────────────────────────────────────── print(f"共 {len(RULES)} 条规则待创建:\n") ok, fail = 0, 0 for elem_key, rule_name, action_type, dsl, att_codes in RULES: inputs = [] for c in att_codes: aid, name = ATT[c] inputs.append({"sourceNodeId": str(aid), "inputKey": "attachment", "inputType": "ATTACHMENT", "inputName": name}) payload = { "elementKey": elem_key, "ruleName": rule_name, "ruleType": "auto", "actionType": action_type, "actionConfig": json.dumps({"description": dsl[:200]}, ensure_ascii=False), "dslContent": dsl, "description": f"来源:{', '.join(ATT[c][1] for c in att_codes) if att_codes else '用户输入'}", "inputs": inputs, } resp = requests.post(f"{BASE}/api/v1/projects/{PROJECT_ID}/rules", headers=HDR, json=payload) if resp.status_code == 200 and resp.json().get("code") == 200: rid = resp.json()["data"].get("id", "?") print(f" ✅ [{rid:>5}] {action_type:18s} {elem_key:50s} ← {', '.join(ATT[c][1] for c in att_codes) if att_codes else '用户输入'}") ok += 1 else: print(f" ❌ {elem_key:50s} → {resp.status_code} {resp.text[:120]}") fail += 1 print(f"\n完成:成功 {ok},失败 {fail}")