report-detect/docs/ocr-validation-flow.md

202 lines
6.4 KiB
Markdown
Raw Permalink Normal View History

# 认监扫描件识别:上传流程与结果判定因果(旧项目逻辑)
本文件整理自旧项目 `C:\Users\WIN10\Desktop\work\22nd-week\认监-扫描件识别`,用于后续对判定逻辑做严格校对与修改。
## 1. 端到端流程概览
### 1.1 前端 4 步流程(新建识别)
来源:`frontend/report-detect-web/src/views/shibieneirong/xinjianshibie/index.vue`
1. 前置信息校验
用户输入CMA证书编号、机构名称、报告编号、产品名称、报告签发日期、申请人姓名、邮箱、电话。
前端本地校验,未做后端校验。
2. 上传报告
选择 PDF 文件,仅前端模拟进度,上传由下一步触发。
3. 智能校验
创建任务后开始轮询预览接口,展示校验结果,满足 PASS 自动提交。
4. 提交完成
展示成功提示。
### 1.2 后端主流程(任务创建 → OCR → 提交)
来源:`backend/report-detect-api/api/endpoints.py`
1. `/tasks` 新建任务
- 保存 PDF 到 `data/uploads/<approval_id>.pdf`
- 插入 `tasks` 记录,`status = processing`
- 写入历史:`已接收文件`
- 触发后台 OCR`run_ocr_task(...)`
2. `run_ocr_task` 后台 OCR
- 生成预览图片(每页)写入 `pages`
- 调用 `ocr_engine.process_pdf` 获取判定结果
- 写入 `ocr_results` 记录
- 写入历史:`系统识别完成`
- 更新任务状态:`ocr_completed`
3. `/reports/{id}/preview`
- 前端轮询获取 OCR 结果与预览图片
4. `/reports/{id}/submit`
- 只允许 `ocr_result.api_status``PASS/valid/pass` 才能提交
- 状态改为 `pending`,写入历史 `用户提交审核`
5. `/reports/{id}/audit`
- 人工审核:`compliant / non-compliant`
- 写入历史 `人工审核完成`
## 2. OCR 与判定逻辑(核心)
来源:`backend/report-detect-api/ocr_engine.py` 与 `scripts/api_validator.py`
### 2.1 OCR 识别来源与规则
1. **CMA 提取**
- 取 PDF 第 1 页,转换为高分辨率图片
- 使用 `cma_paddle.extract_cma_code_paddle`
- 若提取成功,`extracted_cma = 识别值`
2. **机构名提取**
- 优先使用数字证书 `cert_utils.extract_digital_certificate_info` 中的组织名称
- 若无数字证书,则当前逻辑不做完整布局识别(旧项目为简化逻辑),可能为空
- `extracted_org` 可能是多个机构名拼接(以 ` | ` 分隔)
### 2.2 判定输入与中间变量
输入:
- 用户输入:`cma_number`、`institution`
- OCR 输出:`extracted_cma`、`extracted_org`
中间变量(来自 `ocr_engine.process_pdf`
1. `ocr_match_passed`
- 用户输入机构名与 OCR 机构名做“宽松匹配”
- 使用 `api_validator.is_org_name_match(..., threshold=0.6, strict=False)`
- 只要某个 OCR 候选匹配,即为 `True`
2. `cma_exists`
- 调用 `api_validator.query_cma_registry(cma_input)`
- 若返回结果非空 → `True`
3. `org_exists`
- 调用 `api_validator.query_cma_by_name(manual_institution)`
- 若存在任意严格匹配(`threshold=0.8, strict=True``True`
4. `api_consistent`
- 要求 `cma_exists == True``org_exists == True`
- 且用户输入机构名必须与 `query_cma_registry` 返回的机构名严格匹配
- 匹配规则:`threshold=0.8, strict=True`
### 2.3 最终判定条件PASS / FAIL
最终 `api_status` 由以下条件决定:
```
api_status = PASS 当且仅当:
ocr_match_passed == True
且 api_consistent == True
否则 api_status = FAIL
```
## 3. 判定因果链(结果与提示)
### 3.1 核心因果链
1. OCR 能否识别机构名
- 影响 `ocr_match_passed`
2. CMA 是否存在
-`query_cma_registry` 返回结果决定
3. 机构名是否存在
-`query_cma_by_name` 且严格匹配决定
4. CMA 与机构名是否一致
- 必须在 CMA 的查询结果中匹配机构名
5. 通过条件
- `ocr_match_passed == True``api_consistent == True`
### 3.2 结果组合与表现
以下为主要组合场景(前端 Step3 展示逻辑):
1. **完全通过**
- `cma_exists = True`
- `org_exists = True`
- `api_status = PASS`
- 提示:第三行显示“通过”,允许提交,并会自动提交
2. **CMA 不存在**
- `cma_exists = False`
- `org_exists = True/False`
- `api_status = FAIL`
- 提示CMA 行显示“不存在”,第三行显示“不通过”,禁止提交
3. **机构名不存在**
- `org_exists = False`
- `cma_exists = True/False`
- `api_status = FAIL`
- 提示:机构行显示“不存在”,第三行显示“不通过”,禁止提交
4. **CMA 与机构名不一致**
- `cma_exists = True`
- `org_exists = True`
- `api_status = FAIL`
- 提示:第三行显示“不通过”,禁止提交
5. **OCR 机构名识别失败 / 与人工输入不一致**
- `ocr_match_passed = False`
- 即使 API 结果一致,仍会 `FAIL`
- 提示:第三行显示“不通过”,禁止提交
## 4. 前端提示与提交规则
来源:`frontend/report-detect-web/src/views/shibieneirong/xinjianshibie/components/step3.vue`
### 4.1 三行展示逻辑
1. 机构名称存在性
- 显示 `ocrResult.org_exists`
2. CMA 证书编号存在性
- 显示 `ocrResult.cma_exists`
3. 机构名称与证书编号一致性
- 显示 `ocrResult.API核验`
- `PASS` → 通过
- 否则 → 不通过
### 4.2 “无法提交”提示
出现条件:
- `ocrResult.API核验 !== 'PASS'`
提示文案:
```
系统未能校验通过相关信息无法提交。请检查报告是否清晰或包含正确的CMA信息。
```
### 4.3 自动提交
条件:
- `ocrResult.API核验 === 'PASS'`
行为:
- Step3 完成后自动调用 `/reports/{id}/submit`
## 5. 状态流转与历史记录
### 5.1 状态流转
```
processing -> ocr_completed -> pending -> compliant / non-compliant
```
### 5.2 系统历史记录
自动写入的系统记录:
- `已接收文件`
- `系统识别完成`
### 5.3 人工审核记录
人工审核写入:
- `人工审核完成`
- 内容包含审核结论与意见
## 6. 关键规则总结(用于后续修改)
1. **必须同时满足 OCR 机构匹配 + API 一致性,才能 PASS**
2. **CMA 存在 + 机构存在 + CMA-机构一致** 才有机会 PASS
3. **任一条件缺失 → FAIL**
4. FAIL 时前端禁止提交,并提示“系统未能校验通过相关信息…”