# 智慧招标平台(STP)供应商注册模块详细设计说明书 | 文档名称 | 供应商注册模块详细设计说明书 | | :------- | :--------------------------------- | | **文档版本** | V1.0 | | **编制日期** | 2026-06-30 | | **关联文档** | 《需求分析说明书 V1.4》《供应商报名详细设计》《SRM接口方案》 | ## 目录 1. [模块概述](#1-模块概述) 2. [用户角色与权限](#2-用户角色与权限) 3. [页面UI详细设计](#3-页面ui详细设计) 4. [字段级校验规则](#4-字段级校验规则) 5. [AI自动审核详细设计](#5-ai自动审核详细设计) 6. [完整业务流程(含状态机)](#6-完整业务流程含状态机) 7. [时序图(含外部系统交互)](#7-时序图含外部系统交互) 8. [数据模型完整定义](#8-数据模型完整定义) 9. [API接口详细规范](#9-api接口详细规范) 10. [业务规则与约束](#10-业务规则与约束) 11. [异常处理矩阵](#11-异常处理矩阵) 12. [通知策略](#12-通知策略) 13. [SRM双向同步机制](#13-srm双向同步机制) 14. [供应商联系人变更(注册后维护)](#14-供应商联系人变更注册后维护) 15. [安全与合规](#15-安全与合规) 16. [附录](#16-附录) --- ## 1. 模块概述 ### 1.1 建设目标 建立面向潜在投标供应商的**轻量化、全自动、即时生效**的注册机制。注册阶段仅做**主体身份认证**(营业执照有效性核验),不进行人工资格审核。通过即开通平台登录权限和投标报名资格,**深度资质审核后移至投标报名环节按项目要求执行**。 ### 1.2 核心设计理念:注册与审核分离 | 阶段 | 审核内容 | 审核方式 | 通过标准 | | :--- | :--- | :--- | :--- | | **注册阶段** | 营业执照有效性、企业存续状态、基础信息一致性、严重违法筛查 | **全自动AI**(无人工) | 所有一票否决项通过 | | **投标报名阶段** | 项目特定资质、业绩、财务能力、技术能力 | AI初审 + 人工复核 | 满足具体项目资格要求 | ### 1.3 设计原则 - **极简快速**:提交即审核,5秒内出结果,无等待队列。 - **AI全自动**:OCR + 工商API + 风险图谱全链路自动化。 - **一次注册,双平台通用**:自动同步至SRM,建立统一供应商身份(`srm_id`双向绑定)。 - **审核后置**:深度资质审核下沉至报名环节,降低准入门槛。 - **安全合规**:敏感字段(信用代码、手机号)AES-256-GCM加密存储,全量审计。 ### 1.4 适用范围 - **适用对象**:所有拟参与滨化集团招标项目的潜在供应商(含工程、货物、服务类)。 - **与SRM关系**:新供应商自动在SRM创建档案(状态:待认证);已存续SRM供应商通过“无感登录”直接绑定,无需重复注册。 --- ## 2. 用户角色与权限 | 角色 | 权限范围 | | :--- | :--- | | **供应商申请人(未注册)** | 访问注册页面、提交申请、查看审核结果。 | | **已注册供应商(ACTIVE)** | 登录平台、浏览公告、投标报名、维护企业信息(含联系人变更)。 | | **供应商管理专员** | 查看注册统计、处理注册异常申诉、执行黑名单管理(冻结/解封)。 | | **系统管理员** | 配置AI审核阈值、管理工商API密钥、查看系统日志。 | | **合规/审计** | 查阅注册审计日志(只读)。 | --- ## 3. 页面UI详细设计 ### 3.1 注册步骤导航条 ```svg 1 企业信息 2 联系人 3 提交/自动审核 ⚡ AI即时审核 · 秒级通过 ``` ### 3.2 步骤一:企业信息 ```svg 供应商注册 请填写企业真实信息,上传营业执照,系统将自动识别并回填 📄 上传营业执照(JPG/PNG/PDF,≤10MB) 支持拖拽或点击上传,AI 将自动识别企业信息并填充表单 ✅ 已识别:营业执照信息提取成功(统一信用代码:91370100XXXXXXXXXX) 企业全称 * 系统自动识别或手动输入 统一社会信用代码 * 18位代码 注册资本(万元) * 数字 法定代表人 * 姓名 行业分类 * 请选择/输入行业 注册地址 * 请填写详细地址 经营范围 * 系统识别或手动输入,建议不超过200字 主要产品 * 如:工业阀门、管道 + 添加 工业阀门 ✕ 管道配件 ✕ 上一步 下一步 → 📌 注册须知 1. 请确保信息与营业执照一致 2. 统一社会信用代码将作为唯一标识 3. 提交后由供应商管理专员审核 4. 审核通过后可参与投标报名 5. 已有SRM账号请直接登录 ``` **布局说明**:采用左右结构,左侧为表单(占比70%),右侧为“注册须知”浮窗(占比30%)。 **表单字段明细**(按顺序): | 字段 | 组件类型 | 占位提示 | 备注 | | :----------- | :------- | :------------------------------- | :-------------------- | | **营业执照上传** | 拖拽/点击上传区 | “点击或拖拽上传营业执照(JPG/PNG/PDF,≤10MB)” | **AI识别触发点**,上传即自动OCR | | **企业全称** | 文本输入框 | “**系统自动识别**或手动输入” | 最大长度128字符 | | **统一社会信用代码** | 文本输入框 | “18位统一社会信用代码”自动识别 | 自动转大写,格式校验 | | **注册资本(万元)** | 数字输入框 | “请输入数字” | 保留2位小数,≥0 | | **法定代表人** | 文本输入框 | “请输入法定代表人姓名” | 最大长度64字符 | | **行业分类** | 下拉框+搜索 | “请选择或搜索行业” | 基于GB/T 4754-2017,三级分类 | | **注册地址** | 文本输入框 | “请填写详细地址” | 最大长度256字符 | | **经营范围** | 多行文本域 | “系统自动识别或手动输入,不超过500字” | 最大500字符 | | **主要产品** | 标签输入组件 | “输入产品名称,回车添加” | 最多添加20个,每个≤30字符 | **OCR识别状态条**(实时反馈): - 识别中:`⏳ 正在识别营业执照...` - 成功:`✅ 识别完成,已自动回填以下字段:[企业全称]、[信用代码]、[法人]、[地址]、[经营范围]` - 失败:`❌ 识别失败,请手动填写(或检查图片是否清晰)` ### 3.3 步骤二:联系人信息 ```svg 联系人信息 联系人姓名 * 请输入联系人姓名 必填,最大64字符 联系电话 * 13800138000 必填,格式校验,全局唯一 电子邮箱 * 请输入常用邮箱 必填,格式校验,全局唯一 短信验证码 * 点击发送验证码 发送验证码 用于验证手机号真实性(注册必验) 输入密码 确认密码 密码复杂度要求 长度 8~20 位 至少包含 1 个大写字母(A-Z)和 1 个小写字母(a-z) 至少包含 1 个数字(0-9)和 1 个特殊字符(!@#$%^&*()_+-=) 禁止连续/重复字符(如 12345678, aaaaaaaa) 禁止常见弱口令(内置弱密码字典) 密码强度 提交 ``` | 字段 | 组件类型 | 占位提示 | 备注 | | :------------ | :------- | :---------- | :--------------- | | **联系人姓名** | 文本输入框 | “请输入联系人姓名” | 必填,最大64字符 | | **联系电话(手机号)** | 文本输入框 | “请输入11位手机号” | 必填,格式校验,**全局唯一** | | **电子邮箱** | 文本输入框 | “请输入常用邮箱” | 必填,格式校验,**全局唯一** | | **短信验证码** | 输入框+发送按钮 | “点击发送验证码” | 用于验证手机号真实性(注册必验) | | 输入密码 | 密码输入框 | | | | 确认密码 | 密码输入框 | | | **密码复杂度要求**: - 长度 8~20 位 - 至少包含 1 个大写字母(A-Z) - 至少包含 1 个小写字母(a-z) - 至少包含 1 个数字(0-9) - 至少包含 1 个特殊字符(!@#$%^&*()_+-=) - 禁止使用连续/重复字符(如 `12345678`、`aaaaaaaa`) - 禁止使用常见弱口令(内置弱密码字典,如 `password`、`admin123`) **密码强度实时指示器**: - 弱(红色):< 3 项满足 - 中(橙色):≥ 4 项满足 - 强(绿色):全部满足 + 长度≥12 ### 3.4 步骤三:SRM存量引导弹窗 **当检测到SRM存量时,弹出如下引导窗(模态框):** ```svg 🔍 检测到SRM存量供应商 该企业已在SRM系统中注册,您可以选择: 使用SRM账号登录 继续注册 选择“继续注册”将跳过资质审核,直接绑定SRM账号 选择“登录”将跳转至登录页,使用SRM账号密码登录 取消 ``` **选择“继续注册”后的处理**: - 前端重新提交注册请求,携带参数 `confirmSrmBinding: true`。 - 后端跳过AI审核,直接创建STP账号并绑定SRM ID,返回成功(自动登录)。 **选择“使用SRM账号登录”**: - 前端跳转至登录页,并自动填充企业名称/信用代码(可选),引导用户使用SRM账号密码登录(利用统一登录接口)。 ### 3.5 步骤四:提交 & 自动审核 **审核中(等待 3~8 秒)** : ```svg ⏳ AI 正在审核企业信息... 预计 3~8 秒,请勿关闭页面 ✓ 工商信息核验 ✓ 风险扫描 ✓ 唯一性检查 ``` **审核通过(自动登录跳转)** : ```svg 🎉 注册成功! 您的供应商账号已激活,正在自动登录... 供应商编号:SUP_20260630_0158 登录账号:138****8001 📌 温馨提示:参与具体项目投标时,需按招标公告要求提交资质审核材料 ``` **审核不通过**: ```svg 审核未通过 • 统一社会信用代码与工商登记信息不匹配 • 企业状态为“注销”,不符合注册条件 💡 请核对信息后重新提交,如有疑问请联系客服 修改后重新提交 ``` --- ## 4. 字段级校验规则(前后端双重校验) |字段|前端校验|后端校验|错误码| |---|---|---|---| |**营业执照文件**|格式(JPEG/PNG/PDF)、大小≤10MB|文件病毒扫描、图片清晰度检测|`ERR_FILE_001`| |**企业全称**|非空,长度≤128|与OCR结果一致性比对|`ERR_PARAM_001`| |**统一社会信用代码**|非空,格式正则`^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$`,自动转大写|唯一性校验;与工商API比对|`ERR_PARAM_002` / `ERR_REG_002`| |**注册资本**|数字,≥0,最多2位小数|数据类型校验|`ERR_PARAM_003`| |**法定代表人**|非空,长度≤64|与OCR结果一致性比对|`ERR_PARAM_004`| |**行业分类**|非空,必须为GB/T 4754叶子节点|枚举校验|`ERR_PARAM_005`| |**注册地址**|非空,长度≤256|-|`ERR_PARAM_006`| |**经营范围**|非空,长度≤500|-|`ERR_PARAM_007`| |**主要产品**|数组非空,每个≤30字符,最多20个|-|`ERR_PARAM_008`| |**联系人姓名**|非空,长度≤64|-|`ERR_PARAM_009`| |**联系电话**|非空,格式`^1[3-9]\d{9}$`|唯一性校验(`contact_phone`不可重复)|`ERR_PARAM_010` / `ERR_REG_003`| |**电子邮箱**|非空,邮箱格式正则|唯一性校验|`ERR_PARAM_011` / `ERR_REG_003`| |**短信验证码**|非空,6位数字|匹配Redis缓存,有效期5分钟|`ERR_AUTH_001`| |**登录密码**|非空,长度8-20|强度校验(大小写+数字+特殊字符+弱口令字典)|`ERR_PARAM_012`| |**确认密码**|非空,与密码一致|与密码字段比对|`ERR_PARAM_013`| --- ## 5. AI自动审核详细设计 ### 5.1 审核前置:SRM存量检查 ```mermaid graph TD A[接收注册请求] --> B{请求中是否包含
confirmSrmBinding=true?} B -->|是| C[跳过所有AI检查,直接执行SRM绑定流程] B -->|否| D[调用SRM查询接口
根据信用代码查询供应商] D --> E{SRM中存在?} E -->|是| F[返回特殊错误码ERR_SRM_EXISTS
附带SRM供应商基本信息] E -->|否| G[进入AI审核流程(原有7项检查)] C --> H[创建STP供应商记录status=ACTIVE
绑定srm_id] G --> I{综合仲裁} I -->|通过| H I -->|不通过| J[驳回] ``` ### 5.2 各项检查详细规则 | 检查项 | 调用源 | 通过条件 | 硬性拒绝条件 | 超时处理 | | :------------- | :----------- | :----------------------- | :------------------------ | :--------------------- | | **OCR完整性** | 内部OCR服务 | 成功提取「企业全称+信用代码+法人」 | 三项任一缺失 | 超时3s → 降级允许手动输入,但不自动通过 | | **工商验真** | 天眼查/企查查API | 输入名称与信用代码匹配,且置信度≥95% | 不匹配 | 超时5s → 返回“服务繁忙,请稍后重试” | | **企业存续状态** | 天眼查API | 状态为“存续(在营)” | 注销/吊销/清算 | 使用缓存数据(缓存≤24h) | | **严重违法** | 国家企业信用信息公示系统 | 不在“严重违法失信名单” | 在名单中 | 若API不可用,默认通过(记录告警) | | **经营异常** | 天眼查API | 不在“经营异常名录” | **不硬性拒绝**,仅标记 `risk_tags` | 若API不可用,默认无异常 | | **信用代码唯一性** | 本地DB | 未注册(含ACTIVE/REJECTED/锁定) | 已存在(不论状态) | N/A | | **手机号唯一性** | 本地DB | 未被其他ACTIVE供应商绑定 | 已绑定 | N/A | | **SRM 存量供商应商** | | | | | | | | | | | ### 5.3 SRM存量绑定跳过项 当 `confirmSrmBinding=true` 时,跳过以下检查: - OCR完整性 - 工商验真 - 企业状态 - 严重违法 - 经营异常 仍保留的检查: - 信用代码唯一性(STP内) - 手机号/邮箱唯一性 ### 5.3 综合仲裁逻辑(伪代码) ```python def audit_register(request): results = parallel_run([ ocr_check(request.file), business_verify(request.credit_code, request.company_name), status_check(request.credit_code), fraud_check(request.credit_code), exception_check(request.credit_code), uniqueness_check(request.credit_code, request.phone, request.email) ]) # 一票否决项 fatal_checks = ['ocr', 'verify', 'status', 'fraud', 'uniqueness'] for check in fatal_checks: if not results[check].passed: return reject(results[check].reason) # 经营异常仅标记,不阻止 if results['exception'].has_exception: mark_risk_tag(request.supplier_id, '经营异常') return approve() ``` --- ## 6. 完整业务流程(含状态机) ### 6.1 状态定义(精简) | 状态码 | 名称 | 说明 | 可执行操作 | | :--- | :--- | :--- | :--- | | `DRAFT` | 草稿 | 用户正在填写,尚未提交 | 编辑、提交 | | `SUBMITTED` | 提交审核中 | AI正在执行检查(瞬时状态,<5s) | 无(轮询等待) | | `ACTIVE` | 已激活/正常 | AI全部通过,可登录报名 | 登录、报名、修改信息、变更联系人 | | `REJECTED` | 审核驳回 | 至少一项一票否决未通过 | 查看原因、修改后重新提交(30天内) | | `LOCKED` | 已锁定 | 违规操作/被管理员冻结 | 联系管理员解封 | | `ARCHIVED` | 已归档 | 长期未使用或主动注销 | 只读(不可登录) | ### 6.2 状态流转图 ```mermaid stateDiagram-v2 [*] --> DRAFT: 开始注册 DRAFT --> SUBMITTED: 提交(不含SRM绑定确认) SUBMITTED --> SRM_EXISTS: 检测到SRM存量(返回ERR_SRM_EXISTS) SRM_EXISTS --> DRAFT: 用户取消/关闭弹窗 SRM_EXISTS --> ACTIVE: 用户选择“继续注册”(带confirmSrmBinding=true) SRM_EXISTS --> [*]: 用户选择“使用SRM账号登录”(跳转登录) SUBMITTED --> ACTIVE: AI全部通过(新供应商) SUBMITTED --> REJECTED: AI不通过 REJECTED --> DRAFT: 修改重提 ACTIVE --> LOCKED: 管理员冻结 LOCKED --> ACTIVE: 解封 ``` > **注意**:由于审核是实时的,`SUBMITTED`状态在数据库层面几乎不持久化(前端展示加载态即可)。 ### 6.3 完整业务流程 ```mermaid flowchart TD subgraph 供应商端 A[访问注册页] --> B[填写完整信息并提交] B --> C[等待审核结果(3-8秒)] C --> D{前端收到响应} D -->|成功(新供应商通过)| E[显示成功页+自动登录] D -->|错误码ERR_SRM_EXISTS| F[弹出SRM存量引导窗] F --> G{用户选择} G -->|“继续注册”| H[重新提交请求带confirmSrmBinding=true] G -->|“使用SRM账号登录”| I[跳转登录页] G -->|取消| J[返回注册页修改] D -->|其他驳回| K[显示驳回原因+修改] H --> L[立即成功+自动登录] end ``` ```mermaid flowchart TD subgraph STP后端 STP1[接收注册请求] --> STP2{是否有confirmSrmBinding=true?} STP2 -->|是| STP3[跳过AI审核,查询SRM获取srmId] STP2 -->|否| STP4[调用SRM查询接口检测存量] STP4 --> STP5{SRM存在?} STP5 -->|存在| STP6[返回ERR_SRM_EXISTS(含srmId+名称)] STP5 -->|不存在| STP7[执行AI审核(7项检查)] STP7 --> STP8{AI通过?} STP8 -->|通过| STP9[创建供应商status=ACTIVE] STP8 -->|不通过| STP10[创建供应商status=REJECTED] STP3 --> STP9 STP9 --> STP11[创建用户账号+密码哈希] STP11 --> STP12[生成JWT Token] STP12 --> STP13[同步SRM(若已有srmId则更新绑定)] STP13 --> STP14[发送成功通知] STP10 --> STP15[发送驳回通知] end subgraph 外部系统 EXT1[SRM查询接口] EXT2[SRM注册/绑定接口] EXT3[通知网关] end STP4 -.-> EXT1 STP3 -.-> EXT2 STP14 -.-> EXT3 ``` --- ## 7. 时序图 ```mermaid sequenceDiagram participant U as 供应商 participant FE as 前端 participant GW as API网关 participant RegSvc as 注册服务 participant AISvc as AI审核服务 participant BizAPI as 天眼查API participant SRM as SRM系统 participant DB as STP数据库 participant Notify as 通知服务 U->>FE: 填写完整信息(含密码)并提交 FE->>GW: POST /register(无confirmSrmBinding) GW->>RegSvc: 转发 RegSvc->>DB: 校验信用代码是否已在STP注册 alt 已注册 DB-->>RegSvc: 已存在 RegSvc-->>FE: 409 ERR_REG_002(已注册) else 未注册 RegSvc->>SRM: GET /query/by-tax-id(查询存量) SRM-->>RegSvc: 返回结果(存在或不存在) alt SRM存在 RegSvc-->>FE: 200 但 code=ERR_SRM_EXISTS,附带srmId和supplierName FE-->>U: 弹出引导窗 U->>FE: 点击“继续注册” FE->>GW: POST /register + confirmSrmBinding=true GW->>RegSvc: 转发(携带srmId) RegSvc->>DB: 创建供应商 status=ACTIVE,绑定srmId RegSvc->>RegSvc: 创建用户账号,密码哈希 RegSvc->>RegSvc: 生成JWT Token RegSvc->>Notify: 发送成功通知(无需激活) RegSvc-->>FE: 200 成功 + accessToken FE->>FE: 存储Token FE-->>U: 自动跳转工作台 else SRM不存在(新供应商) RegSvc->>AISvc: 执行AI审核(7项并行) AISvc->>BizAPI: 工商验真/状态/违法等 BizAPI-->>AISvc: 结果 AISvc-->>RegSvc: 审核结论 alt 通过 RegSvc->>DB: 创建供应商 status=ACTIVE RegSvc->>RegSvc: 创建用户账号、生成Token RegSvc->>SRM: POST /register(同步注册至SRM) SRM-->>RegSvc: srmId RegSvc->>DB: 更新srmId RegSvc->>Notify: 发送成功通知 RegSvc-->>FE: 200 成功 + Token FE-->>U: 自动登录 else 不通过 RegSvc->>DB: 创建供应商 status=REJECTED RegSvc->>Notify: 发送驳回通知 RegSvc-->>FE: 400 失败(含原因) FE-->>U: 显示驳回页 end end end ``` --- ## 8. 数据模型完整定义 ### 8.1 供应商主表 `t_supplier_profile` | 字段名 | 类型 | 约束 | 说明 | | ---------------------- | ------------- | ---------------- | -------------------------------------- | | `id` | BIGINT | PK | 自增主键 | | `supplier_id` | VARCHAR(32) | UNIQUE, NOT NULL | 业务编号 | | `user_id` | VARCHAR(32) | INDEX | 关联用户账号 | | `srm_id` | VARCHAR(32) | INDEX | SRM系统ID(存量绑定或新注册同步后回填) | | `company_name` | VARCHAR(128) | NOT NULL | 企业全称 | | `credit_code` | VARCHAR(128) | NOT NULL, UNIQUE | 信用代码(加密) | | `credit_code_md5` | CHAR(32) | UNIQUE | MD5盲索引 | | `registered_capital` | DECIMAL(15,2) | | 注册资本 | | `legal_representative` | VARCHAR(64) | | 法定代表人 | | `industry_code` | VARCHAR(16) | | 行业代码 | | `industry_name` | VARCHAR(64) | | 行业名称 | | `address` | VARCHAR(256) | | 注册地址 | | `business_scope` | TEXT | | 经营范围 | | `main_products` | JSON | | 主要产品 | | `contact_name` | VARCHAR(64) | NOT NULL | 联系人姓名 | | `contact_phone` | VARCHAR(128) | NOT NULL, UNIQUE | 手机号(加密) | | `contact_phone_md5` | CHAR(32) | UNIQUE | MD5 | | `contact_email` | VARCHAR(128) | NOT NULL | 邮箱 | | `license_file_url` | VARCHAR(512) | | 营业执照URL | | `license_ocr_result` | JSON | | OCR结果 | | `audit_result` | JSON | | AI审核报告(新供应商) | | **`source_type`** | VARCHAR(20) | NOT NULL | **NEW / SRM_BINDING**(标识注册来源) | | **`srm_bind_time`** | DATETIME | | **SRM绑定时间(存量绑定)** | | `status` | VARCHAR(20) | NOT NULL | DRAFT/SUBMITTED/ACTIVE/REJECTED/LOCKED | | `risk_tags` | JSON | | 风险标签 | | `reject_reasons` | JSON | | 驳回原因 | | `activated_at` | DATETIME | | 激活时间(即注册成功时间) | | `created_at` | DATETIME(3) | | 创建时间 | | `updated_at` | DATETIME(3) | | 更新时间 | ### 8.2 用户账号表 `t_user`(新增字段) | 字段名 | 类型 | 说明 | | --------------- | ------------ | ----------- | | `user_id` | VARCHAR(32) | PK | | `supplier_id` | VARCHAR(32) | FK | | `login_name` | VARCHAR(64) | UNIQUE(手机号) | | `password_hash` | VARCHAR(128) | Argon2id哈希 | | `user_type` | VARCHAR(20) | 'SUPPLIER' | | `status` | VARCHAR(20) | 'ACTIVE' | | `last_login_at` | DATETIME | | --- ## 9. API接口详细规范 ### 9.1 提交供应商注册(支持SRM存量检测) |项目|内容| |---|---| |**路径**|`/api/v1/supplier/register`| |**方法**|`POST`| **请求体(第一次提交,无confirmSrmBinding)** ```json { "companyName": "滨化新材料有限公司", "creditCode": "91370100MA3XXXXXXX", "registeredCapital": 5000.00, "legalRepresentative": "张伟", "industryCode": "C2614", "address": "山东省滨州市黄河五路888号", "businessScope": "化工产品、新材料技术研发...", "mainProducts": ["聚丙烯", "环氧丙烷"], "contactName": "李强", "contactPhone": "13800138001", "contactEmail": "liqiang@example.com", "licenseFileUrl": "https://oss.stp.com/xxx.pdf", "smsCode": "123456", "password": "Abcd@2026#", "confirmPassword": "Abcd@2026#", "agreeTerms": true } ``` **特殊响应(检测到SRM存量)** ```json { "code": "ERR_SRM_EXISTS", "message": "检测到该供应商已在SRM系统中注册", "data": { "srmId": "SRM_12345", "companyName": "滨化新材料有限公司", "creditCode": "91370100MA3XXXXXXX", "hint": "您可以选择继续注册(跳过资质审核)或使用SRM账号登录" } } ``` **第二次提交(用户选择继续注册)** ```json { ...(同第一次请求), "confirmSrmBinding": true, "srmId": "SRM_12345" // 可选,后端也可再次查询 } ``` **成功响应(无论新注册还是存量绑定,均一致)** ```json { "code": "0", "data": { "supplierId": "SUP_20260630_0158", "srmId": "SRM_12345", "userId": "U_...", "status": "ACTIVE", "accessToken": "eyJ...", "tokenType": "Bearer", "expiresIn": 1800, "sourceType": "NEW" 或 "SRM_BINDING", "message": "注册成功,账号已激活" } } ``` ### 9.2 营业执照OCR(预填) | 项目 | 内容 | | :--------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | **路径** | `/api/v1/ocr/business-license` | | **方法** | `POST` | | **请求** | `multipart/form-data`,字段 `file` | | **响应(成功)** | `{"code":"0","data":{"companyName":"...","creditCode":"...","legalPerson":"...","registeredCapital":"...","address":"...","businessScope":"..."}}` | | **响应(失败)** | `{"code":"ERR_OCR_001","message":"图片识别失败,请确认图片清晰"}` | ### 9.3 发送短信验证码 | 项目 | 内容 | | :--- | :--- | | **路径** | `/api/v1/auth/sms/send` | | **方法** | `POST` | | **请求** | `{"phone":"13800138000","captchaToken":"图形验证码"}` | | **响应** | `{"code":"0","data":{"expireSeconds":300,"resendAfterSeconds":60}}` | **其他错误码** - `ERR_REG_002`:信用代码已注册(409) - `ERR_REG_003`:手机号已被占用(409) - `ERR_REG_004`:邮箱已被占用(409) - `ERR_REG_005`:短信验证码错误或过期(401) - `ERR_REG_006`:工商API服务繁忙,请稍后重试(503) ### 9.4 首次登录激活(设置密码) | 项目 | 内容 | | :--- | :--- | | **路径** | `/api/v1/supplier/activate` | | **方法** | `POST` | | **请求** | `{"supplierId":"SUP_...","password":"Abcd@1234","confirmPassword":"Abcd@1234"}` | | **成功** | `{"code":"0","message":"激活成功"}` | --- ## 10. 业务规则与约束 | ID | 规则 | 说明 | | --- | ---------------- | ------------------------------------------------------- | | R01 | **信用代码唯一性** | 无论来源,STP内信用代码唯一。 | | R02 | **SRM存量检测优先** | 每次注册请求首先查询SRM,除非已带`confirmSrmBinding`参数。 | | R03 | **存量绑定跳过AI** | 当`confirmSrmBinding=true`时,跳过OCR、工商验真、状态、违法检查,仅保留唯一性校验。 | | R04 | **存量绑定的SRM账号状态** | 不要求SRM账号必须激活,只要存在记录即可绑定。 | | R05 | **密码设置要求** | 存量绑定同样需要设置密码(与正常注册相同)。 | | R06 | **存量绑定后SRM同步** | 若srmId已存在,则无需再次调用SRM注册接口,只需在STP记录绑定关系。若srmId为空(异常),需补录。 | | R07 | **引导弹窗后取消** | 用户取消则回到注册页,可修改信息后再次提交(会再次触发SRM检测)。 | | R08 | **重复检测** | 若STP已存在同信用代码,直接返回已注册,不查询SRM。 | --- ## 11. 异常处理矩阵 |异常场景|处理方式|用户侧表现|后端动作| |---|---|---|---| |**SRM查询接口超时**|降级:视为新供应商,进入AI审核|正常AI审核流程(可能延迟)|记录告警,超时5s后转AI| |**SRM查询返回错误**|降级:视为新供应商|正常AI审核|记录错误日志| |**存量绑定后SRM绑定失败**|异步重试,STP仍激活|用户无感知|标记同步失败,告警管理员| |**用户选择“继续注册”但信用代码已在STP注册**|返回已注册错误|提示“该企业已注册”|返回ERR_REG_002| --- ## 12. 通知策略 |触发事件|通知方式|接收方|文案| |---|---|---|---| |**新供应商注册成功**|邮件+短信|联系人|“恭喜X公司注册成功!已自动激活,请直接登录。”| |**SRM存量绑定成功**|邮件+短信|联系人|“恭喜X公司完成STP账号绑定,您已是滨化供应商,可直接登录参与投标。”| |**注册驳回**|邮件+短信|联系人|“注册未通过,原因:...”| --- ## 13. SRM双向同步机制 ### 13.1 注册时正向同步(STP → SRM) - **触发时机**:AI审核通过,`INSERT`成功后立即执行。 - **接口**:`POST /api/v1/supplier/register`(见接口方案3.2) - **映射关系**: | STP字段 | SRM字段 | | :--- | :--- | | `company_name` | `supplierName` | | `credit_code` | `taxId` | | `contact_name` | `contactInfo.name` | | `contact_phone` | `contactInfo.phone` | | `contact_email` | `contactInfo.email` | | `address` | `address` | - **状态映射**:STP `ACTIVE` → SRM `PENDING_CERTIFICATION`(需后续补充资质文件完成认证)。 ### 13.2 SRM存量供应商绑定(无需同步,仅获取srmId) - 调用SRM查询接口获取srmId,存入本地,不调用注册接口。 - 如果SRM供应商状态为“未激活”等,不影响STP绑定。 ### 13.3 反向同步(SRM → STP) 若SRM侧修改供应商信息,通过定时增量同步接口更新STP(联系人等),与本注册模块无关。 --- ## 14. 供应商联系人变更(注册后维护) > 本模块为注册流程的**必要延伸**,确保企业联系人信息变更时账户安全与业务通知可达。 ### 14.1 自助变更(旧手机号可用) ```mermaid flowchart LR A[登录工作台] --> B[进入企业信息页] B --> C[点击修改联系人] C --> D[验证旧手机号/邮箱] D --> E[填写新联系人信息] E --> F[验证新手机号/邮箱] F --> G[提交变更] G --> H[即时生效 + 同步SRM] ``` ### 14.2 人工辅助变更(旧手机号不可用) ```mermaid flowchart LR A[点击“旧手机无法接收验证码?”] --> B[下载《变更申请函》模板] B --> C[填写+加盖公章] C --> D[上传盖章扫描件] D --> E[提交人工申请] E --> F[管理员审核(4h内)] F --> G[后台执行变更] ``` ### 14.3 接口与数据(简略) - **变更接口**:`PUT /api/v1/supplier/contact` - **审计日志**:写入`t_supplier_contact_change_log`(含旧值/新值/变更人/IP/哈希链)。 - **SRM同步**:调用`POST /api/v1/supplier/contact/update`。 > 详细设计参考《联系人变更补充设计》,此处仅作概要嵌入,确保完整性。 --- ## 15. 安全与合规 | 安全维度 | 具体措施 | | :--- | :--- | | **传输安全** | 强制 HTTPS + TLS 1.3,HSTS 头部强制。 | | **敏感字段加密** | `credit_code`、`contact_phone` 使用 **AES-256-GCM** 应用层加密,密钥由KMS托管,内存动态漂移(参见全局安全方案4.2)。 | | **可搜索加密** | 唯一性校验使用字段的 **MD5/SHA-256** 盲索引(不可逆),不直接对密文进行`SELECT`。 | | **数据脱敏展示** | 后台展示信用代码为 `913701**********`,手机号为 `138****8001`。 | | **审计防篡改** | 所有审计日志采用 **哈希链+数字签名**(参见需求说明书4.8.1),保留≥7年。 | | **防机器人** | 注册提交需验证图形验证码(极验),手机验证码发送每日限5次。 | | **密码安全** | 首次激活密码强度≥8位,含大小写+数字+特殊字符,不得为弱口令(密码字典检测)。 | | **合规性** | 满足《个人信息保护法》第13条(告知同意)、第17条(隐私政策),注册前勾选同意《用户协议》与《隐私政策》。 | --- ## 16. 附录 ### 16.1 统一社会信用代码正则(前端+后端) ```regex ^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$ ``` ### 16.2 行业分类示例(GB/T 4754-2017 三级) | 一级 | 二级 | 三级代码 | 三级名称 | | :--- | :--- | :--- | :--- | | C 制造业 | 26 化学原料和化学制品制造业 | 2614 | 有机化学原料制造 | | C 制造业 | 29 橡胶和塑料制品业 | 2926 | 塑料包装箱及容器制造 | | E 建筑业 | 48 土木工程建筑业 | 4813 | 市政道路工程建筑 | ### 16.3 错误码速查表 | 错误码 | HTTP状态 | 含义 | | :--- | :--- | :--- | | `0` | 200 | 成功 | | `ERR_PARAM_001~011` | 400 | 参数校验失败(具体见第4章) | | `ERR_REG_001` | 400 | 注册审核不通过 | | `ERR_REG_002` | 409 | 信用代码已注册 | | `ERR_REG_003` | 409 | 手机号/邮箱已被占用 | | `ERR_REG_004` | 503 | 工商API服务繁忙 | | `ERR_AUTH_001` | 401 | 验证码错误/过期 | | `ERR_FILE_001` | 400 | 文件格式/大小不符 | | `ERR_OCR_001` | 400 | OCR识别失败 | | `ERR_SYS_001` | 500 | 系统内部异常 |