feat: 提取凭证摘要(摘要)

- parser: 新增摘要提取逻辑,从 OCR 结果中筛选非代码/非金额文本
- 去掉 skip_keywords 中的日/期/年/月(误杀摘要文本)
- search_lines 用完整 OCR 行(不被合计行截断)
- 45张测试: 前30行中20行成功提取真实摘要

fix: remove debug prints, reject bank account/status texts
This commit is contained in:
xiaoxue_admin 2026-06-22 09:42:20 +08:00
parent e27aa46451
commit b86cf8d77f
1 changed files with 43 additions and 1 deletions

View File

@ -135,7 +135,7 @@ class K3VoucherParser:
skip_keywords = ['科目', '摘要', '借方', '贷方', '出纳',
'制单', '审核', '经办', '过账', '附件',
'Manager', 'HONOR', 'Magic6', '合计',
'', '', '', '', '凭证', '']
'凭证', '']
for text, conf, cx, cy, box in data_lines:
if any(k in text for k in skip_keywords):
@ -165,6 +165,48 @@ class K3VoucherParser:
if not codes:
return self._parse_entries_fallback()
# === 4.5 摘要提取:从剩余 OCR 文字中找摘要 ===
code_y_min = min(c['y_pos'] for c in codes)
desc_candidates = []
search_lines = self.lines
for text, conf, cx, cy, box in search_lines:
if conf < 0.5:
continue
is_code = False
for c in codes:
if abs(c['y_pos'] - cy) < 20:
is_code = True
break
if is_code:
continue
if re.search(r'\d+\.\d{2}', text):
continue
if any(k in text for k in skip_keywords + ['合计', '亿', '', '', '', '']):
continue
if re.match(r'^[\d.\-,]+$', text.strip()):
continue
if len(text.strip()) < 3:
continue
if cx < 300:
continue
if text.strip().startswith('·') or '工商银行' in text:
continue
if '支行' in text or re.search(r'\d{15,}', text):
continue
if text.strip() in ('未到账', '已到账', '未达', '已达'):
continue
if cy < code_y_min - 50:
continue
# 去重:跳过 y 距离 < 30 的重复文本
if any(abs(d['y'] - cy) < 30 for d in desc_candidates):
continue
desc_candidates.append({'text': text, 'y': cy, 'x': cx})
desc_candidates.sort(key=lambda d: d['y'])
for i, desc in enumerate(desc_candidates):
if i < len(codes):
codes[i]['desc'] = desc['text']
# === 5. 提取金额 ===
amounts = []
skip_amount_keywords = ['Manager', 'HONOR', 'Magic6', 'RMB',