# 数据信息填报系统 · 功能逻辑 PRD
> 产品代号:**填报通 / CollectFlow**(暂定)
> 版本:V1.9(2026-09-28 同步数据库决策与字段落库方式)
> 日期:2026-09-24
> 文档定位:**只描述"系统怎么运转",不含数据库设计、接口定义、代码结构**
> 配套文档:《数据信息填报系统PRD》(主 PRD,含库表与接口)—— 主 PRD 回答"做什么",本文回答"怎么运转"
> 读者:产品经理、研发、测试、UI 设计
## 变更记录
| 版本 | 日期 | 变更内容 |
|---|---|---|
| V1.0 | 2026-09-24 | 初稿:角色/流转/12 个功能逻辑/规则速查/20 个边界场景/文案规范 |
| **V1.1** | 2026-09-24 | **压缩逻辑按实测重写**:用 28 张真实 A4 扫描件实测,**300dpi/q85 下 28/28 达标(平均 806KB)**,无需牺牲清晰度。① §3.7.1 新增实测结论;② §3.7.3 由"逐级降质逼近"改为"一次编码到位 + 兜底路径";③ §3.7.4 抽检机制标注为"实测不触发";④ §4 速查表、§7 未决事项同步更新 |
| **V1.2** | 2026-09-24 | **修正材料来源通道**:取消"直接拍照"(实测 4 类材料无一来自现场拍照,均为截图/扫描件/照相馆电子版)。① §3.5 改为"**微信聊天记录 / 手机相册 / 聊天文件**"三通道,拍照默认关闭;② 新增"**必须保留原始文件名**"设计逻辑(聊天记录可拿到原始名,相册拿不到);③ 新增来源引导文案与 4 个相关异常分支;④ §4 速查表、§5 场景表(+4 条)、§6 文案、§7 未决事项同步更新 |
| **V1.3** | 2026-09-24 | **新增"名单门禁"(D6)**:① §2.1/§2.2 流程图改为"扫码 → 姓名+身份证核验 → 填报",**社会收集也必须先导名单**(废除"自由填报");② §2.4 由三条铁律扩为**四条**,新增"没有名单就没有填报";③ §3.1 整节重写为**门禁逻辑**(判定优先级、命中后绑定、统一失败提示、**限流防枚举**、名单不下发);④ §3.3 名单逻辑补充"姓名/身份证列为必填、缺列阻断发布";⑤ §4 速查、§5 场景(14/15 改写,+4 条)、§6 文案(+5 组门禁文案)、§7 未决事项(+4 项)同步更新 |
| **V1.4** | 2026-09-24 | **新增材料识别设计(方案 B:规则为主 + VLM 兜底)**:① §3.5 升级为「材料上传与材料识别」,新增 **3.5-B 材料识别**整节(四路信号、文件名/形态/关键词/印章四类规则、置信度分级、**VLM 三种触发条件**、冲突裁决表、成本预估、三条不可违背原则、六个集成点);② §4 速查新增"材料识别"块;③ §5 场景 +4 条(29–32);④ §6 文案 +3 组;⑤ §7 未决事项 +3 项 |
| **V1.5** | 2026-09-24 | **材料识别规则实测校正(用 112 个真实文件 + 32 个 OCR 抽样验证)**:
① **证伪初版形态规则**——初版写"身份证宽高比 ≈1.585",实测为 **0.732–1.016**,与一寸照片 0.714 **高度重叠,形态层根本无法区分**;② 架构改为**四层递进**:文件名 → 形态(**只分流派,不定型**)→ OCR 强词计分 → VLM;③ **证伪"命中即判定"**——实测关键词大量交叉命中(工作证明含"学籍/学校"、学籍表含"居民身份证"),改为**只用强词 + 加权计分取最高**;④ 新增**一寸照片"零文字"判据**(实测 8/8 无文字);⑤ **VLM 触发率由 15% 重估为 2%~10%**(初版偏高的原因是形态规则写错产生假冲突);⑥ 新增 §3.5-B 开头的**实测验证结果表 + OCR 耗时表 + 局限性说明**;⑦ §4 速查、§7 未决事项同步更新 |
| **V1.6** | 2026-09-28 | **按官方《考生线下报名信息导入模板》校准表单填写逻辑**:① §3.4 重写——新增**「评价计划」三级级联**(职业→工种→等级受计划约束,从源头防错,源自官方规则 04/05/06);② 新增**补考科目数量约束**(三/四/五级最多 1 科、一/二级最多 2 科、**专项职业能力无补考**);③ 新增**专项职业能力整体降级**(无工种/无等级/无补考);④ 明确 **"无"是合法业务值而非空值**(工作单位、报考工种);⑤ 补格式校验(入学时间 YYYY-MM-DD、工作年限阿拉伯数字、下拉严格受限);⑥ §4 速查新增"表单填写"块;⑦ 异常分支 +3 条 |
| **V1.7** | 2026-09-28 | **新增「评价计划导入」完整逻辑(确认下发文件模式 = A)**:① §3.2 拆为 **3.2-A 评价计划导入** + 3.2-B 任务创建向导;② 定义**导入七步流程**(上传 → 自动解析 → **人工确认列映射** → 导入体检 → **差异对比** → 确认写入 → 留痕);③ 明确列映射**必须人工确认但可保存复用**、原始文件**必须留档**、差异对比中**移除项须关联已有考生告警**;④ 7 条异常分支(扫描版PDF、合并单元格、增量 vs 全量、机构临时增补…);⑤ §4 速查新增"评价计划"块;⑥ §7 未决事项 +3 项(**需索取真实计划清单样本**) |
| **V1.8** | 2026-09-28 | **实测校正:不存在"计划清单"文件,报考范围来自名单**:
① §3.2-A 由"评价计划导入(七步流程)"整体重写为「**报考范围聚合**」——名单导入后自动聚合"职业×工种×等级"集合 + 一致性体检 + 管理员确认;
② 新增**追加名单告警机制**(超出已确认范围的报考项需管理员确认——范围失控的主要入口);
③ §3.4 新增 **⚠️ 最关键的第 1 条「字段三类规则」**:🔒锁定(姓名/身份证号/报考三项,空则阻断发布)/✏️预填可改(其余,标注"老师已填请核对")/📄材料(学生唯一重活)——依据是实测名单 21 项已填 18 项,**学生端几乎不用打字**;
④ §3.4 步骤重新编号为 13 步,异常分支措辞校正("计划已过期"→"报考范围已关闭");
⑤ §4 速查新增"报考范围""字段三类规则"两块,删除"评价计划"块;
⑥ §7 关闭 21/22/23,新增 24(预填字段能否由学生修改) |
| **V1.9** | 2026-09-28 | **同步数据库决策(PG / Vastbase)与字段落库方式**:① §3.4「字段三类规则」补**存储说明**——18 个业务字段在名单表与填报单表中为**正式列**(非 JSON),"按工种统计""按学历筛选"可直接走索引,仅机构额外追加字段进 `extras_json`;② 本文档其余部分不受影响(功能逻辑卷不承载库表设计,DDL 见主 PRD §7.3) |
---
## 目录
- [0. 文档说明与关键决策](#0-文档说明与关键决策)
- [1. 角色与端](#1-角色与端)
- [2. 全局业务流转](#2-全局业务流转)
- [3. 功能逻辑详述](#3-功能逻辑详述)
- [3.1 身份识别与任务匹配](#31-身份识别与任务匹配)
- [3.2 报考范围聚合与任务创建](#32-报考范围聚合与任务创建)
- [3.2-A 报考范围聚合](#32-a-报考范围聚合按实际情况校正)
- [3.2-B 任务创建向导](#32-b-任务创建向导)
- [3.3 名册逻辑](#33-名册逻辑)
- [3.4 表单填写逻辑](#34-表单填写逻辑)
- [3.5 材料上传与材料识别逻辑](#35-材料上传与材料识别逻辑)
- [3.5-A 上传流程](#35-a-上传流程)
- [3.5-B 材料识别(这是什么材料)](#35-b-材料识别这是什么材料)
- [3.6 命名规范化逻辑](#36-命名规范化逻辑)
- [3.7 压缩逻辑(扫描件强制 1M)](#37-压缩逻辑扫描件强制-1m)
- [3.8 校验逻辑](#38-校验逻辑)
- [3.9 审核逻辑](#39-审核逻辑)
- [3.10 汇总导出逻辑](#310-汇总导出逻辑)
- [3.11 通知与催报逻辑](#311-通知与催报逻辑)
- [3.12 历史数据整理器逻辑](#312-历史数据整理器逻辑)
- [4. 一页纸规则速查](#4-一页纸规则速查)
- [5. 异常与边界场景](#5-异常与边界场景)
- [6. 用户可见文案规范](#6-用户可见文案规范)
- [7. 未决事项](#7-未决事项)
---
## 0. 文档说明与关键决策
### 0.1 本文包含 / 不包含
| 包含 | 不包含 |
|---|---|
| 角色能做什么、不能做什么 | 数据库表结构 |
| 每个功能的触发条件与处理步骤 | 接口定义与字段 |
| 判断规则、优先级、兜底策略 | 代码结构、类设计、框架选型 |
| 状态流转与谁能改变状态 | 部署、性能参数 |
| 用户看到什么、看到哪句话 | 测试用例(另见主 PRD §12) |
### 0.2 已决策事项(本文据此撰写)
| 编号 | 决策 | 影响章节 |
|---|---|---|
| **D1** | **扫描件(工作证明/申报表等 A4 材料)强制压缩到 1M,不做体积放宽、不设例外。** 当"≤1M"与"清晰度"冲突时,**体积优先,牺牲清晰度**;被牺牲的文件必须标记出来供人工抽检 | §3.7 |
| D2 | 学籍表等**屏幕截图类材料保持原始像素与 PNG 格式**,不缩放、不转 JPG | §3.7 |
| D3 | 校验位(身份证)用于**裁决**证件号争议,而非仅做格式校验 | §3.6、§3.8 |
| D4 | 一寸照片**统一规格化为 295×413 px(25×35mm @300dpi)** | §3.7 |
| **D5** | **材料来源只提供"选择已有文件":微信聊天记录 / 手机相册 / 手机文件;不提供"直接拍照"**(默认关闭,材料级可配)。理由:实测 4 类材料无一来自现场拍照 | §3.5 |
| **D6** | **填报必须先过名单门禁**:学校收集与社会收集**都必须先导入名单**,填报人进入前必须填写「姓名 + 身份证号」与名单匹配,**匹配不到只提示、不放行**(取消原"自助认领"与"自由填报") | §3.1、§3.3 |
---
## 1. 角色与端
| 角色 | 主用端 | 可以做什么 | 不可以做什么 |
|---|---|---|---|
| 平台运营 | PC | 开通/停用租户、查看全局用量、内容风控 | 查看任何考生的材料内容 |
| 学校管理员 | PC(主)+ 手机(次) | 建任务、配规则、导名册、终审、导出上报 | 修改已归档任务的配置 |
| 班主任 | PC + 手机 | 催报、初审、批量通过、代传材料 | 终审、导出、查看其他班级 |
| 填报人(学生) | 微信小程序 | 填报、上传、修改、撤回(未审核前) | 查看他人材料、修改已终审内容 |
| 社会填报人 | 小程序 / H5 | 自主填报 | 查看他人、指定班主任 |
**端能力差异(功能逻辑层面)**
| 能力 | 小程序 | PC |
|---|---|---|
| 填报 | ✅ 主入口 | ❌ |
| 材料来源选择 | ✅ 从微信聊天记录选(可拿原始文件名)/ 从相册选 / 从手机文件选;**不提供拍照** | ✅ 仅本地上传(拖拽或文件选择) |
| 初审 / 批量通过 | ✅ | ✅ |
| 表单设计与规则配置 | ❌(屏幕太小且易误操作) | ✅ 唯一入口 |
| 名册导入 | ❌ | ✅ |
| 汇总导出 | ❌ | ✅ |
| 查看大图 / 对比原图与压缩图 | ✅ 支持 | ✅ 支持 |
---
## 2. 全局业务流转
### 2.1 学校收集(主流程)
```
【前置】学校管理员建任务
↓ 导入名单(Excel)+ 选定班级 + 配置表单与材料规则
↓ 发布任务 → 生成填报二维码
填报人扫码 → 微信授权
↓ 【门禁】填写「姓名 + 身份证号」→ 与名单匹配
↓ 匹配成功 → 绑定名单项 → 回填只读信息 → 进入填报
↓ 匹配失败 → 统一提示页(重新填写 / 申请加入名单),不给填报
填报人逐项填写表单 → 逐项上传材料
↓ 每次上传后立即:命名规范化 → 压缩 → 校验 → (必要时)OCR
↓ 填报人看到"文件名已规范 / 体积已压缩 / 有无问题"的即时反馈
填报人提交
↓ 系统做提交前总校验(有无缺失、有无红色阻断项)
↓ 通过则进入【待初审】
班主任初审(手机或 PC)
↓ 一键批量通过全部绿色项
↓ 红黄项逐个处理:通过 或 驳回(选原因)
↓ 驳回 → 填报人收到通知 → 修改 → 重新提交(回到【待初审】)
管理员终审
↓ 全部通过后进入【已通过】
管理员导出
↓ 系统按目录规范打包(含分卷、汇总 Excel)
↓ 下载上报至认定机构
```
> 🔒 **门禁不变式**:**没有名单,就不能填报。** 名单是唯一的准入依据,不存在"自由填报"。
### 2.2 社会收集(差异流程)
```
【前置】管理员建任务(模式=社会收集,无班主任层,但同样必须先导入名单)
↓ 导入名单(预报名名单 / 意向名单 / 报名点收集的名单)
↓ 生成公开填报二维码/链接
社会人员扫码 → 微信授权
↓ 【门禁】填写「姓名 + 身份证号」→ 与名单匹配(规则与学校收集完全一致)
↓ 匹配失败 → 统一提示页,不给填报
填报 → 上传材料(同样走规范化 / 压缩 / 校验)
提交 → 直接进入【待终审】(跳过初审)
管理员终审 → 通过 → 导出
```
> ⚠️ **与学校收集唯一的差异**:审核流跳过班主任层。**名单导入与身份核验两项完全一致。**
> 📌 初稿曾写"社会收集名册可选、允许自由填报",本版已废除。
### 2.3 状态机
**填报单状态**
| 状态 | 含义 | 谁能改变 | 可回到哪些状态 |
|---|---|---|---|
| 草稿 | 已开始填但未提交 | 填报人 | → 待初审/待终审(提交) |
| 待初审 | 已提交,等班主任 | 班主任、系统(跳过初审时) | → 待终审(通过)/→ 已驳回(驳回) |
| 待终审 | 初审通过,等管理员 | 管理员 | → 已通过(通过)/→ 已驳回(驳回) |
| 已驳回 | 被打回,等填报人修改 | 填报人 | → 待初审/待终审(重新提交) |
| 已通过 | 终审通过 | 管理员(解锁) | → 已归档 |
| 已归档 | 任务结束后锁定 | — | 不可逆 |
> 🔒 **业务不变量**:终审通过后默认不可修改。如需更正,必须管理员主动"解锁",且解锁动作计入审计。
**任务状态**
| 状态 | 含义 | 转入条件 | 转出条件 |
|---|---|---|---|
| 草稿 | 配置中,填报人不可见 | 新建 | 管理员点"发布" |
| 收集中 | 可填报 | 发布 | 到期自动截止 / 手动截止 |
| 暂停 | 临时停止接收 | 管理员操作 | 管理员恢复 |
| 已截止 | 不再接收新提交(已提交的仍可审核) | 到期或手动 | 归档 |
| 已归档 | 只读 | 管理员操作 | 不可逆 |
**材料项状态**
| 状态 | 含义 |
|---|---|
| 未上传 | 该材料尚未提交 |
| 已上传待处理 | 文件已到,正在规范化/压缩/校验 |
| 已受理 | 处理完成,无阻断问题 |
| 有警告 | 处理完成,存在黄项(可提交但需注意) |
| 有阻断 | 处理完成,存在红项(不可提交) |
| 已驳回 | 审核认为本项不合格,需重传 |
| 已通过 | 审核确认合格 |
### 2.4 四条铁律
1. **没有名单,就没有填报**——两种收集模式都必须先导入名单,填报人必须通过「姓名 + 身份证号」核验才能进入填报页,核验不通过只提示、不放行。
2. **一个人在一个任务下只有一份填报单**——不允许同一人重复建单,只允许在原有单上修改。
3. **没有规范文件名、没有压到 1M 内的文件,不得进入汇总包**——导出时若发现不合格文件,导出直接报错并列出清单,不允许"带着问题打包"。
4. **终审通过是"进入上报范围"的唯一门槛**——初审通过不算,材料上传完成也不算。
---
## 3. 功能逻辑详述
> 每个功能按「**触发 → 处理 → 输出 → 异常**」四段描述。
### 3.1 身份识别与名单匹配(进入填报的门禁)
> ⚠️ **本版强化**:学生填报与外部(社会)填报**都必须先导入名单**,填报人**必须先通过「姓名 + 身份证号」匹配名单**,匹配成功才进入填报页。**匹配不到就不给填,只做提示。**
**触发**:填报人扫码或点击链接进入任务。
**处理步骤**
```
扫码进入
↓ ① 微信授权(静默取 openid)
↓ ② 解析任务:二维码带的任务标识 → 无效则提示"链接无效"
↓ ③ 检查任务状态:未开始 / 已暂停 / 已截止 / 已归档 → 分别提示,不进入
↓ ④ 【门禁页】填写两项:
· 姓名
· 身份证号(数字键盘、自动分段、末位 X 自动大写、支持粘贴)
本地先做格式 + 校验位校验 → 不合格当场提示,不发请求
↓ ⑤ 提交匹配(在服务端完成)
↓ ⑥ 命中 → 绑定 → 进入填报页
未命中 → 失败提示页(重新填写 / 申请加入名单)
```
**匹配判定顺序**
| 优先级 | 判定条件 | 结果 |
|---|---|---|
| 1 | 身份证号 **+** 姓名 **完全一致** | ✅ 直接命中 |
| 2 | 身份证号命中,但姓名不一致 | 尝试**形近字 / 同音字纠错**(复用 §3.6 能力)→ 命中则请用户确认"你是不是 XXX?" |
| 3 | 身份证号命中,姓名纠错后仍不一致 | 🔴 失败(**不提示姓名错误,统一提示**) |
| 4 | 身份证号未命中 | 🔴 失败 |
| 5 | 命中多条(同一人在两个班) | 列出可选班级,由本人选择 |
**命中后的处理**
1. 该名单项**锁定绑定**到当前用户(openid),防止他人冒用;
2. 若该名单项**已被其他人绑定** → 提示"该信息已被登记,如有疑问请联系老师";
3. 姓名、身份证号**回填并置为只读**(避免用户改动后又对不上名单);
4. 班级、专业、学号等名单中已有的信息一并回填;
5. 进入填报页。
**匹配失败提示(统一文案)**
> "**没有找到你的信息。**
> 请核对姓名和身份证号是否与老师提供的名单一致。
> 如果确实已报名,可以申请加入名单,由老师审核。"
提供两个动作:**重新填写** / **申请加入名单**(FR-509)——**均为系统内动作,不展示任何联系方式**
**🔒 安全要求(重要,必须实现)**
| 要求 | 说明 |
|---|---|
| **限流** | 同一 openid 每小时最多 10 次匹配;同一 IP 每分钟最多 20 次;超出则锁定并提示"操作过于频繁,请稍后再试" |
| **失败原因不区分** | 无论"身份证号不在名单"还是"姓名不匹配",**提示文案完全一致**。否则可被用来探测某个身份证号是否在名单中 |
| **名单不下发** | 名单只在服务端参与匹配,**绝不下发到前端** |
| **不记录明文匹配日志** | 失败尝试只记 openid、时间、结果,不记明文姓名与身份证号 |
| **传输加密** | 姓名与身份证号走加密传输 |
**异常分支**
| 情况 | 处理 |
|---|---|
| 姓名对、身份证号错(或反之) | 统一失败提示,不透露是哪一项错 |
| 身份证号对、姓名有错别字(如"扬晨"↔"杨晨") | 形近字纠错命中 → "你是不是 **杨晨**?" → 用户确认后通过 |
| 一人在两个班的名单中 | 两条都列出,让本人选择班级;结果通知管理员核对 |
| 该名单项已被他人绑定 | 提示"该信息已被登记,如有疑问请联系老师" |
| 任务已截止但确需补交 | 提示已截止;管理员可延长截止或点名放行 |
| 同一微信帮多人填(哥哥帮弟弟) | 允许,但**切换填报人需重新走核验**,且记录操作留痕 |
| 名单外的人确实要报名 | 本版按需求实现为"**不给填、只提示**",需老师去后台把人加进名单(见下方待决策事项) |
> 🤔 **待决策:名单外的人怎么处理?**
> **修订(FR-509)**:名单外的人原先只能"联系老师",老师需反复去后台加人——这在几百人的社会收集中会成为运营负担。现已改为**学生自助申请 + 管理员逐条审批**,且**系统内不展示联系方式**。
> **建议方案**(未纳入本版):在失败页增加"**申请加入名单**"按钮 → 生成管理员待办 → **管理员批准后自动放行**。
> 这样既守住"必须先有名单"的门禁,又不用老师手工加人。**请确认是否采纳。**
### 3.2 报考范围聚合与任务创建
#### 3.2-A 报考范围聚合(⚠️ 按实际情况校正)
> **纠正**:上一版假设"认定机构会下发一份计划清单文件",**该假设不成立**。
> 经真实名单实测确认:**「报考职业 / 报考工种 / 报考等级」这三列,在导入名单时就已经由老师填好了**(28/28,均为「车工 / 数控车工 / 四级中级工」)。
> ⇒ 报考范围**从名单聚合而来**,**不需要任何外部文件**。
**触发**:名单导入完成后自动执行。
**处理步骤**
```
名单导入
↓
① 【聚合】扫描全部名单行的「报考职业 / 报考工种 / 报考等级」
↓ 生成"职业 × 工种 × 等级"的取值集合
↓
② 【一致性体检】输出报告:
· 是否有人的三项为空(红色必填,不该为空)
· 同一职业下是否出现互相矛盾的工种
· 等级是否与该工种的常规设置相符
· 是否与参考字典拼写不符(如"数控车床工" vs "数控车工")
· 本次共涉及几组"职业/工种/等级"
↓
③ 【管理员确认 / 修正】
↓ 写入 collect_task.plan_scope_json
↓
④ 学生端只读展示 + 导出时原样写回 Excel 的 G/H/I 列
```
**追加名单时的约束(关键防线)**
| 情况 | 处理 |
|---|---|
| 追加的人报考项**在已确认范围内** | ✅ 直接接受 |
| 追加的人报考项**超出范围** | ⚠️ **告警**:"新增了范围外的报考项:车工 / 普通车工 / 三级",**需管理员确认后才接受**,并同步更新范围 |
> 💡 中途补录最容易绕过审核,是报考范围失控的主要入口,必须设这道闸。
**异常分支**
| 情况 | 处理 |
|---|---|
| 名单里有人三项为空 | 🔴 **阻断发布**:"名单中有 N 人未填写报考职业/工种/等级" |
| 整批出现多组不同的报考项 | 正常(一个任务可覆盖多个工种),但需管理员确认无误 |
| 老师发现填错想改 | 管理员可直接修改名单行(留痕),范围自动重新聚合 |
| 名单里出现参考字典没有的职业/工种 | 仅提示"可能拼写有误",**不阻断**(最终以机构要求为准) |
| 认定类型 = 专项职业能力 | 三项中只有"职业"有值,工种/等级允许为空 |
**关键设计**
| # | 设计点 | 理由 |
|---|---|---|
| 1 | **范围是"聚合结果",不是"约束来源"** | 老师已经确定好了,系统只做体检与展示,**不越权更正** |
| 2 | **一致性体检比范围校验更有价值** | 单看一行都合法,但"38 人报数控车工、2 人报车工"很可能是填错——**这类问题只有聚合后才能发现** |
| 3 | **追加名单必须告警** | 见上表 |
| 4 | **参考字典只提示、不阻断** | 机构可能有非常规的职业名称,**系统不该比机构更权威** |
**输出**:`collect_task.plan_scope_json`(本期报考范围)+ 一致性体检报告。
#### 3.2-B 任务创建向导
**触发**:管理员在工作台点"新建收集任务"。
**七步逻辑**
| 步骤 | 输入 | 校验 | 输出 |
|---|---|---|---|
| ① 基本信息 | 任务名、收集模式(学校/社会)、批次号、专业、工种、等级、起止时间 | 必填;结束时间必须晚于开始时间;批次号在租户内唯一 | 任务骨架 |
| ② 覆盖班级 | 勾选本次收集涉及哪些班级 | 学校模式至少选 1 个班;社会模式可选报名点 | 应填人范围 |
| ③ 名单 | 上传 Excel 或手动添加(**两种模式均必填**) | 必须含「姓名」「身份证号」列;人数 > 0 | 准入名单 |
| ④ 表单 | 选模板或自定义字段 | 至少 1 个字段;必填字段不得全部为空 | 填报字段集 |
| ⑤ 材料 | 材料清单、命名模板、体积上限、压缩档位 | 至少 1 项材料;命名模板必须含"姓名""证件号""材料名" | 材料规则集 |
| ⑥ 审核流 | 是否启用班主任层、驳回次数上限、超时小时数 | 学校模式默认启用;社会模式默认关闭 | 审核规则 |
| ⑦ 预览发布 | — | 试跑至少 1 条样本文件名,确认命名结果正确 | 二维码 / 链接 |
**关键逻辑点**
- 第 ⑦ 步必须有"**命名规则试跑**":管理员粘贴几条学生可能的原始文件名,系统立即演示会被改成什么,确认无误才能发布。这是防止"规则配错导致全员改名错误"的唯一闸门。
- 每一步都可保存为草稿,中途退出不丢失。
- 已发布的任务修改配置时:**表单与材料规则的新改动只对新提交生效**,已提交的数据不受影响(避免数据错乱)。
- 任务支持"克隆":复制配置与名册,**不复制任何已上传的文件**。
### 3.3 名单逻辑
> 🔒 **铁律**:**两种收集模式(学校 / 社会)都必须先导入名单**,名单是唯一的准入依据。
> 初稿曾允许"社会收集可不导名单、自由填报",本版已废除。
**触发**:管理员在上传名单步骤选择 Excel 文件。
**处理步骤**
1. **定位表头**:不假设第 1 行是表头。系统从前 10 行中自动寻找包含"姓名""身份证"等关键词的行作为表头(真实模板第 1–5 行是说明文字,**第 6 行才是表头**)。
2. **字段映射**:自动匹配标准字段(姓名、身份证号、手机号、学号、班级、专业等),无法自动识别的列由管理员手动指定或忽略。**「姓名」与「身份证号」为必填列**(缺任一列则无法用于门禁核验,必须补齐后才能发布任务)。
3. **逐行体检**(导入前),生成《导入体检报告》:
- 身份证号格式与校验位是否通过
- 姓名是否为空、是否有重复
- 同一证件号是否重复出现
- 手机号格式
4. **按体检结果决定**:有致命问题(如证件号重复、校验位失败)→ 提示管理员确认后仍可导入,但问题行被标记。
5. **建立名单**:证件号通过哈希去重存储,界面展示时脱敏(如 `3601**********1234`)。
6. **发布前校验**:任务发布前必须确认名单人数 > 0 且姓名/身份证号列完整,否则不允许发布。
**输出**:名单列表 + 体检报告(可下载)。
**异常分支**
| 情况 | 处理 |
|---|---|
| 找不到表头行 | 提示"未识别到表头,请检查 Excel",并允许手动指定行号 |
| **缺少「姓名」或「身份证号」列** | 🔴 阻断发布:"名单必须包含姓名和身份证号才能开启填报核验" |
| 模板被学生自行修改过(多列、少列、换表头) | 以字段映射向导兜底,不强行报错 |
| 名单里有人实际不报名 | 管理员可"移出应填名单",状态记为已移除,不计入完成率 |
| 名单导入后发现漏人 | 支持追加导入,按证件号去重合并;**追加后新人即可立即填报** |
| 名单项始终无人认领 | 不影响任务完成率统计口径(完成率 = 已提交 / 名单有效人数) |
**名册变更留痕**:任何姓名/证件号的修改都必须记录"谁在何时把 X 改成 Y",并在审核界面可见。
### 3.4 表单填写逻辑
**触发**:填报人通过名单门禁后进入填报页。
**表单来源**:任务所属**评价计划** + 任务表单配置。默认套用官方《考生线下报名信息导入模板》的 21 字段(详见主 PRD §5.4.1)。
**处理步骤**
1. **字段三类规则**(⚠️ 最关键:决定了学生端要填多少字)
实测老师交上来的名单里,**21 个字段已填满 18 个**。因此学生端的字段按三类呈现:
| 类别 | 字段 | 学生端行为 |
|---|---|---|
| 🔒 **锁定** | 姓名、身份证号、**报考职业、报考工种、报考等级** | **只读不可改**。名单为空 → **阻断任务发布**(这三项必须由老师确定)。学生要改只能找老师 |
| ✏️ **预填可改** | 学历、是否在校生、在读学校、所学专业、入学时间、工作单位、联系电话、是否补考、补考科目、本职业工作年限、已获证书相关 | 名单有值 → 预填并标注"**老师已填,请核对**",学生可直接修改(留痕);名单为空 → 学生必填 |
| 📄 **材料** | 一寸照片、身份证、学籍表、工作证明等 | 学生上传(**学生唯一的重活**) |
> 💡 实测数据说明为什么"锁定"是必要的:整班 28 人的报考三项**完全一致**(车工/数控车工/四级中级工)——这是老师根据机构要求统一定的。**让学生去选只会制造错误。**
> 💡 实测数据也说明为什么其余字段该允许改:联系电话有 28 个不同值、入学时间可能记错——**允许学生自己改正比回退给老师更高效**。
>
> 📦 **存储说明**:这 18 个业务字段(除姓名/身份证号外)在名单表和填报单表里都是**正式列**(不是 JSON),因此"按工种统计报名人数""按学历筛选"这类查询可直接走索引。只有机构额外追加的字段才进 `extras_json`。详见主 PRD §7.3。
2. **报考范围的一致性体检**(在学生填报之前完成)
系统从名单聚合出本期范围时,会做一次体检:
- 同一职业下出现互相矛盾的工种 → 提示老师确认
- 等级与该工种常规设置不符 → 提示
- 与参考字典拼写不符("数控车床工" vs "数控车工")→ 提示
- 有人三项为空 → 🔴 阻断发布
> 单看一行都合法,但"38 人报数控车工、2 人报车工"很可能是填错——**这类问题只有聚合后才能发现**。
3. **选择范围先收窄**(⚠️ 源自官方规则 04/05/06)
「报考职业 / 报考工种 / 报考等级」三项**不是自由选择**,而是限定在**本期报考范围**内:
```
本期范围 → 只列出范围内的职业
↓ 选中职业
只列出该职业范围内的工种(该职业无工种 → 只能填"无")
↓ 选中工种
只列出该工种范围内的等级
```
⇒ **从源头杜绝填错**,而不是提交后报错。
> 注:实测官方 Excel 模板里「报考职业」「报考工种」**根本没有下拉**(21 列中 13 列自由填写)——**这正是本系统相对模板的核心增量**。
4. **条件显示(级联)**:官方模板用**绿色标题**标识级联列,共两组:
| 触发字段 | 值 | 级联行为 |
|---|---|---|
| **是否补考** | 是 | 按等级放开补考科目(见第 5 条) |
| **是否补考** | 否 | 补考理论 / 实操 / 综合 **全部隐藏且不校验** |
| **是否在校生** | 是 | 在读学校 / 所学专业 / 入学时间 **三项显示且必填** |
| **是否在校生** | 否 | 上述三项**隐藏且不校验** |
> 隐藏的字段不参与必填校验,也不出现在导出结果中。
5. **补考科目数量约束**(官方规则 07,**最容易做错**)
| 认定类型 / 等级 | 最多可选科目数 | 可选项 |
|:--:|:--:|---|
| **专项职业能力** | **0** | 无补考 |
| 三 / 四 / 五级 | **1** | 补考理论、补考实操 中选一个 |
| 一 / 二级 | **2** | 补考理论、补考实操、补考综合 中最多选两个 |
⇒ 达到上限后,其余科目选项**置灰不可选**(而不是事后报错)。
6. **专项职业能力的整体降级**:`认定类型 = 专项职业能力` 时,**工种、等级、补考三项全部隐藏**,官方规则 05/06/07 整体跳过。
7. **下拉严格受限**:官方规定"**若手动输入则只能填写下拉选项中包含的值**"。
⇒ 移动端一律用选择器;PC 端允许输入但做**严格值匹配**,不在选项内的值直接拒绝。
8. **"无"是合法值,不是空值**(⚠️ 实现陷阱)
- 工作单位没有 → 填"无"
- 报考工种该职业没有 → 填"无"
- ⇒ 必填校验时 **"无"算已填**;做单位统计、去重时**不能把"无"当成真实单位名**。
9. **格式校验**
- 联系电话:11 位数字
- 入学时间:**必须 YYYY-MM-DD**
- 本职业工作年限:**只能阿拉伯数字**(0、1、2…)
10. **实时校验**:每个字段失焦即校验,立即反馈,不等到提交时集中报错。
11. **草稿自动保存**:每 10 秒或字段变更后保存;断网时暂存本地,恢复网络后补传。
12. **跨任务记忆**:同一人第二次填报自动带出上次信息(仅本租户内)。
13. **提交前总校验**:汇总所有问题,分三类呈现
- 🔴 阻断项:必须处理才能提交
- 🟡 警告项:可勾选"我已确认"后继续
- 🟢 通过项
**输出**:提交成功 → 进入待初审/待终审;或显示阻断清单。
**异常分支**
| 情况 | 处理 |
|---|---|
| 填报中途退出 | 草稿保留,重新进入时提示"继续上次填写" |
| 提交时网络中断 | 提示"提交未成功,已保存草稿",不做"假成功" |
| 同一账号在两台设备同时填 | 以最后保存的版本为准,并提示"你的内容在另一台设备上被修改过" |
| 提交后又想改 | 未进入审核前可"撤回";已进入审核需联系老师驳回 |
| **报考范围已关闭**(认定机构批次结束) | 提示"本批次已结束",不允许新建填报单;已提交的不受影响 |
| **学生发现自己的报考职业/工种/等级不对** | 提示"该三项由老师统一确定,请联系老师修改",**不允许自行输入** |
| **选了"专项职业能力"却想填工种/等级** | 该三项不显示;若历史数据带出旧值,自动清空 |
### 3.5 材料上传与材料识别逻辑
#### 3.5-A 上传流程
> ⚠️ **重要修正(V1.2)**:**不提供"直接拍照"入口。**
> 复核 4 类材料的真实来源后发现,**没有一类是"现场拍照"产生的**:
>
> | 材料 | 真实来源 | 实测证据 |
> |---|---|---|
> | 学籍表 | 教务系统**屏幕截图** | 28 张均为约 1025×590 的 16:9 截图 |
> | 工作证明 | **扫描仪扫描件**(多在打印店完成) | 28 张均为 1208–1352 dpi 的 A4 扫描图 |
> | 一寸照片 | **照相馆拍摄后的电子版** | 27/28 张尺寸完全一致(984×1378) |
> | 身份证 | 既有扫描件或翻拍件 | 尺寸跨度 558×745 ~ 2216×2796,来源不一 |
>
> 现场拍照只会引入模糊、畸变、反光、阴影问题,**反而制造返工**。填报入口必须是"**选择已有文件**"。
**触发**:填报人在某个材料项上点击"选择材料"。
**四种来源通道(按实际使用频率排序)**
| # | 通道 | 适用材料 | 说明 |
|---|---|---|---|
| 1 | **从微信聊天记录选择** | 全部(**主力通道**) | 学生从照相馆、打印店、老师、家人处收到的文件,通常就躺在聊天记录里 |
| 2 | **从手机相册选择** | 学籍表截图、已有的翻拍件 | 手机截图会自动存入相册 |
| 3 | **从聊天记录 / 手机文件选择** | 扫描件 PDF、Word 版申报表 | 需要选中"文件"类型而非"图片"类型 |
| 4 | ~~直接拍照~~ | **默认关闭** | 材料级可配置开启(例如某批次允许现场补拍身份证),但默认不提供 |
**两条关键设计逻辑**
**① 必须保留原始文件名(极其重要)**
- 从**聊天记录**选择文件时,微信会返回该文件的**原始名称**(例如 `张三-360121200010101234-工作证明.jpg`);
- 从**相册**选择图片时,拿不到文件名(通常是 `IMG_0001.jpg`)。
⇒ 系统必须优先使用前者。**文件名本身就是最有价值的信息**——命名规范化引擎(§3.6)能直接从文件名中读出姓名、证件号、材料类型,准确率远高于从无名截图里靠 OCR 猜。
⇒ 产品层要提示用户:"**优先从聊天记录里选**,因为文件名里带着你的信息,系统能自动帮你填。"
**② 支持一次多选**
身份证正反面、多页材料允许一次选多张,减少重复操作。
**③ 来源引导(每个材料项都要给)**
| 材料 | 引导文案 |
|---|---|
| 一寸照片 | "照相馆给过你电子版吗?在微信聊天记录里搜一下" |
| 工作证明 | "打印店扫描后会发给你,从聊天记录里选" |
| 学籍表 | "教务系统截图后,从手机相册里选" |
| 身份证 | "拍过的照片或者扫描件都可以,从聊天记录或相册里选" |
**处理步骤(一次上传的完整生命周期)**
```
点击"选择材料"
↓ 弹出来源选择:微信聊天记录 / 手机相册 / 手机文件
↓ 选中文件(可多选)
↓ 【客户端】只做三件事:
↓ ① 记录原始文件名(若来源支持)
↓ ② 方向校正
↓ ③ 尺寸限幅(长边 ≤2400px)
↓ 不做有损质量压缩(原因见 §3.7.6 二次有损防护)
↓ 上传到存储(显示进度;支持断点续传)
↓ 【服务端】形态识别 → 选定压缩档位
↓ 命名规范化(§3.6)
↓ 压缩到目标体积(§3.7)
↓ 格式转换(如需)
↓ 校验(§3.8)
↓ 必要时 OCR 识别并回填
↓ 返回处理结果
填报人看到结果卡片:
┌─────────────────────────────────────────┐
│ 原名:曾伊豪-361029200907295110身份证.jpg.jpg │
│ 已规范为:曾伊豪-...-身份证.jpg │
│ 体积:17.1MB → 512KB ✅ │
│ 校验:通过 ✅ │
└─────────────────────────────────────────┘
```
**输出**:材料项状态变为"已受理/有警告/有阻断",并附上处理前后对比。
**异常分支**
| 情况 | 处理 |
|---|---|
| 上传中断 | 断点续传;已传部分不重复上传 |
| 格式不在白名单 | 提示支持的格式,并说明"建议用 JPG" |
| 从聊天记录选文件时超出微信单文件体积限制 | 提示改为"从相册选那张图片",并说明聊天中收到的图片可选择非原图版本(体积更小)。**各通道的实际体积上限需在开发期实测确认** |
| 聊天记录里找不到该文件(过期/被清理) | 提示替代方案:请对方重新发送 / 从手机文件里找 / 联系老师代传 |
| 从相册选的图片没有文件名(`IMG_0001.jpg`) | 无法从文件名提取信息 → 走 OCR 识别回填,并在界面提示"这张图没有名字信息,请确认归属" |
| 文件来自"文件传输助手" | 正常处理,文件名可保留 |
| 选中的是压缩过度的聊天图片(微信默认会压缩图片) | 检测分辨率是否偏低,若低于建议值则提示"这张图可能被压缩过,建议让对方发原图" |
| 文件过大(>50MB) | 提示"文件过大,请让对方重新发送一份清晰的扫描件" |
| 处理超时 | 转后台异步处理,页面显示"处理中",完成后推送通知 |
| 处理失败 | 保留原图,标记失败原因,允许一键重试;不丢弃用户已上传的内容 |
| 上传了错误的材料(如把身份证传到照片项) | 依靠 OCR 内容比对提示"这张看起来不是身份证",并允许一键移动到正确材料项 |
| 重复上传同一材料 | 保留历史版本,默认取最新;旧版本可回溯 |
#### 3.5-B 材料识别(这是什么材料)
> **决策(方案 B)**:**规则为主 + 视觉大模型兜底。** 先用零成本规则判断,只在"规则判不准"或"与用户声明冲突"时才调用视觉大模型。
**📊 实测验证结果(2026-09-24,用 112 个真实文件 + 32 个 OCR 抽样)**
| 层 | 方法 | 实测结果 | 成本 |
|---|---|---|---|
| **第 1 层 文件名** | 别名表匹配 | **112/112 = 100%** | 0 |
| **第 2 层 形态** | 粗分流派 | **111/112 = 99.1%** 能正确分流派,但**流派内无法定型** | 0 |
| **第 3 层 内容 OCR** | 强词计分 + 零文字判据 | **32/32 = 100%**(4 类材料各 8 个) | OCR(本来就要做) |
| 第 4 层 VLM | 兜底 | 触发率 **2%~10%**(重估) | 按次 |
**OCR 耗时实测**(CPU,图片降采样至 2000px)
| 材料 | 耗时 | 文字量 |
|---|---|---|
| 一寸照片 | 0.1–0.3s | 0 字 |
| 身份证 | 0.9–1.6s | 107–138 字 |
| 学籍表 | 1.0–1.4s | 265–269 字 |
| 工作证明 | 3.5–4.9s | 702–755 字 |
**本次验证发现并修正的两处设计错误**
| # | 初版设计(错) | 实测真相 | 修正后 |
|---|---|---|---|
| 1 | 身份证宽高比 ≈ 1.585,可按形态直接判定 | 实际 **0.732–1.016**,与一寸照片 0.714 **高度重叠** | 形态层降级为"只分流派" |
| 2 | OCR 关键词"命中任一即判定" | 关键词**大量交叉命中**(工作证明里含"学籍/学校",学籍表里含"居民身份证") | 改为**只用强词 + 加权计分取最高** |
**⚠️ 本次验证的局限性(必须在开发期补测)**
1. **文件名 100% 是"有偏测试"**——这 112 个文件是老师**已经规范命名过**的;真实收集中学生传来的文件名更乱,准确率必然更低;
2. OCR 抽样仅 32/112,未覆盖全部文件;
3. 未覆盖的困难场景:**模糊件、翻拍反光、非标准材料**(学信网备案表、其它佐证材料在本数据集中不存在);
4. 上述结果**不能直接当作线上准确率承诺**,只用于验证架构方向。
**要解决什么问题**
| # | 场景 | 问题 |
|---|---|---|
| 1 | 填报上传 | 用户在"身份证"槽位传了学籍表 → 需要发现并提示 |
| 2 | 整理器散图分拣 | 一堆没有目录的散图 → 需要判断每张是什么,才能归入目录 |
| 3 | 审核辅助 | 班主任想快速确认"这堆材料里有没有传错的" |
| 4 | 缺失检测兜底 | 例如"其它佐证材料"传了 3 张,需要区分它们分属什么 |
**四路信号**
| 信号 | 内容 | 可靠性 | 成本 |
|---|---|---|---|
| **S1 槽位** | 用户在**哪个材料项**上传的(用户声明) | 高,但**用户可能传错** | 0 |
| **S2 文件名** | 原始文件名里的材料名(如 `...-工作证明.jpg`) | **最可靠**(前提是聊天记录来源) | 0 |
| **S3 形态** | 宽高比、像素量、DPI、是否有大面积红色(印章) | 中(拍歪、裁图后会失效) | 极低(只读头部) |
| **S4 内容** | OCR 文字关键词、版面特征 | 高 | OCR 已在做,无额外成本 |
**🔑 一个必须记住的前提:不是所有材料都有文字。**
一寸照片**完全没有文字**,只能靠形态(5:7 比例、纯色背景、人脸居中)判断。因此**不能因为"没识别出关键词"就判定材料错了**。
**规则层判定(必跑,零成本)**
**① 文件名规则**(最强信号)
- 用材料别名表(§3.6)做最长匹配
- 命中 → 直接定为该材料,置信度 **0.95**
**🔧 三层递进架构(实测校正后的最终设计)**
> ⚠️ **本文档初版把形态层写成"直接判定材料类型",实测证明是错的。** 正确架构如下:
```
第 1 层 文件名 → 能定死就定死(准确率实测 100%,零成本)
↓ 判不出
第 2 层 形态 → 【只分流派,不材料定型】
↓ 流派内还有多个候选
第 3 层 内容(OCR) → 在流派内定死(准确率实测 100%)
↓ 仍判不出
第 4 层 VLM → 兜底(实测触发率仅 2%~10%)
```
**第 1 层:文件名规则**(最强信号)
- 用材料别名表(§3.6)做最长匹配
- 命中 → 直接定为该材料,置信度 **0.95**
- ⚠️ 前提是来源为**微信聊天记录**(可保留原始文件名);相册来源拿不到文件名
**第 2 层:形态规则 —— 只分流派(关键修正)**
| 形态流派 | 判定特征(实测标定) | 该流派内的候选材料 | 定型靠什么 |
|---|---|---|---|
| **A4 扫描件流** | 像素量 > **2000 万**(实测 1.44~1.81 亿) | 工作证明 / 申报表 / 备案表 | 内容层 |
| **宽屏截图流** | 宽高比 **1.60~1.90**(实测 1.689~1.758) | 学籍表 / 学信网备案表截图 | 内容层 |
| **竖版小照片流** | 宽高比 **0.60~1.05**,像素 < 2000 万(实测 0.714~1.016) | **一寸照片 / 身份证翻拍** ← 混合! | 内容层 |
| 未判定 | 其他 | — | VLM |
> ❌ **本文档初版写的"身份证 宽高比 ≈1.585(85.6:54)"是错的。**
> 实测:真实身份证件是**竖版/近方拍摄**,宽高比 **0.732~1.016**,与**一寸照片的 0.714 高度重叠**,像素量也重叠(416K~6196K vs 1356K~3378K)。
> ⇒ **形态层根本无法区分「一寸照片」和「身份证」**,必须交给内容层。这是本次验证最重要的结论。
**第 3 层:内容规则(OCR 关键词加权计分)**
> ❌ **本文档初版写的"命中任一关键词即判定"是错的。**
> 实测发现**关键词大量交叉命中**:工作证明里同时出现"学籍/学校/入学/专业/姓名",学籍表里也出现"居民身份证",身份证里也出现"学校/姓名"。
> ⇒ 必须**只用高唯一性强词 + 加权计分取最高**,通用词(姓名/学校/专业/出生/单位/本人)全部剔除。
| 材料 | **强特征词**(权重 ×3) | 实测得分 |
|---|---|---|
| 身份证 | 公民身份号码 / 签发机关 / 有效期限 / 居民身份证 | 9~12 |
| 学籍表 | 学籍 / 学籍号 / 学籍状态 / 学籍证明 | 6(另有身份证噪声 3) |
| 工作证明·申报表 | 职业技能等级认定 / 个人申报表 / 申报表 / 兹证明 / 技能等级 | 12(另有学籍表噪声 3) |
| **一寸照片** | ——(**零文字**,见下) | 9 |
**🔑 一寸照片的"零文字"判据**
实测 8/8 张一寸照片 **OCR 文字量为 0**(真实证件照没有任何文字)。
⇒ 规则:**整图文字量 < 5 字 → 判定为一寸照片**(结合竖版小照片流派)。
这是整个识别体系里**最干净的信号**,比任何关键词都可靠。
**判定规则**
```
对每个候选材料算分:分数 = 3 × (命中的强词数)
若整图文字量 < 5 字 → 一寸照片得 9 分
取最高分者为识别结果;全部为 0 分 → 交 VLM
```
> 📌 强词表**必须可配置**(每个租户/机构材料名与措辞不同),并提供"从历史文件自动学习候选强词"的辅助功能。
> 📌 学信网备案表、其它佐证材料等**当前数据集未覆盖**,需在新批次数据上补充标定。
**④ 印章检测**(辅助信号)
扫描件上大面积红色像素区域 → 提示"疑似盖章文件"。仅作辅助,不能单独定论。
**判定与置信度**
```
置信度 ≥ 0.90 → 直接采信识别结果
置信度 0.70–0.90 → 采信但标记,界面提示用户确认
置信度 < 0.70 → 不判断,以用户槽位为准(不打扰用户)
```
**VLM 兜底触发条件(成本控制的核心)**
只有以下三种情况才调用视觉大模型:
| # | 触发条件 | 理由 |
|---|---|---|
| 1 | 规则层置信度落在 **0.4–0.7**(疑似但不确定) | 值得花钱确认 |
| 2 | 规则识别结果**与槽位冲突** | 这是最需要判断的场景(防传错) |
| 3 | **散图分拣**且规则层无法判定 | 没有槽位可参考,只能靠内容 |
**不触发 VLM 的情况(占绝大多数,零成本通过)**
- 规则层置信度 ≥ 0.9(文件名清楚 / 关键词明确)→ 直接定
- 槽位与识别结果一致 → 无需二次确认
- 规则层置信度 < 0.4 且无冲突 → **不值得花钱**,直接放行
- 一寸照片等纯形态材料 → 靠形态规则即可(比例特征极其稳定)
**成本预估(已按实测重估)**
| 方案 | 调用量(按 48 万文件/学期) | 相对成本 |
|---|---|---|
| 全部走 VLM | 48 万次 | 100% |
| **本方案(规则为主 + 兜底)** | **约 1~4.8 万次** | **约 2%~10%** |
| 只用规则 | 0 次 | 0%(但模糊件判不出) |
**实测触发率(按"聊天记录来源占比"推算)**
| 聊天记录来源占比 | VLM 触发率 | 48 万文件的调用量 |
|---|---|---|
| 90% | **2.0%** | 约 1.0 万次 |
| 80% | **4.0%** | 约 1.9 万次 |
| 70% | **6.0%** | 约 2.9 万次 |
| 50% | **10.0%** | 约 4.8 万次 |
> ✅ **勘误**:本文档初版预估"触发率约 15%",**实测重估为 2%~10%**。
> 初版之所以偏高,是因为形态规则写错(把身份证误判为一寸照片)产生了大量**假冲突**,从而错误触发 VLM。
> 修正形态规则后,冲突大幅减少,成本也随之下降 60%~85%。
>
> ⚠️ 上表的"相册来源中 20% 需 VLM"为保守假设,需在开发期用真实数据实测标定。
**冲突裁决表(核心规则)**
| 用户槽位(声明) | 识别结果 | 置信度 | 系统动作 | 用户看到 |
|---|---|---|---|---|
| A | A | 任意 | ✅ 通过 | 无感 |
| A | **B** | ≥ 0.9 | 🟡 **提示 + 一键移动** | "这张看起来是**学籍表**,不是身份证。要移过去吗?" |
| A | B | 0.7–0.9 | 🟡 软提示,不强制 | "这张不太像身份证,请确认一下" |
| A | B | < 0.7 | 放行 | 无感 |
| A | 无法识别 | — | 放行 | 无感 |
| **无槽位**(散图) | A | ≥ 0.9 | ✅ **自动归入** | — |
| 无槽位 | A | 0.7–0.9 | 建议归入,可改 | "建议归到「学籍表」" |
| 无槽位 | 无法识别 | — | 进入「待人工归属」 | 拖拽归位界面 |
**🔒 三条不可违背的原则**
1. **只提示,不自动改位置(散图除外)**
识别必然有误判。**自动改位置比传错更危险**——它会把用户原本放对的文件挪走。唯一的例外是散图分拣:那里本来就没有位置,自动归入是无害的。
2. **识别结果不覆盖用户的声明**
即使用户把身份证传到了"学籍表"槽位,系统也只是提示;最终位置由用户决定。
3. **识别不出 ≠ 材料错**
新材料类型、无文字的图片、模糊件都可能识别失败。**识别失败一律放行**,不得阻断提交。
**集成点**
| 场景 | 时机 | 动作 |
|---|---|---|
| 填报上传 | 每次上传后(异步) | 冲突时提示 + 一键移动 |
| 提交前总校验 | 提交时 | 汇总"疑似传错"清单,按 🟡 警告呈现 |
| 整理器·散图分拣 | 无目录结构时 | 自动归属;判不出的进待人工归属 |
| 整理器·体检报告 | — | 输出"疑似错位"清单 |
| 审核辅助 | 班主任查看时 | 材料卡片上显示"系统判定:身份证 92%" |
| 规则优化 | 定期 | 用人工纠正确认的结果反哺关键词表 |
**异常与降级**
| 情况 | 处理 |
|---|---|
| OCR 服务不可用 | 降级为仅文件名 + 形态判定,不阻断 |
| VLM 超时(>5s)或失败 | 放弃识别,以用户槽位为准,放行 |
| 图片无法解码 | 交压缩模块报错处理 |
| 遇到系统中不存在的新材料类型 | 不判断,放行 |
| 同一文件被识别为多个材料且置信度接近 | 归入"待确认",提示用户选择 |
**性能要求**
- 识别为**异步**执行,**不阻塞上传与提交**;
- 规则层(含关键词匹配)单文件 ≤300ms;
- VLM 兜底 5s 超时,超时即放弃。
### 3.6 命名规范化逻辑
**目标**:无论填报人交上来什么名字,系统都输出 `姓名-证件号-材料名.后缀`。
**处理步骤**
| 步骤 | 做什么 | 关键判断 |
|---|---|---|
| 1 | 剥离扩展名 | 循环剥离,直到没有已知扩展名为止(解决 `.jpg.jpg`) |
| 2 | 提取证件号 | 从文件名中找出最长的 15–18 位号码片段 |
| 3 | 证件号归一化 | 补齐位数、末位 `x` 统一为大写;位数不足或校验不通过时启动裁决(见下) |
| 4 | 材料名识别 | 用材料别名表做最长匹配("在职证明""工作证明扫描件"→ 统一为"工作证明") |
| 5 | 姓名识别 | 取剩余的中文串;与名册比对,做形近字/同音字纠错 |
| 6 | 组装 | 按模板拼接,清理非法字符,重名自动加序号 |
| 7 | 标记 | 标注本次是"全自动""已修复""待确认"还是"需人工" |
**证件号争议裁决表(核心规则)**
| 文件名中的号 | 名册中的号 | 判定结论 | 系统动作 |
|---|---|---|---|
| 校验通过 | 校验通过 | 两个都是真实有效号码 → **疑似两人材料** | 🔴 不自动改,必须人工确认(串档) |
| 校验**不通过** | 校验通过 | **文件名写错了** | ✅ 自动按名册改正 |
| 校验通过 | 校验不通过 | 名册可能录错 | 🟡 提示管理员核对名册 |
| 位数不足 / 无法校验 | 校验通过 | 文件名残缺 | ✅ 按名册补齐 + 🟡 标黄供确认 |
| 名册中查无此人 | — | 非本任务人员 | 转"待认领"队列 |
> 这条规则的价值:把"证件号到底谁对"从**人的判断**变为**算法的判断**。实测 5 个人工疑点中,3 个可自动处理,只有 1 个必须人工。
**姓名纠错规则**
| 情况 | 判定 | 动作 |
|---|---|---|
| 与名册姓名不一致,但只差 1 个字且拼音相同(如"扬晨"↔"杨晨") | 高置信 | 自动改为名册姓名 |
| 与名册姓名不一致,差 1 个字但拼音不同 | 中置信 | 🟡 标黄,由填报人或班主任确认 |
| 与名册姓名完全不一致(如 3 个字都不同) | 低置信 | 🔴 标红,转人工 |
**材料名别名表(可维护)**
| 规范名 | 接受的别名 |
|---|---|
| 一寸照片 | 1寸照片、一寸电子照片、证件照、照片、免冠照 |
| 身份证 | 身份证正反面、身份证扫描件、身份证正面、身份证反面 |
| 学籍表 | 学籍证明、在读证明、学籍卡 |
| 工作证明 | 在职证明、工作证明扫描件、个人申报表、申报表、单位证明 |
| 学信网备案表 | 学信网学历备案表、学历证书电子注册备案表、备案表 |
| 其它佐证材料 | 毕业证书、社保个人权益单、职称证明、技能等级证书、佐证 |
**异常分支**
| 情况 | 处理 |
|---|---|
| 文件名完全无法解析(如 `IMG_20260924_0932.jpg`) | 保留原名 + 标红"需人工";同时提供"手动指定归属"入口 |
| 同一人同一材料出现多个版本 | 版本号递增,默认取最新;旧版本保留可回溯 |
| 规范后与他人重名 | 追加序号(如 `...身份证(2).jpg`),并提示 |
| 材料名与内容不符(如"工作证明"里其实是申报表) | 以规则的规范名为准(机构要求如此),不擅自改名 |
### 3.7 压缩逻辑(扫描件强制 1M)
#### 3.7.1 核心决策
> **D1:所有材料,包括 A4 扫描件,一律强制输出 ≤ 1M。不设例外、不提供体积放宽选项。**
由此确定约束的优先级:
| 约束 | 性质 | 冲突时的取舍 |
|---|---|---|
| 输出体积 ≤ 1M | **硬约束** | 不可协商 |
| 分辨率与清晰度(DPI / 质量) | 软约束 | 冲突时牺牲清晰度,但必须标记 |
| 原始文件保留 | 保障措施 | 始终保留 30 天,用于复核与重出 |
> ✅ **重大实测结论(2026-09-24,用 28 张真实扫描件完整实测)**
>
> **"体积 ≤1M" 与 "清晰度" 根本不冲突。** 按 A4 等比缩放至标准扫描分辨率 300dpi(2480×3508)、质量 85 编码:
>
> | 输出参数 | 平均体积 | 最大体积 | 达标情况 |
> |---|---|---|---|
> | 300dpi / q90 | 958 KB | 964 KB | ✅ 28/28(余量仅 6%,不推荐) |
> | **300dpi / q85** | **806 KB** | **831 KB** | ✅ **28/28 ← 默认参数** |
> | 300dpi / q80 | 718 KB | 740 KB | ✅ 28/28 |
> | 300dpi / q75 | 653 KB | 673 KB | ✅ 28/28 |
> | 400dpi / q80 | 1070 KB | 1078 KB | ❌ 全部超标 |
>
> **结论:**
> 1. 输出的是**标准 300dpi 扫描件**,清晰度**零损失**,认定机构没有正当理由拒收。
> 2. 整班 444MB → **22MB**,压缩率 **95%**;单张处理约 2 秒。
> 3. 下文 3.7.3 的"逐级降质"路径**作为兜底保留,但预计 100% 不会触发**。
> 4. §3.7.4 的"清晰度牺牲标记 + 人工抽检"机制**实测中不会产生任何待抽检文件**,作为极端情况的安全网保留。
>
> 📌 参数可随实际情况调整:若某些批次扫描件内容更复杂(如满页手写、彩色底纹),系统会自动进入兜底路径,无需人工干预。
#### 3.7.2 材料形态识别与档位
系统先识别材料属于哪种物理形态,再套用对应策略(**不能对所有图片用同一把尺子**):
| 档位 | 形态 | 典型材料 | 尺寸策略 | 输出格式 |
|---|---|---|---|---|
| P1 证件照 | 标准证件照(比例 5:7) | 一寸照片 | **固定 295×413 px** | JPG |
| P2 证件翻拍 | 手机翻拍(有透视变形) | 身份证、备案表 | 长边控制在 1400–2400 px | JPG |
| P3 扫描件 | **A4 纸张扫描件**(超高像素) | 工作证明、申报表 | **按 A4 等比缩放,用 DPI 控制** | JPG |
| P4 截图 | 屏幕截图(比例接近 16:9) | 学籍表 | **保持原始像素,不缩放** | **PNG** |
| P5 文档 | PDF / Word | 各类文档 | 页面重采样 | PDF |
**形态自动判定依据**:像素总量、宽高比、格式、压缩特征。判定置信度低时,回退到管理员为该材料指定的档位。
#### 3.7.3 压缩执行顺序(关键逻辑)
压缩有两个可调旋钮:**采样率(尺寸)** 和 **编码质量**。二者的使用顺序**按形态区分**:
| 形态 | 顺序 | 原因 |
|---|---|---|
| **文字类(P3 扫描件 / P4 截图)** | **先降采样,后降质量** | 文字与印章是"高对比边缘"。质量降低会在笔画边缘产生锯齿状噪点(JPEG 伪影),直接破坏可读性;而等比重采样是可控的平滑,对文字更友好 |
| **照片类(P1 证件照 / P2 翻拍)** | **先降质量,后降采样** | 人脸细节对重采样敏感(一缩放就"糊脸"),对轻度质量下降反而不敏感 |
**P3 扫描件的完整压缩路径(一次编码到位)**
```
1. 形态确认为 A4 扫描件
2. 判断是否需要先做安全降采样(像素过大时先降到安全区,见 3.7.5)
3. 方向校正 + 色彩统一 + 剥离隐私信息(GPS、设备型号)
4. 用默认参数直接编码一次:
A4 等比缩放至 300dpi(2480×3508),JPEG 质量 85
5. 测量输出体积:
≤ 1M → 直接输出,结束 ← 实测本批 28/28 走这条
> 1M → 进入兜底路径(第 6 步)
6. 兜底路径(预计极少触发;参数按形态区分顺序):
300dpi/q80 → 300dpi/q75 → 300dpi/q70
→ 240dpi/q80 → 200dpi/q80 → 180dpi/q75 → 150dpi/q70
→ 120dpi/q65 → 继续降采样直至达标
7. 写回清晰度等级(见 3.7.4)
```
**实测参考值(A4 扫描件,JPEG 编码)**
| 输出 DPI | 质量 | 平均体积 | 结论 |
|---|---|---|---|
| 300 | 90 | 958 KB | ✅ 达标但余量小,不采用 |
| **300** | **85** | **806 KB** | ✅ **默认参数** |
| 300 | 80 | 718 KB | ✅ 备选 |
| 300 | 75 | 653 KB | ✅ 备选 |
| 400 | 80 | 1070 KB | ❌ 超标,不可用 |
| 500 | 80 | 1452 KB | ❌ 超标,不可用 |
> 📌 与初始推算的差异:本文曾推算"要压进 1M,A4 扫描件只能取 150–170dpi",**该推算错误**。
> 原因是文档扫描件以白底为主、内容稀疏,压缩率远高于照片(照片的 1M 上限确实需要大幅降质,文档不需要)。
#### 3.7.4 清晰度标记与人工抽检
**这是"强制 1M"的必要配套机制**——既然存在有损的可能,就必须让人知道哪些文件损了。
> ✅ **实测说明**:在 28 张真实扫描件上,默认参数(300dpi/q85)**全部直接达标**,因此**不产生任何 🟡 或 🔴 文件**。本机制作为极端情况(满页手写、彩色底纹、内容极复杂)的安全网保留,不会给班主任增加日常负担。
系统为每个文件打一个清晰度等级:
| 等级 | 判定条件 | 系统动作 |
|---|---|---|
| 🟢 优 | DPI ≥ 200 且质量 ≥ 75 | 直接通过 |
| 🟢 良 | DPI 150–200 | 通过 |
| 🟡 可 | DPI 120–150 | 通过 + 进入**抽检清单** |
| 🔴 强制压缩 | DPI < 120,或触达质量地板 | 通过 + **必须人工确认** + 界面醒目标记 |
**抽检机制**
1. 每个任务生成一份《压缩质量抽检清单》,列出所有 🟡 与 🔴 文件。
2. 班主任/管理员在审核界面可**一键只看这些文件**。
3. 抽检认为不可接受的,可驳回要求重传(并提示"请用手机拍摄而非扫描仪扫描")。
4. 抽检结论回写到文件记录,用于后续参数优化。
#### 3.7.5 超大图的保护逻辑
真实数据中存在 1.6 亿像素的扫描件(约 1272dpi A4)。这类图片如果不做保护,会直接拖垮服务器。
**保护规则**
1. 处理前先只读取图片的头部信息取得宽高,**不解码像素**。
2. 像素数超过 5000 万 → 先做一次流式降采样到安全区,再进入正常流程。
3. 单个文件处理超过 20 秒 → 中断并转入后台队列,页面显示"处理中"。
4. 单文件像素上限 2 亿、体积上限 50MB,超出直接拒绝并提示。
5. 内存与并发:图片处理占用的内存远大于 CPU,因此**并发数按内存反推设定**,不能按 CPU 核数设定。
#### 3.7.6 二次有损防护
**问题**:如果客户端先压一次、服务端再压一次,图片会被"有损压缩两遍",清晰度损失远大于一次到位。
**规则**
1. **客户端只做无损操作**:方向校正 + 尺寸限幅,不做有损质量压缩。
2. **最终编码由服务端一次性完成**,参数只在服务端确定。
3. 服务端检测到"该图已被明显有损压缩过"(如体积远小于同尺寸的合理值)时,**不再压缩**,只做格式与命名处理,并标记"疑似过度压缩"。
#### 3.7.7 其他材料的压缩逻辑
| 材料 | 处理 |
|---|---|
| 一寸照片(P1) | 先降质量(85→80→76→72),触底后按比例缩尺寸;**最终统一输出 295×413 px** |
| 身份证(P2) | 长边压到 2400px 以内但不得低于 1400px;**低于 1400px 的原始图不压缩,标记"分辨率不足"** |
| 学籍表(P4) | **保持原始像素,输出 PNG**,仅做无损优化;不缩放、不转 JPG(转 JPG 会让文字边缘发虚) |
| 图片本身已 <1M | 仅做命名规范化与格式确认,**不重新压缩**(避免无谓降质) |
| 图片体积过小且分辨率过低 | 标记"疑似过度压缩",提示重传(**体积小不等于合格**) |
#### 3.7.8 失败与异常
| 情况 | 处理 |
|---|---|
| 压缩后仍 >1M 且已触达下限 | 继续降采样直至达标(强制路径),标记为强制压缩 |
| 图片损坏 / 无法解码 | 保留原图,提示"文件无法识别,请重新上传" |
| 输出体积异常小(如 30KB) | 标记"疑似过度压缩",进入抽检 |
| 处理超时 | 转后台异步,不阻塞用户 |
| 用户重传同一材料 | 以新版本重新走完整流程,旧版本保留 |
### 3.8 校验逻辑
**校验的三层呈现**:🔴 阻断(不可提交)/🟡 警告(可提交但需确认)/🟢 通过。
| 编号 | 规则 | 触发时机 | 级别 | 反馈给谁 | 系统动作 |
|---|---|---|---|---|---|
| V1 | 身份证号格式与校验位 | 输入时 / 上传后 | 🔴 | 填报人 | 高亮错误位置,要求核对原件 |
| V2 | 证件号与名册一致 | 输入时 / 上传后 | 🔴 | 填报人 | 展示名册值,按裁决表处理 |
| V3 | 姓名与名册一致 | 输入时 | 🟡 | 填报人 | 给出形近字建议 |
| V4 | **同一人跨材料证件号一致** | 每次上传后 | 🔴 | 填报人 | 标出是哪两份材料冲突 |
| V5 | 材料完整性(必传项) | 提交时 | 🔴 | 填报人 | 列出缺失清单,附上传入口 |
| V6 | 文件格式白名单 | 上传时 | 🔴 | 填报人 | 自动转换或提示重传 |
| V7 | 文件体积上限 | 上传时 | 🔴 | 填报人 | 自动压缩;压不动才提示 |
| V8 | 图片可读性(分辨率过低 / 全黑 / 全白 / 严重模糊) | 上传时 | 🟡 | 填报人 | 提示重新提供(重扫描 / 索取原图) |
| V9 | 重复文件(同一文件被多次上传) | 上传时 | 🟡 | 填报人 | 提示"与 XX 的材料重复" |
| V10 | 身份证有效期是否过期 | OCR 后 | 🟡 | 填报人 | 提示 |
| V11 | 名册内证件号重复 | 名册导入时 | 🔴 | 管理员 | 指出具体行号 |
| V12 | 材料内容与类型不符(如"身份证"位传了风景照) | OCR 后 | 🟡 | 填报人 | 提示疑似传错,提供"移到正确材料项"入口 |
**校验的展示原则**
- 一次性列出全部问题,不做"改一个报一个"的循环;
- 每个问题必须包含三要素:**哪里错、错成什么、怎么改**;
- 阻断项必须给出直达修复的入口(点击跳转到对应字段/材料)。
### 3.9 审核逻辑
**触发**:填报人提交后进入待审队列。
**班主任初审逻辑**
1. 打开待审列表:默认按"异常优先"排序,红黄项排前面。
2. 列表呈现:每行一个学生,含头像、姓名、班级、各材料缩略图、状态色点。
3. **一键批量通过**:只对"全部材料均为 🟢 且无待确认项"的学生生效;任何有红黄项的自动跳过,不允许被批量带过。
4. 逐项审核:查看大图、可对比原图与处理后的图、查看校验问题清单。
5. 处理动作:
- 通过 → 进入待终审
- 驳回 → 必须选择原因(提供常用原因快选),可补充文字
6. 审核超时:超过设定时长未处理,系统每小时提醒一次,并升级通知管理员。
**管理员终审逻辑**
1. 只能看到"初审通过"的填报单。
2. "全部通过"按钮**仅在整批零红黄项时可用**(防止管理员大而化之地放行)。
3. 终审通过后默认锁定,不再允许学生修改。
**驳回逻辑**
1. 驳回必须带原因,原因是结构化选项 + 可选文字补充。
2. 学生收到通知后修改,重新提交,回到**初审**(不是回到终审,除非该单此前已在终审环节被驳回)。
3. 驳回次数累计,达到上限(默认 3 次)自动提醒管理员介入。
4. 驳回记录全部留痕,审核时间轴对学生可见(让学生知道进度)。
**审核行为的边界**
| 情况 | 规则 |
|---|---|
| 班主任帮学生代传材料 | 允许,但记录操作人;审核界面标注"由 X 老师代传" |
| 班主任批量通过后发现有错 | 支持在进入终审前撤回单个学生的通过结论 |
| 审核人变更(换班主任) | 支持转交,历史审核记录保留原审核人 |
| 同一份单被两个人同时审 | 以后提交的动作为准,前面的人收到"该单已被 XX 处理"提示 |
### 3.10 汇总导出逻辑
**触发**:管理员点击"导出"。
**处理步骤**
1. **前置检查**:扫描导出范围内所有文件,若存在"命名未规范 / 体积超 1M / 存在红项未处理"的文件,**直接报错并列出清单**,不允许打包。(对应 §2.4 铁律 2)
2. **范围确定**:默认只导出"已通过终审"的记录;可选按班级、按人员筛选。
3. **目录结构生成**(默认规范,可配置):
```
{批次号}-{任务名}/
├── 24中技数控1班/
│ ├── 一寸照片/ 张三-360121200010101234-一寸照片.jpg
│ ├── 身份证/ 张三-360121200010101234-身份证.jpg
│ ├── 学籍表/ 张三-360121200010101234-学籍表.jpg
│ └── 工作证明/ 张三-360121200010101234-工作证明.jpg
├── 24中技数控2班/
└── 考生线下报名信息导入模板(汇总).xlsx
```
4. **汇总 Excel**:合并所有填报字段,一行一人,并附完成情况。
5. **分卷压缩**:超过设定单包体积(如 50MB)时自动分卷,便于上传与传输。
6. **异步执行**:导出在后台进行,页面显示进度,完成后通知。
7. **有效期**:导出包默认保留 7 天,过期自动清理(避免长期堆积大文件)。
**输出**:可下载的压缩包(分卷)与汇总 Excel。
**异常分支**
| 情况 | 处理 |
|---|---|
| 有文件未通过终审 | 报错并列出名单,提供"仅导出已通过者"的选项 |
| 有文件命名不规范 | 报错并列出,提供"立即修复"入口(一键重新规范化) |
| 导出过程中有人提交新数据 | 以导出任务创建时刻的快照为准,不动态变化 |
| 导出包过大 | 自动分卷;或提示"建议按班级分批导出" |
### 3.11 通知与催报逻辑
**通知渠道优先级**:微信订阅消息(首选)→ 服务号模板消息 → 短信(兜底,计费)。
**触发点与内容**
| 触发点 | 发给谁 | 内容要点 |
|---|---|---|
| 任务发布 | 全体应填人 | 任务名、截止时间、填报入口 |
| 临期提醒 | 尚未提交者 | 剩余天数、未完成项 |
| 提交成功 | 填报人 | 已提交、进入审核 |
| 审核驳回 | 填报人 | 驳回原因、修改入口 |
| 审核通过 | 填报人 | 已通过 |
| 待审提醒 | 班主任 | 有多少人待审、超时人数 |
| 超时升级 | 管理员 | 哪个班主任有单超时未处理 |
| 导出完成 | 管理员 | 下载入口与有效期 |
**催报规则**
1. 自动催报:截至日前 7 天、3 天、1 天、当日各一次,**只催未提交者**,不打扰已完成的人。
2. 手动催报:班主任/管理员可随时对指定人员或"全部未提交者"发起。
3. **频次保护**:同一人同一天最多收到 2 条催报(防止打扰引发反感)。
4. 夜间免打扰:22:00–08:00 不发送。
**订阅消息额度管理(重要)**
微信的一次性订阅消息需用户逐次授权,**发几次就消耗几次**,额度很容易耗尽。
对策:
- 填报人首次进入时一次性请求多条订阅授权,并引导其勾选"总是保持以上选择";
- 系统记录每个人剩余的授权额度,额度不足时自动降级到服务号或短信;
- 产品层减少催报次数、提升一次填完率(减少返工即减少通知)。
### 3.12 历史数据整理器逻辑
**用途**:处理老师手上已经存在的"乱文件夹",无需重新收集即可产出规范结果。作为获客入口(先看到价值,再谈系统上线)。
**触发**:上传一个压缩包,或指定一个已有目录结构。
**处理步骤**
1. **解析文件树**:识别目录与文件名,生成清单。
2. **逐文件走同一套规则**:形态识别 → 命名规范化(§3.6)→ 压缩(§3.7)→ 校验(§3.8)。
3. **生成《材料体检报告》**,包含:
- 命名违规清单(原文件名 → 规范名)
- 证件号异常清单(与名册比对的结果,含裁决结论)
- 体积超标清单(压缩前后对比)
- 分辨率不足清单
- 缺失材料清单(同一人缺了哪几项)
- 重复文件清单
4. **输出规范化后的压缩包**,目录结构可直接上报。
5. 报告与结果可生成分享链接给班主任。
**特殊能力:散图分拣**
老师从微信里收到的常常是**一堆没有目录、名字很乱的散图**。整理器需要能:
- 按证件号/姓名把散图自动归属到人;
- 无法归属的单独列出,供人工拖拽归位;
- 归位后按材料类型自动分入对应目录。
**异常分支**
| 情况 | 处理 |
|---|---|
| 压缩包内有嵌套压缩包 | 提示是否一并展开处理 |
| 存在无法识别的文件(如 `IMG_001.jpg`) | 归入"待人工归属",不猜测、不放任 |
| 名册缺失(没有 Excel) | 允许无名册运行:仅做命名规范与压缩,不做一致性校验,报告中说明该限制 |
---
## 4. 一页纸规则速查
**材料来源**
- ❌ **不提供"直接拍照"**——所有材料都是已有文件(截图、扫描件、照相馆电子版)
- 三个入口:**① 微信聊天记录(主力)→ ② 手机相册 → ③ 聊天/手机文件**
- **优先引导用户从聊天记录选**:那里能拿到**原始文件名**,系统可直接读出姓名+证件号+材料名
- 相册来的图没有文件名(`IMG_0001.jpg`)→ 只能靠 OCR,须让用户确认归属
**报考范围(从名单聚合,不是外部文件)**
- ❌ **不存在"认定机构下发的计划清单文件"**——实测确认名单里已填好报考三项(28/28)
- 范围 = **名单中「职业 × 工种 × 等级」的聚合结果**,存 `collect_task.plan_scope_json`
- **一致性体检比范围校验更有价值**:单看一行都合法,但"38 人报数控车工、2 人报车工"只有聚合后才能发现
- **追加名单必须告警**:超出已确认范围的报考项需管理员确认——这是范围失控的主要入口
- 参考字典只提示拼写、**不阻断**(机构可能有非常规职业名)
**字段三类规则(决定学生填多少字)**
- 🔒 **锁定**:姓名、身份证号、报考职业/工种/等级 → 只读,名单为空则**阻断发布**
- ✏️ **预填可改**:其余字段 → 名单有值则预填标"老师已填,请核对"并可改;空则学生必填
- 📄 **材料**:学生上传 —— **这是学生唯一的重活**
- 实测老师名单已填满 21 项中的 18 项 ⇒ **学生端几乎不用打字**
**表单填写(官方模板 21 字段)**
- **报考职业/工种/等级必须在"本期报考范围"内** —— 从源头防错
- ⚠️ **官方 Excel 模板里「报考职业」「报考工种」根本没有下拉**(21 列中 13 列自由填写)→ **这正是我们相对模板的核心增量**
- **补考科目数**:三/四/五级最多 1 科;一/二级最多 2 科;**专项职业能力没有补考**
- **是否在校生=是** → 在读学校/所学专业/入学时间三项必填,入学时间 **YYYY-MM-DD**
- **"无"是合法业务值**,不是空值(工作单位、报考工种都可能填"无")
- **专项职业能力**:无工种、无等级、无补考,三项整体跳过
- 官方要求:手动输入时**只能填下拉选项里有的值**
**准入(门禁)**
- **两种模式都必须先导名单**,没有名单不能填报
- 进入填报前必须**填写「姓名 + 身份证号」匹配名单**,不通过只提示、不放行
- 匹配失败**不区分原因**(防止探测身份证号),只给"重新填写 / 申请加入名单"两个出口
- 匹配接口必须**限流**(同 openid 每小时 ≤10 次)
- 姓名形近字/同音字可纠错,但必须**让用户确认**后才通过
**命名**
- 目标:`姓名-证件号-材料名.后缀`
- 证件号争议:**名册优先**,但"两个号码都合法"时**必须人工**
- 姓名纠错:差 1 字且拼音相同 → 自动;否则标黄/标红
- 无法解析 → 保原名 + 标红,绝不乱猜
**材料识别(这是什么材料)**
- **四层递进**:① 文件名(能定就定)→ ② 形态(**只分流派,不定型**)→ ③ OCR 强词计分(在流派内定死)→ ④ VLM 兜底
- **形态层不能区分「一寸照片」和「身份证」**——二者宽高比高度重叠(0.714 vs 0.732–1.016),必须靠内容层
- **一寸照片永远是零文字** → "文字量 < 5 字"是最干净的判据
- 关键词**必须只用强词 + 加权计分**,通用词(姓名/学校/专业/出生)全是噪声
- **只提示、不自动改位置**(散图分拣除外)——自动挪位置比传错更危险
- **识别不出 ≠ 材料错**,识别失败一律放行
- 实测:文件名层 100%、形态分流 99.1%、内容层 100%;**VLM 触发率仅 2%~10%**
**压缩(强制 1M)**
- 体积 ≤1M 是**硬约束**,扫描件**无例外**
- **默认参数:A4 等比缩至 300dpi(2480×3508)+ 质量 85** ← 实测 28/28 达标,平均 806KB,清晰度零损失
- 一次编码到位;只有超限才进兜底路径(先降采样、后降质量)
- 兜底触发下限(<120dpi)→ 标记"强制压缩",必须人工确认(实测不会触发)
- 客户端的活:只做方向校正 + 尺寸限幅;**最终编码只在服务端做一次**
**校验**
- 三层:🔴阻断 / 🟡警告 / 🟢通过
- 一次列全,每条必须含"哪里错 + 错成什么 + 怎么改"
**审核**
- 批量通过**只带绿色项**,红黄项一律不放过
- 驳回必须选原因;驳回后回到初审
- 终审通过即锁定
**导出**
- 有不合格文件**直接拒绝打包**(铁律 2)
- 只导出终审通过的;目录结构可配置;默认 7 天清理
**通知**
- 只催未提交者;同日同人 ≤2 条;夜间免打扰
- 订阅消息额度有限,必须管理剩余额度
---
## 5. 异常与边界场景
> 用真实数据中的 28 人 / 112 个文件作为场景库。
| # | 场景 | 输入的实际情况 | 系统判定 | 输出给用户 | 是否需人工 |
|---|---|---|---|---|---|
| 1 | 学生把照片传给了别人 | 陈子文的一寸照片用的是另一个人的证件号 | 两个号码校验位都通过 → 不是打字错误,是两个人 | 🔴"这张照片上的证件号和你其他材料不一致,请检查是否传错" | ✅ 必须 |
| 2 | 学生证件号填错 | 于豪身份证文件名末 6 位倒置 | 文件名号码校验失败、名册通过 → 文件名错 | ✅ 自动按名册改正,提示"已自动纠正" | ❌ 自动 |
| 3 | 学生姓名写了错别字 | 扬晨(应为杨晨),证件号正确 | 差 1 字 + 拼音相同 → 高置信 | ✅ 自动改为"杨晨" | ❌ 自动 |
| 4 | 文件名多了一个后缀 | 工作证明、身份证共 56 份 `.jpg.jpg` | 循环剥离扩展名 | ✅ 自动修复 | ❌ 自动 |
| 5 | 文件名少了个横杠 | 曾伊豪、徐程宇的身份证文件 | 识别到证件号前后无分隔符 | ✅ 自动补上 | ❌ 自动 |
| 6 | 证件号少了一位 | 曹文锋一寸照片仅 17 位 | 位数不足无法校验 → 名册兜底 | 🟡"已按老师名单补齐,请确认是否正确" | 🟡 确认 |
| 7 | 学生传了扫描仪扫的 16MB A4 | 10517×15445、1272dpi | P3 扫描件档 → A4@300dpi/q85 | ✅"17.1MB → 810KB,清晰度无损" | ❌ 自动 |
| 8 | 学生传的证件照只有 558×745 | 杨晨身份证 0.08MB | 长边低于 1400px → 分辨率不足 | 🟡"这张图有点小,可能看不清。可以让对方发一张原图,或从聊天记录里选那份带文件名的" | 🟡 确认 |
| 9 | 学籍表是系统截图 | 1025×590、PNG | P4 截图档 → 不缩放、保持 PNG | ✅ 不处理,仅规范命名 | ❌ 自动 |
| 10 | 学生填到一半退出了 | 网络中断、切后台 | 草稿已本地暂存 | 重新进入提示"继续上次填写" | ❌ |
| 11 | 学生提交后又改了主意 | 已提交待审 | 未进入审核前允许撤回 | "已撤回,可继续修改" | ❌ |
| 12 | 学生重复提交同一份材料 | 传了两次身份证 | 版本号递增 | 保留最新,旧版本可回溯 | ❌ |
| 13 | 学生把身份证传到了照片项 | 材料名与内容不符 | OCR 识别出不是证件照 | 🟡"这张看起来不是一寸照片,是否移动到身份证?" | 🟡 |
| 14 | **名单里没有这个人** | 转班生/插班生/名单漏录 | 门禁匹配失败 | 🔴"没有找到你的信息。请核对姓名和身份证号是否与老师提供的名单一致" | ✅ 老师把此人加进名单 |
| 15 | 同一人在两个班的名单里 | 转班未清理旧名单 | 命中两条 | 列出两个班级让本人选择,结果通知管理员核对 | 🟡 |
| 16 | 班主任批量通过后发现错了 | 有人红项被漏看 | 批量通过只带绿项,理论上不该发生 | 支持在终审前撤回;审计留痕 | 🟡 |
| 17 | 任务截止了但学生要补交 | 学生忘交 | 任务已截止 | 提示"已截止";管理员可延长截止或点名放行 | 🟡 |
| 18 | 班主任离职/换人 | 账号停用 | 待办无人处理 | 支持转交;超时自动升级通知管理员 | 🟡 |
| 19 | 导出时有人材料不全 | 3 人未完成 | 前置检查不通过 | 🔴 报错并列出名单,提供"仅导出已通过者" | 🟡 |
| 20 | 老师手里已有 475MB 的乱文件夹 | 每班 112 个文件 | 走整理器路径 | 输出体检报告 + 规范包 | ✅(内容核对) |
| 21 | 学生从**聊天记录**选了照相馆发来的照片 | 文件带原始名 `张三-...-一寸照片.jpg` | 文件名可读 → 直接提取姓名/证件号/材料名 | ✅ 一次通过;文案"已按文件名自动识别" | ❌ 自动 |
| 22 | 学生从**相册**选了截图 | 文件名为 `IMG_4821.PNG`,1025×590 | 无文件名信息 → 走 OCR + 人工确认归属 | 🟡"这张图没有名字信息,已识别为学籍表,请确认" | 🟡 确认 |
| 23 | 学生从聊天记录收到的是被微信压缩过的图 | 分辨率明显偏低 | 低于建议值 | 🟡"这张图可能被压缩过,建议让对方发原图" | 🟡 确认 |
| 24 | 聊天记录里的文件已过期/被清理 | 选不到该文件 | 通道不可用 | 提示"请让对方重新发送,或从手机文件里找,也可请老师代传" | ❌ |
| 25 | 学生姓名打成"扬晨"(名单是"杨晨") | 形近字 | 身份证号命中 + 姓名纠错命中 | 🟡"你是不是 **杨晨**?" → 确认后通过 | 🟡 确认 |
| 26 | 有人反复试别人的身份证号 | 尝试枚举名单 | 触发限流 | 🔒 锁定并提示"操作过于频繁,请稍后再试";记录 openid | ❌ 系统自动拦截 |
| 27 | 同一个名单项被两个人绑定 | 冒用 / 代填冲突 | 已被绑定 | 🔴"该信息已被登记,如有疑问请联系老师" | 🟡 |
| 28 | 老师忘了导入名单就想发布任务 | 操作遗漏 | 发布前校验不通过 | 🔴"请先导入名单,名单必须包含姓名和身份证号" | ❌ 阻断发布 |
| 29 | 学生把学籍表传到了"身份证"槽位 | 槽位与内容冲突 | 规则层识别出关键词"学籍",置信度 0.93 | 🟡"这张看起来是**学籍表**,不是身份证。要移过去吗?"[一键移动] | 🟡 用户确认 |
| 30 | 学生传了一堆散图,没归类 | 微信收到的图片 | 整理器无槽位 → 按证件号归属到人 + 按内容判定材料类型 | 自动归入目录;判不出的进"待人工归属" | 🟡 部分人工 |
| 31 | 学生传了一张纯色背景的图 | 一寸照片(无文字) | 形态规则:5:7 比例 + 背景纯净 → 置信度 0.88 | 🟡"请确认这张是一寸照片" | 🟡 确认 |
| 32 | 学生把正确材料放在正确位置,但因图糊识别失败 | 槽位与内容无法比对 | 置信度 <0.4 → **不判断** | ✅ 直接放行(**不因识别失败而打扰用户**) | ❌ 系统静默放行 |
---
## 6. 用户可见文案规范
### 6.1 三条原则
1. **不用术语**——不说"证件号校验位不通过",说"身份证号和老师名单上的不一样"。
2. **指出位置**——必须告诉用户是哪一份材料、哪一个字段有问题。
3. **给出动作**——每条错误都要有"接下来做什么",并提供直达入口。
### 6.2 文案对照表
| 场景 | ❌ 不要这样写 | ✅ 应该这样写 |
|---|---|---|
| 证件号不符 | 身份证号校验失败 | 身份证号第 16 位和老师名单上的不一样,请核对身份证原件(名单上是 `3601...6619`) |
| 疑似串档 | 跨材料一致性校验未通过 | 这张"一寸照片"上的身份证号是 `3601...4232`,和你其他材料不一致,请确认是否传错文件 |
| 分辨率不足 | 图片分辨率低于阈值 | 这张照片有点小,放大后可能看不清,建议重新拍一张 |
| 压缩受限 | 压缩比未达标 | 这张图内容太复杂,压到最小还是超过 1M,建议用手机拍一张更清晰的 |
| 缺材料 | 必填项校验失败 | 还差 1 项:学籍表。点击去上传 → |
| 公章不清 | 图像质量评分不足 | 照片有点模糊,公章可能看不清,建议找打印店重新扫描一份 |
| 任务已截止 | 任务状态异常 | 本次填报已在 9 月 20 日截止。如需补交,请联系你的班主任 |
| 姓名不符 | 姓名匹配度低 | 老师名单上的名字是"杨晨",你写的是"扬晨",是同一个字吗? |
| **材料从哪来** | — | "这份材料一般在**微信聊天记录**里:照相馆/打印店发给你之后,从这里选,系统能自动帮你填好信息" |
| **相册图片无名字** | 无法解析文件名 | "这张图没有名字信息,系统已识别为学籍表。请确认是不是这一份" |
| **聊天图片被压缩过** | 图片分辨率偏低 | "这张图好像被微信压缩过,有点糊。可以让对方发一张原图,或者点开图片后选『原图』再保存" |
| **门禁:匹配失败** | 未找到该身份证号 / 姓名不匹配 | "**没有找到你的信息。**请核对姓名和身份证号是否与老师提供的名单一致。如果确实已报名,可以申请加入名单,由老师审核" |
| **门禁:姓名疑似写错** | 身份证对、姓名形近 | "你是不是 **杨晨**?(老师名单上写的是这个名字)" |
| **门禁:已被绑定** | 名单项已绑他人 | "该信息已被登记,如有疑问请联系老师" |
| **门禁:限流** | 尝试过于频繁 | "操作过于频繁,请稍后再试" |
| **门禁:格式错误** | 身份证位数/校验位不对 | "身份证号看起来不太对(应该是 18 位),请再核对一下" |
| **材料传错位置(高置信)** | 槽位与识别冲突,置信度 ≥0.9 | "这张看起来是**学籍表**,不是身份证。要移过去吗?" [移动] / [不用,就放这里] |
| **材料存疑(中置信)** | 置信度 0.7–0.9 | "这张不太像身份证,请确认一下" |
| **识别失败(静默)** | 置信度 <0.7 或无冲突 | ——(**不提示,直接放行**,避免制造噪音) |
### 6.3 好消息也要说
处理成功的反馈同样重要——**让用户看见系统替他做了什么**:
- "文件名已自动规范化:`...110身份证.jpg.jpg` → `...110-身份证.jpg`"
- "体积已压缩:17.1MB → 900KB(省了 95%)"
- "全部 4 项材料已齐全,可以去提交了"
> 这类反馈是让家长/学生愿意继续用下去的关键——他们能直观看到"这个系统真的帮我干活了"。
---
## 7. 未决事项
| # | 事项 | 影响 | 需谁确认 |
|---|---|---|---|
| 1 | **取得认定机构对"300dpi 扫描件"的书面认可**(D1 已定强制 1M,实测 300dpi 下 28/28 达标且清晰度零损失,此项已无技术争议,仅走确认流程) | 中 | 认定机构 |
| 2 | ~~压缩参数实测标定~~ **已完成(2026-09-24,28 张真实扫描件实测)**:默认 300dpi/q85,平均 806KB,0 张超标 | — | ✅ 已闭环 |
| 3 | ~~文字类降质顺序 A/B 验证~~ **已取消**:默认参数下不触发兜底路径,无需验证 | — | ✅ 已闭环 |
| 4 | 分辨率不足的判定阈值(建议长边 1400px)需认定机构确认 | 中 | 认定机构 |
| 5 | 截图类材料保持 PNG 是否会被拒收 | 中 | 认定机构 |
| 6 | 抽检机制由谁执行、抽检比例 | 低(实测不产生待抽检文件) | 客户 |
| 7 | 驳回次数上限默认 3 次是否合适 | 低 | 客户 |
| 8 | 导出包默认保留 7 天是否够用 | 低 | 客户 |
| 9 | **各来源通道的实际体积上限需实测**(微信聊天记录选文件、相册、文件选择三条通道各自能传多大的文件),并据此设计超限提示与降级路径 | 中 | 研发 |
| 10 | **微信相册/相机权限的隐私声明**需在小程序后台同步更新(当前声明需覆盖"从相册选择") | 中 | 研发 + 法务 |
| **11** | **名单外的人怎么处理?** 当前按需求实现为"不给填、只提示",需老师去后台加人。建议增加"申请加入名单 → 管理员审批后自动放行"通道,**请确认是否采纳** | **高** | 客户 |
| 12 | **门禁限流阈值**(同 openid 每小时 10 次)是否合适,需按实际人数与使用习惯标定 | 中 | 研发 |
| 13 | 社会收集的名单从哪来(预报名名单 / 报名点收集 / 机构导出)?若来源不稳定,"先导名单"的落地难度较大 | 中 | 客户 |
| 14 | 门禁核验是否还要加**手机号验证码**(防止他人拿到姓名+身份证号后代填) | 中 | 客户 |
| **15** | **材料识别的 VLM 选型与单价**(用于成本核算与供应商比价);触发率 15% 为预估值,需用真实数据实测标定 | 中 | 研发 + 商务 |
| 16 | 关键词表由谁维护(平台预置 + 租户自维护);是否需要"从历史文件自动学习关键词"功能 | 中 | 产品 |
| 17 | 一寸照片的纯形态判定阈值(宽高比容差、背景纯净度)需用真实样本标定 | 中 | 研发 |
| **18** | **强特征词表需在更多批次数据上补充标定**——学信网备案表、其它佐证材料在本数据集中不存在,其强词尚未定义 | **高** | 产品 + 研发 |
| **19** | 需要补充测试**困难场景**:模糊件、翻拍反光、非标准材料,当前 112 个样本未覆盖 | **高** | 研发 |
| 20 | ~~文件名规则的真实准确率待测~~ ✅ **已降级**:该指标不影响交付项(输出命名取自名册、归属靠证件号反查、识别有槽位兜底、失败放行)。残留需求仅为**上传页引导文案**要贴合学生真实文件名,班主任在群里问两句即可,**不需专门样本** | — | 产品 |
| ~~21~~ | ~~认定机构下发文件的真实格式样本~~ **已澄清:不存在该文件**,报考范围来自名单 → 问题关闭 | — | ✅ 已闭环 |
| ~~22~~ | ~~下发文件是全量还是增量~~ **同上,问题关闭** | — | ✅ 已闭环 |
| ~~23~~ | ~~国标职业字典初始数据来源~~ **降级**:字典改为可选的拼写校验(P2),不阻塞开发 | 低 | 产品 |
| **24** | **是否允许学生修改"老师预填"的字段?** 本版设计为"可改并留痕"(依据:电话有 28 个不同值、入学时间可能记错)。若机构要求严格一致,需改为"只读 + 申请修改" | **中** | 客户 |
---
**文档结束**