# 学员与证书业务模型 ## 1. 核心关系 - 学员是长期主体,证书是某一次学习成果的签发记录。 - 一个学员可以拥有多张证书,证书可以来自不同项目、不同课程、不同模板和不同时间段。 - 证书签发后保存当次课程、阶段、日期和模板代码,不依赖项目默认值继续变化。 - 项目只负责归档和提供默认值,不能代替证书模板定义字段。 ## 2. 学员身份规则 - 系统使用标准化后的手机号定位学员,姓名用于一致性校验和业务确认。 - 输入手机号会去除空格、短横线及中国大陆区号,最终保存为 11 位手机号。 - 手机号不存在时,手工签发和证书批量导入都会自动创建学员。 - 手机号已存在且姓名一致时,复用原学员。 - 手机号已存在但姓名不一致时,必须报冲突,不能自动改名或把证书挂到错误学员。 - 确需更名时,应在学员管理中人工修改,并保留姓名历史。 ## 3. 模板字段规则 `app/services/certificate_templates.py` 是模板字段的唯一规则源。每个字段定义: - `key`:后端和前端使用的稳定字段键。 - `label`:页面和 Excel 使用的中文名称。 - `field_type`:文本或日期。 - `required`:该模板签发证书时是否必填。 - `example`:Excel 填写示例。 - `description`:后台提示和 Excel 填写说明。 新增模板时,应先在这里声明字段。手工创建表单、Excel 表头、Excel 校验和后端签发校验都会读取同一份定义。 ## 4. 导入流程 ### 证书导入 1. 先选择证书模板。 2. 下载该模板专用 Excel,不能跨模板混用。 3. 上传后只做校验,不立即写入正式证书。 4. 管理员确认后调用统一签发服务。 5. 学员不存在时自动创建;重复证书跳过;身份冲突或字段错误进入失败记录。 证书导入的公共业务列是姓名、手机号和项目代码。其余列由所选证书模板决定。 ### 学员导入 - 姓名和手机号必填,学员编号和备注选填。 - 只维护学员主数据,不创建证书。 - 已有学员姓名手机号一致时可补充学员编号和备注。 - 冲突行单独返回,不修改已有学员姓名。 ## 5. 签发入口 手工创建和证书导入统一调用 `app/services/certificate_issuance.py`,由该服务负责: - 校验项目和模板; - 解析或创建学员; - 校验模板字段和课程日期; - 判断重复证书; - 创建证书编号; - 创建公开链接和二维码令牌。 路由层只处理权限、HTTP 参数、事务提交和操作日志,不应再次复制签发规则。