Commit a5990444 authored by Data Governance Dev's avatar Data Governance Dev

feat(web2): 身份证治理去掉空字符串检测 —— 空白/None/全空格都不算违规

需求调整:业务上认为「字段没填」≠「填了不合规的值」。
之前 NULL/空字符串会被打成 EMPTY violation 计入 bad_rows,新逻辑直接合规。

改动:
- idcard_validator.py
  - validate():value is None 或 strip() 后空字符串 → ok=True, violations=[]
  - VIOLATION_LABELS 移除 EMPTY 条目
  - docstring 顶部去掉「1. EMPTY」校验项,更新设计说明
- IdCardTool.vue
  - ruleLabels 移除 EMPTY → '空值'

验证(python 直接调 validate):
  None / '' / '   ' / '\t\n  '  →  ok=True, violations=[]  ✓
  '110101199003078888'           →  ok=False, ['CHECK_DIGIT'] ✓
  '12345'                         →  ok=False, ['LENGTH']    ✓

涉及到的语义变化:
- 统计上:matched_columns 不变(仍然命中的字段),invalid_count 会下降
- 前端 UI:「空值」chip 不会再出现
parent cfca7ea3
...@@ -6,13 +6,12 @@ ...@@ -6,13 +6,12 @@
GB/T 2260 地址码(最简校验:非 00 前缀即可,完整区划表留待外部数据接入) GB/T 2260 地址码(最简校验:非 00 前缀即可,完整区划表留待外部数据接入)
校验项: 校验项:
1. EMPTY 值为空 / None 1. LENGTH 长度不是 18 位 / 15 位
2. LENGTH 长度不是 18 位 / 15 位 2. CHARSET 字符集不合规(前 17 位非数字 / 第 18 位非 0-9 或 X)
3. CHARSET 字符集不合规(前 17 位非数字 / 第 18 位非 0-9 或 X) 3. CHECK_DIGIT 校验位计算错误(GB 11643 §6)
4. CHECK_DIGIT 校验位计算错误(GB 11643 §6) 4. ADDRESS_PREFIX 地址码全 0 或前 2 位为 00
5. ADDRESS_PREFIX 地址码全 0 或前 2 位为 00 5. BIRTH_DATE 出生日期不是真实日期 / 晚于今天 / 早于 1900
6. BIRTH_DATE 出生日期不是真实日期 / 晚于今天 / 早于 1900 6. ORDER_CODE 顺序码不在 001-999 范围
7. ORDER_CODE 顺序码不在 001-999 范围
返回结构: 返回结构:
{ {
...@@ -27,6 +26,10 @@ ...@@ -27,6 +26,10 @@
设计: 设计:
- reasons 是按 rule_id 去重的 dict(一类违规只给一条原因文本) - reasons 是按 rule_id 去重的 dict(一类违规只给一条原因文本)
- 原因文本含「现场值」+「期望值」,方便定位 - 原因文本含「现场值」+「期望值」,方便定位
- 2026-08-17:空白 / None / 全空格不再算违规(直接当 ok=True)
- 业务上认为「字段没填」≠「填了不合规的值」
- 旧逻辑:None / '' → EMPTY violation(要求必填)
- 新逻辑:None / '' / ' ' → 直接合规,violations=[]
""" """
from __future__ import annotations from __future__ import annotations
...@@ -158,26 +161,26 @@ def validate(value) -> dict: ...@@ -158,26 +161,26 @@ def validate(value) -> dict:
"is_15_old": bool, "is_15_old": bool,
"normalized": str|None "normalized": str|None
} }
2026-08-17:空白 / None / 全空格 → 直接 ok=True(不算违规)
""" """
if value is None: # 空白 / None / 全空格:直接合规(不算违规,2026-08-17 起)
return { s = None
"ok": False, if value is not None:
"violations": ["EMPTY"], try:
"reasons": {"EMPTY": "值为 NULL"}, s = str(value).strip()
"length": 0, except Exception:
"is_15_old": False, s = None
"normalized": None, if value is None or not s:
}
s = str(value).strip()
if not s:
return { return {
"ok": False, "ok": True,
"violations": ["EMPTY"], "violations": [],
"reasons": {"EMPTY": "值为空字符串"}, "reasons": {},
"length": 0, "length": 0,
"is_15_old": False, "is_15_old": False,
"normalized": None, "normalized": None,
} }
if _is_all_same(s) and len(s) >= 15: if _is_all_same(s) and len(s) >= 15:
return { return {
"ok": False, "ok": False,
...@@ -265,7 +268,6 @@ def validate(value) -> dict: ...@@ -265,7 +268,6 @@ def validate(value) -> dict:
# ── 规则 ID → 中文标签(前端展示用)─────────────────────── # ── 规则 ID → 中文标签(前端展示用)───────────────────────
VIOLATION_LABELS = { VIOLATION_LABELS = {
"EMPTY": "空值",
"LENGTH": "长度不是 18 位", "LENGTH": "长度不是 18 位",
"CHARSET": "字符集 / 占位符类不合规", "CHARSET": "字符集 / 占位符类不合规",
"CHECK_DIGIT": "校验位错误(GB 11643 §6)", "CHECK_DIGIT": "校验位错误(GB 11643 §6)",
......
...@@ -246,8 +246,8 @@ import IdCardTable from '@/components/IdCardTable.vue' ...@@ -246,8 +246,8 @@ import IdCardTable from '@/components/IdCardTable.vue'
const { state, currentConnection } = useDbConnection() const { state, currentConnection } = useDbConnection()
/* ──── 规则 ID → 中文标签(前端展示) ──── */ /* ──── 规则 ID → 中文标签(前端展示) ──── */
// 2026-08-17:去掉了 EMPTY 规则(空白/None/全空格不再算违规,后端直接当合规)
const ruleLabels = { const ruleLabels = {
EMPTY: '空值',
LENGTH: '长度', LENGTH: '长度',
CHARSET: '字符集', CHARSET: '字符集',
CHECK_DIGIT: '校验位', CHECK_DIGIT: '校验位',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment