# 数据提取规则系统设计文档 > 版本: 2.0.0 > 日期: 2026-01-23 > 作者: AI Assistant (Claude Opus 4.5) ## 一、概述 ### 1.1 背景 在电力工程预评价报告生成场景中,用户需要从多个来源文档(PDF、Word、Excel)中提取特定数据,生成标准化的报告。 **核心痛点**: - 不同工程项目的报告结构相似,但数据不同 - 人工从多个文档中复制粘贴数据,效率低、易出错 - 相同类型的报告需要重复劳动 **解决方案**: 用户上传一份**已完成的真实报告**作为示例,在报告中标记**变量**(如工程名称、批复日期等),并配置每个变量的**数据来源**。之后遇到同类项目,只需替换来源文件,系统自动提取数据生成新报告。 ### 1.2 核心概念 | 概念 | 说明 | | ---- | ---- | | **模板(Template)** | 基于真实报告创建,包含变量定义和来源文件配置 | | **来源文件定义(SourceFile)** | 模板需要的来源文件类型,用别名标识(如"可研批复") | | **变量(Variable)** | 报告中需要动态替换的内容,绑定到文档中的具体位置 | | **生成任务(Generation)** | 使用模板生成新报告的一次任务 | ### 1.3 设计原则 1. **示例驱动**:基于真实报告创建模板,所见即所得 2. **数据溯源**:每个提取值都能追溯到来源文档的具体位置 3. **灵活来源**:来源文件数量和类型由用户自定义 4. **一次配置,多次复用**:模板创建后可用于生成任意多份新报告 --- ## 二、用户使用流程 ### 2.1 流程概览 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 第一次:创建模板 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. 上传示例报告(一份真实的、完整的报告) │ │ "襄阳连云110kV预评价报告.docx" │ │ │ │ 2. 添加来源文件(自定义数量和别名) │ │ ├── 可研批复.pdf 别名:"可研批复" │ │ ├── 站址报告.docx 别名:"站址报告" │ │ └── 概算表.xlsx 别名:"概算表" │ │ │ │ 3. 在示例报告中标记变量 │ │ 选中文本 "襄阳连云 110kV 输变电工程" │ │ → 设为变量 "project_name" │ │ → 来源:从【可研批复】第1页 AI提取 │ │ │ │ 4. 保存模板 │ │ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第二次起:使用模板生成新报告 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. 选择模板 │ │ │ │ 2. 上传新项目的来源文件(按别名对应) │ │ ├── 武汉东湖批复.pdf → "可研批复" │ │ ├── 武汉站址报告.docx → "站址报告" │ │ └── 武汉概算.xlsx → "概算表" │ │ │ │ 3. 点击【生成】 │ │ 系统自动: │ │ - 从新文件提取数据 │ │ - 替换模板中的变量 │ │ - 生成新报告 │ │ │ │ 4. 预览、确认、下载 │ │ "武汉东湖110kV预评价报告.docx" │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 2.2 变量标记交互 用户在文档编辑器中操作: ``` ┌─────────────────────────────────────────────────────────────────┐ │ 📄 示例报告编辑器 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 一、项目概述 │ │ │ │ 1.1 工程名称:襄阳连云 110kV 输变电工程 │ │ ═══════════════════════════ ← 用户选中这段文字 │ │ │ │ │ ▼ 右键菜单 │ │ ┌────────────────────────────────────┐ │ │ │ 📌 设为变量 │ │ │ │ │ │ │ │ 变量名:project_name │ │ │ │ 显示名:工程名称 │ │ │ │ │ │ │ │ 当前值:襄阳连云 110kV 输变电工程 │ │ │ │ │ │ │ │ 数据来源: │ │ │ │ ● 从来源文件提取 │ │ │ │ ├─ 来源文件:[可研批复 ▼] │ │ │ │ ├─ 定位方式:[按页码 ▼] │ │ │ │ ├─ 页码范围:1-2 │ │ │ │ └─ 提取方式:[AI提取 ▼] │ │ │ │ └─ 提取目标:工程项目名称 │ │ │ │ │ │ │ │ ○ 手动输入 │ │ │ │ ○ 引用其他变量 │ │ │ │ ○ 固定值(不变) │ │ │ │ │ │ │ │ [取消] [确定] │ │ │ └────────────────────────────────────┘ │ │ │ │ 1.2 建设单位:【$construction_unit】← 已标记的变量高亮显示 │ │ │ │ 1.3 批复日期:【$approval_date】 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 三、系统架构 ### 3.1 整体架构图 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 前端 (Vue.js / Flutter) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 模板管理 │ │ 文档编辑器 │ │ 变量配置 │ │ 报告生成 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ API Gateway │ └─────────────────────────────────────────────────────────────────────────────┘ │ ┌────────────────────────────┼────────────────────────────┐ ▼ ▼ ▼ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ │ template-service │ │ document-service │ │ ai-service │ │ (模板与生成) │ │ (文档管理) │ │ (AI提取) │ │ ┌────────────────┐ │ │ ┌────────────────┐ │ │ ┌────────────────┐ │ │ │ TemplateService│ │ │ │ DocumentService│ │ │ │ DeepSeekClient │ │ │ │ VariableService│ │ │ │ ElementService │ │ │ │ AIExtractService│ │ │ │ GenerationSvc │ │ │ └────────────────┘ │ │ └────────────────┘ │ │ └────────────────┘ │ └──────────────────────┘ └──────────────────────┘ └──────────────────────┘ │ │ │ └────────────────────────────┴────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ PostgreSQL + Redis │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 3.2 模块职责 | 模块 | 职责 | 位置 | | ---- | ---- | ---- | | **template-service** | 模板管理、变量配置、报告生成(重构 extract-service) | `backend/extract-service` | | **document-service** | 文档管理、元素存储(已有) | `backend/document-service` | | **parse-service** | 文档解析、结构化提取(已有) | `backend/parse-service` | | **ai-service** | AI 提取、总结(已有) | `backend/ai-service` | --- ## 四、数据库设计 ### 4.1 ER 图 ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ templates │ │ source_files │ │ variables │ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ id │◄──────│ template_id │ │ id │ │ user_id │ │ id │ │ template_id │──────►│ │ name │ │ alias │◄──────│ source_file_alias│ │ │ description │ │ description │ │ name │ │ │ base_document_id│ │ file_types │ │ display_name │ │ │ status │ │ required │ │ location │ │ │ config │ │ example_doc_id │ │ example_value │ │ │ created_at │ │ display_order │ │ source_type │ │ │ updated_at │ └─────────────────┘ │ source_config │ │ └─────────────────┘ │ extract_type │ │ │ │ extract_config │ │ │ ┌─────────────────┐ │ display_order │ │ │ │ generations │ └─────────────────┘ │ │ ├─────────────────┤ │ └──────►│ template_id │ │ │ id │◄─────────────────────────────────────────┘ │ user_id │ (通过 template_id 关联) │ name │ │ source_file_map │ ← JSONB: {"可研批复": "doc_123", ...} │ variable_values │ ← JSONB: {"project_name": {...}, ...} │ output_doc_id │ │ status │ │ created_at │ │ completed_at │ └─────────────────┘ ``` ### 4.2 表结构定义 #### 4.2.1 templates(模板表) ```sql CREATE TABLE templates ( id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) NOT NULL, name VARCHAR(255) NOT NULL COMMENT '模板名称', description TEXT COMMENT '模板描述', base_document_id VARCHAR(36) NOT NULL COMMENT '示例报告文档ID', status VARCHAR(32) DEFAULT 'draft' COMMENT '状态: draft/published/archived', config JSONB COMMENT '模板配置', is_public BOOLEAN DEFAULT FALSE COMMENT '是否公开', use_count INT DEFAULT 0 COMMENT '使用次数', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, create_by VARCHAR(36), update_by VARCHAR(36) ); CREATE INDEX idx_templates_user_id ON templates(user_id); CREATE INDEX idx_templates_status ON templates(status); COMMENT ON TABLE templates IS '报告模板'; ``` #### 4.2.2 source_files(来源文件定义表) ```sql CREATE TABLE source_files ( id VARCHAR(36) PRIMARY KEY, template_id VARCHAR(36) NOT NULL REFERENCES templates(id) ON DELETE CASCADE, alias VARCHAR(100) NOT NULL COMMENT '文件别名,如"可研批复"', description TEXT COMMENT '文件说明', file_types JSONB COMMENT '允许的文件类型: ["pdf", "docx"]', required BOOLEAN DEFAULT TRUE COMMENT '是否必须', example_document_id VARCHAR(36) COMMENT '创建模板时使用的示例文件', display_order INT DEFAULT 0 COMMENT '显示顺序', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE (template_id, alias) ); CREATE INDEX idx_source_files_template ON source_files(template_id); COMMENT ON TABLE source_files IS '来源文件定义'; ``` #### 4.2.3 variables(变量表) ```sql CREATE TABLE variables ( id VARCHAR(36) PRIMARY KEY, template_id VARCHAR(36) NOT NULL REFERENCES templates(id) ON DELETE CASCADE, -- 变量标识 name VARCHAR(100) NOT NULL COMMENT '变量名(程序用)', display_name VARCHAR(200) NOT NULL COMMENT '显示名称', variable_group VARCHAR(100) COMMENT '变量分组', -- 在示例报告中的位置 location JSONB NOT NULL COMMENT '文档中的位置', -- location 结构: -- { -- "element_id": "elem_001", -- "type": "text" | "table_cell" | "paragraph", -- "start_offset": 10, -- "end_offset": 35, -- "row_index": 2, -- 表格行 -- "col_index": 1 -- 表格列 -- } -- 示例值(原文档中的值) example_value TEXT COMMENT '示例值', value_type VARCHAR(32) DEFAULT 'text' COMMENT '值类型: text/date/number/table', -- 数据来源 source_file_alias VARCHAR(100) COMMENT '来源文件别名', source_type VARCHAR(32) NOT NULL COMMENT '来源类型: document/manual/reference/fixed', source_config JSONB COMMENT '来源配置', -- source_config 示例(document类型): -- { -- "location": { -- "type": "page", -- "pageStart": 1, -- "pageEnd": 2 -- } -- } -- 提取方式 extract_type VARCHAR(32) COMMENT '提取类型: direct/ai_extract/ai_summarize', extract_config JSONB COMMENT '提取配置', -- extract_config 示例(ai_extract类型): -- { -- "targetDescription": "提取工程名称", -- "fieldType": "text", -- "expectedFormat": "XX市XX工程" -- } display_order INT DEFAULT 0 COMMENT '显示顺序', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE (template_id, name) ); CREATE INDEX idx_variables_template ON variables(template_id); COMMENT ON TABLE variables IS '模板变量'; ``` #### 4.2.4 generations(生成任务表) ```sql CREATE TABLE generations ( id VARCHAR(36) PRIMARY KEY, template_id VARCHAR(36) NOT NULL REFERENCES templates(id), user_id VARCHAR(36) NOT NULL, name VARCHAR(255) COMMENT '任务名称', -- 来源文件映射:别名 → 文档ID source_file_map JSONB NOT NULL COMMENT '来源文件映射', -- 示例:{"可研批复": "doc_123", "站址报告": "doc_456"} -- 变量提取结果 variable_values JSONB COMMENT '变量值', -- 示例: -- { -- "project_name": { -- "value": "武汉东湖 110kV 输变电工程", -- "confidence": 0.96, -- "source_preview": "...", -- "status": "extracted" -- } -- } -- 生成的文档 output_document_id VARCHAR(36) COMMENT '输出文档ID', status VARCHAR(32) DEFAULT 'pending' COMMENT '状态: pending/extracting/review/completed/error', error_message TEXT COMMENT '错误信息', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, completed_at TIMESTAMP COMMENT '完成时间' ); CREATE INDEX idx_generations_template ON generations(template_id); CREATE INDEX idx_generations_user ON generations(user_id); CREATE INDEX idx_generations_status ON generations(status); COMMENT ON TABLE generations IS '报告生成任务'; ``` --- ## 五、变量来源类型 ### 5.1 来源类型总览 | 来源类型 | 说明 | 适用场景 | | -------- | ---- | -------- | | `document` | 从来源文件提取 | 工程名称、批复日期等需要从文档中获取的信息 | | `manual` | 手动输入 | 联系人、特殊备注等无法自动获取的信息 | | `reference` | 引用其他变量 | 组合已提取的值,如"《{project_name}可行性研究报告》" | | `fixed` | 固定值 | 不随项目变化的固定文本 | ### 5.2 document 类型配置 ```json { "source_file_alias": "可研批复", "source_type": "document", "source_config": { "location": { "type": "page", // page | chapter | element "pageStart": 1, "pageEnd": 2, "paragraphKeyword": null // 可选:段落关键词过滤 } }, "extract_type": "ai_extract", "extract_config": { "targetDescription": "从批复文件中提取工程项目的完整名称", "fieldType": "text", "expectedFormat": "XX市XX工程", "examples": ["襄阳连云220千伏输变电工程"] } } ``` ### 5.3 manual 类型配置 ```json { "source_type": "manual", "source_config": { "placeholder": "请输入项目联系人姓名", "required": true, "defaultValue": "", "inputType": "text", // text | textarea | date | number "validation": { "maxLength": 50, "pattern": "^[\\u4e00-\\u9fa5]{2,10}$" } } } ``` ### 5.4 reference 类型配置 ```json { "source_type": "reference", "source_config": { "referenceVariables": ["project_name", "design_unit", "report_date"], "combineTemplate": "《{project_name}可行性研究报告》由{design_unit}于{report_date}编制", "transform": { "type": "format", "formatPattern": "{0}" } } } ``` ### 5.5 fixed 类型配置 ```json { "source_type": "fixed", "source_config": { "fixedValue": "本报告依据《电力建设工程预算编制办法》(2018版)编制。" } } ``` --- ## 六、提取类型 ### 6.1 提取类型总览 | 提取类型 | 说明 | 适用场景 | | -------- | ---- | -------- | | `direct` | 直接提取 | 定位到的内容直接使用 | | `ai_extract` | AI字段提取 | 从一段文本中提取特定字段 | | `ai_summarize` | AI总结 | 对内容进行总结提炼 | ### 6.2 direct 配置 ```json { "extract_type": "direct", "extract_config": { "trimWhitespace": true, "removeLineBreaks": false, "mergeSpaces": true } } ``` ### 6.3 ai_extract 配置 ```json { "extract_type": "ai_extract", "extract_config": { "targetDescription": "从批复文件中提取可研批复的日期", "fieldType": "date", "expectedFormat": "YYYY年MM月DD日", "examples": ["2024年5月15日", "2023年12月1日"] } } ``` ### 6.4 ai_summarize 配置 ```json { "extract_type": "ai_summarize", "extract_config": { "summarizePrompt": "请对以下内容进行总结,重点描述项目建设的必要性", "focusPoints": ["建设背景", "现状问题", "建设目的"], "rules": ["使用正式的工程报告语言", "保留关键的数据和指标"], "style": "formal", "maxLength": 300 } } ``` --- ## 七、API 设计 ### 7.1 模板管理 API | 方法 | 路径 | 说明 | | ---- | ---- | ---- | | POST | `/api/v1/templates` | 创建模板 | | GET | `/api/v1/templates` | 获取模板列表 | | GET | `/api/v1/templates/{id}` | 获取模板详情 | | PUT | `/api/v1/templates/{id}` | 更新模板 | | DELETE | `/api/v1/templates/{id}` | 删除模板 | | POST | `/api/v1/templates/{id}/publish` | 发布模板 | | POST | `/api/v1/templates/{id}/duplicate` | 复制模板 | ### 7.2 来源文件定义 API | 方法 | 路径 | 说明 | | ---- | ---- | ---- | | POST | `/api/v1/templates/{templateId}/source-files` | 添加来源文件定义 | | GET | `/api/v1/templates/{templateId}/source-files` | 获取来源文件定义列表 | | PUT | `/api/v1/templates/{templateId}/source-files/{id}` | 更新来源文件定义 | | DELETE | `/api/v1/templates/{templateId}/source-files/{id}` | 删除来源文件定义 | | POST | `/api/v1/templates/{templateId}/source-files/reorder` | 调整顺序 | ### 7.3 变量 API | 方法 | 路径 | 说明 | | ---- | ---- | ---- | | POST | `/api/v1/templates/{templateId}/variables` | 创建变量 | | GET | `/api/v1/templates/{templateId}/variables` | 获取变量列表 | | GET | `/api/v1/templates/{templateId}/variables/{id}` | 获取变量详情 | | PUT | `/api/v1/templates/{templateId}/variables/{id}` | 更新变量 | | DELETE | `/api/v1/templates/{templateId}/variables/{id}` | 删除变量 | | POST | `/api/v1/templates/{templateId}/variables/{id}/preview` | 预览提取结果 | ### 7.4 生成任务 API | 方法 | 路径 | 说明 | | ---- | ---- | ---- | | POST | `/api/v1/generations` | 创建生成任务 | | GET | `/api/v1/generations` | 获取生成任务列表 | | GET | `/api/v1/generations/{id}` | 获取任务详情 | | POST | `/api/v1/generations/{id}/execute` | 执行提取 | | GET | `/api/v1/generations/{id}/progress` | 获取执行进度 | | PUT | `/api/v1/generations/{id}/variables/{varName}` | 修改变量值 | | POST | `/api/v1/generations/{id}/confirm` | 确认并生成文档 | | GET | `/api/v1/generations/{id}/download` | 下载生成的文档 | --- ## 八、核心流程 ### 8.1 创建模板流程 ``` 1. 用户上传示例报告 POST /api/v1/parse/upload → 返回 document_id 2. 创建模板 POST /api/v1/templates { "name": "110kV输变电工程预评价模板", "baseDocumentId": "doc_001" } → 返回 template_id 3. 添加来源文件定义 POST /api/v1/templates/{templateId}/source-files { "alias": "可研批复", "description": "可研批复文件", "fileTypes": ["pdf", "docx"], "required": true, "exampleDocumentId": "doc_002" } 4. 创建变量(前端在编辑器中操作,调用此API) POST /api/v1/templates/{templateId}/variables { "name": "project_name", "displayName": "工程名称", "location": { "elementId": "elem_001", "type": "text", "startOffset": 10, "endOffset": 35 }, "exampleValue": "襄阳连云 110kV 输变电工程", "sourceFileAlias": "可研批复", "sourceType": "document", "sourceConfig": { ... }, "extractType": "ai_extract", "extractConfig": { ... } } 5. 发布模板 POST /api/v1/templates/{templateId}/publish ``` ### 8.2 生成报告流程 ``` 1. 创建生成任务 POST /api/v1/generations { "templateId": "tpl_001", "name": "武汉东湖110kV预评价", "sourceFileMap": { "可研批复": "doc_123", "站址报告": "doc_456" } } → 返回 generation_id 2. 执行提取 POST /api/v1/generations/{generationId}/execute 3. 查询进度 GET /api/v1/generations/{generationId}/progress → { "total": 10, "completed": 6, "currentVariable": "geology_summary" } 4. 查看提取结果,可修改 GET /api/v1/generations/{generationId} PUT /api/v1/generations/{generationId}/variables/project_name { "value": "修正后的值" } 5. 确认并生成文档 POST /api/v1/generations/{generationId}/confirm 6. 下载 GET /api/v1/generations/{generationId}/download ``` --- ## 九、与现有系统集成 ### 9.1 复用已有服务 | 已有服务 | 复用内容 | | -------- | -------- | | document-service | 文档存储、DocumentElement 结构 | | parse-service | 文档解析、结构化提取 | | ai-service | DeepSeek API 调用、AI 提取 | | graph-service | 可选:将变量注册为数据源 | ### 9.2 重构 extract-service 现有 `extract-service` 的代码需要重构: | 原概念 | 新概念 | 说明 | | ------ | ------ | ---- | | Project | Template | 模板取代项目 | | SourceDocument | SourceFile | 来源文件**定义**,不是具体文件 | | ExtractRule | Variable | 变量,绑定到文档位置 | | ExtractResult | Generation.variable_values | 生成任务中的变量值 | | - | Generation | 新增:生成任务 | --- ## 十、未来扩展 ### 10.1 模板市场 - 用户可将模板设为公开 - 其他用户可基于公开模板创建自己的模板 - 模板评分和使用统计 ### 10.2 批量生成 - 上传多组来源文件 - 一次生成多份报告 - 生成任务队列管理 ### 10.3 版本控制 - 模板版本管理 - 生成任务关联模板版本 - 版本对比和回滚 --- > 文档结束