Files
STP/docs/architecture/详细设计/评标专家信息维护模块详细设计.md
T
weiwen_ye f24c503d9d docs(architecture): 明确专家信息维护模块中内外部专家功能适用性
- 补充集团内部专家仅适用于部分功能的说明
- 菜单栏中银行账户和安全设置标记为仅外部专家可用
- 个人资料字段增加"适用对象"列,区分内外专家
- 调整字段备注,明确双因子验证仅针对外部专家
2026-07-02 22:42:35 +08:00

22 KiB
Raw Blame History

评标专家信息维护模块详细设计

1. 概述

1.1 设计目标

评标专家信息维护模块是专家登录后管理个人档案的核心枢纽,设计目标包括:

  • 信息统一管理:集中维护个人基本信息、专业资质、执业资格、联系方式等。
  • 财务信息独立维护:管理银行账户信息,确保评审劳务报酬准确发放。
  • 安全自主可控:支持密码修改、手机/邮箱更换、登录设备管理等安全操作。

1.2 适用角色

  • 已注册并通过审核的外部评标专家。
  • 集团内部专家仅适用于部分功能。
  • 不同专家根据其专业领域和职称等级,展示差异化内容(如高级职称可参评更高级别项目)。

1.3 核心功能模块

模块 功能简述
个人资料 查看与修改基本信息(工作单位、从事专业、职称等),敏感字段变更需审核
专业资质 上传/更新职称证书、执业资格证书,AI辅助识别与真伪校验
银行账户 维护开户银行及账号(加密存储),用于劳务报酬发放
安全设置 修改密码、更换手机号/邮箱、踢出设备、查看登录日志

2. 页面布局总览

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 820" font-family="'Microsoft YaHei', sans-serif">
  <defs>
    <filter id="shadow" x="-2%" y="-2%" width="104%" height="104%">
      <feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.06"/>
    </filter>
    <filter id="shadowDeep" x="-2%" y="-2%" width="104%" height="104%">
      <feDropShadow dx="0" dy="6" stdDeviation="12" flood-color="#000" flood-opacity="0.10"/>
    </filter>
    <linearGradient id="headerBg" x1="0" y1="0" x2="1" y2="0">
      <stop offset="0%" stop-color="#1a237e"/><stop offset="100%" stop-color="#283593"/>
    </linearGradient>
    <linearGradient id="brandGrad" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" stop-color="#1a237e"/><stop offset="100%" stop-color="#283593"/>
    </linearGradient>
  </defs>
  
  <!-- 背景 -->
  <rect width="1200" height="820" fill="#f5f7fa"/>
  
  <!-- ===== 顶部导航栏 ===== -->
  <rect width="1200" height="64" fill="url(#headerBg)"/>
  <text x="40" y="42" font-size="22" font-weight="bold" fill="#fff">智慧招标平台</text>
  <text x="190" y="42" font-size="13" fill="rgba(255,255,255,0.8)">Smart Tendering Platform</text>
  
  <!-- 导航菜单 -->
  <text x="440" y="42" font-size="15" fill="rgba(255,255,255,0.8)">首页</text>
  <text x="520" y="42" font-size="15" fill="rgba(255,255,255,0.8)">招标公告</text>
  <text x="620" y="42" font-size="15" fill="rgba(255,255,255,0.8)">定标公告</text>
  <text x="720" y="42" font-size="15" fill="rgba(255,255,255,0.8)">企业新闻</text>
  
  <!-- 已登录用户 -->
  <circle cx="1030" cy="32" r="16" fill="rgba(255,255,255,0.3)"/>
  <text x="1030" y="37" text-anchor="middle" font-size="12" fill="#fff"></text>
  <text x="1060" y="37" font-size="14" fill="#fff">王建国</text>
  <text x="1110" y="37" font-size="12" fill="rgba(255,255,255,0.7)"></text>

  <!-- ===== 内容区:左侧菜单 + 右侧内容 ===== -->
  
  <!-- 左侧菜单栏(精简为4项) -->
  <rect x="40" y="90" width="220" height="690" rx="12" fill="#fff" filter="url(#shadow)"/>
  
  <!-- 专家头像 & 基本信息 -->
  <circle cx="150" cy="145" r="50" fill="#e8eaf6" stroke="#c5cae9" stroke-width="2"/>
  <text x="150" y="150" text-anchor="middle" font-size="28" fill="#1a237e" font-weight="bold"></text>
  <text x="150" y="210" text-anchor="middle" font-size="16" font-weight="bold" fill="#1a2332">王建国</text>
  <text x="150" y="235" text-anchor="middle" font-size="13" fill="#4a5568">高级工程师 · 化工专业</text>
  <rect x="80" y="250" width="140" height="24" rx="12" fill="#4caf50"/>
  <text x="150" y="267" text-anchor="middle" font-size="12" fill="#fff">✅ 专家库已入库</text>
  
  <line x1="60" y1="290" x2="240" y2="290" stroke="#f0f2f7" stroke-width="1"/>
  
  <!-- 菜单项(仅保留4项) -->
  <rect x="60" y="310" width="180" height="40" rx="8" fill="#e8eaf6"/>
  <text x="150" y="336" text-anchor="middle" font-size="14" font-weight="bold" fill="#1a237e">👤 个人资料</text>
  
  <rect x="60" y="365" width="180" height="40" rx="8" fill="#f5f5f5"/>
  <text x="150" y="391" text-anchor="middle" font-size="14" fill="#4a5568">🎓 专业资质</text>
  
  <rect x="60" y="420" width="180" height="40" rx="8" fill="#f5f5f5"/>
  <text x="150" y="446" text-anchor="middle" font-size="14" fill="#4a5568">🏦 银行账户</text>
  
  <rect x="60" y="475" width="180" height="40" rx="8" fill="#f5f5f5"/>
  <text x="150" y="501" text-anchor="middle" font-size="14" fill="#4a5568">🔐 安全设置</text>

  <!-- ===== 右侧内容区 ===== -->
  <rect x="280" y="90" width="880" height="690" rx="12" fill="#fff" filter="url(#shadow)"/>
  
  <!-- 页面标题 -->
  <text x="310" y="130" font-size="20" font-weight="bold" fill="#1a2332">👤 个人资料</text>
  <text x="310" y="158" font-size="14" fill="#8895aa">维护您的个人信息,确保资料准确无误</text>
  
  <line x1="310" y1="175" x2="1120" y2="175" stroke="#f0f2f7" stroke-width="2"/>

  <!-- 表单区(两列布局) -->
  <!-- 第一列 -->
  <text x="310" y="215" font-size="14" fill="#4a5568">真实姓名 <tspan fill="#e91e63">*</tspan></text>
  <rect x="310" y="225" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="325" y="250" font-size="14" fill="#1a2332">王建国</text>

  <text x="610" y="215" font-size="14" fill="#4a5568">性别 <tspan fill="#e91e63">*</tspan></text>
  <rect x="610" y="225" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="625" y="250" font-size="14" fill="#1a2332"></text>

  <!-- 第二行 -->
  <text x="310" y="295" font-size="14" fill="#4a5568">身份证号码 <tspan fill="#e91e63">*</tspan></text>
  <rect x="310" y="305" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="325" y="330" font-size="14" fill="#1a2332">110101********4477</text>
  <text x="560" y="330" font-size="12" fill="#4caf50">✅ 已实名认证</text>

  <text x="610" y="295" font-size="14" fill="#4a5568">出生日期</text>
  <rect x="610" y="305" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="625" y="330" font-size="14" fill="#1a2332">1975-03-07</text>

  <!-- 第三行 -->
  <text x="310" y="375" font-size="14" fill="#4a5568">工作单位 <tspan fill="#e91e63">*</tspan></text>
  <rect x="310" y="385" width="240" height="38" rx="6" fill="#ffffff" stroke="#e0e4ec"/>
  <text x="325" y="410" font-size="14" fill="#b0bbcc">请输入工作单位</text>

  <text x="610" y="375" font-size="14" fill="#4a5568">现从事专业 <tspan fill="#e91e63">*</tspan></text>
  <rect x="610" y="385" width="240" height="38" rx="6" fill="#ffffff" stroke="#e0e4ec"/>
  <text x="625" y="410" font-size="14" fill="#b0bbcc">请输入专业名称</text>

  <!-- 第四行 -->
  <text x="310" y="455" font-size="14" fill="#4a5568">技术职称 <tspan fill="#e91e63">*</tspan></text>
  <rect x="310" y="465" width="240" height="38" rx="6" fill="#ffffff" stroke="#e0e4ec"/>
  <text x="325" y="490" font-size="14" fill="#b0bbcc">请选择职称等级</text>

  <text x="610" y="455" font-size="14" fill="#4a5568">职称专业 <tspan fill="#e91e63">*</tspan></text>
  <rect x="610" y="465" width="240" height="38" rx="6" fill="#ffffff" stroke="#e0e4ec"/>
  <text x="625" y="490" font-size="14" fill="#b0bbcc">请输入职称专业</text>

  <!-- 第五行 -->
  <text x="310" y="535" font-size="14" fill="#4a5568">手机号码 <tspan fill="#e91e63">*</tspan></text>
  <rect x="310" y="545" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="325" y="570" font-size="14" fill="#1a2332">138****8000</text>
  <text x="560" y="570" font-size="12" fill="#4caf50">✅ 已验证</text>

  <text x="610" y="535" font-size="14" fill="#4a5568">电子邮箱 <tspan fill="#e91e63">*</tspan></text>
  <rect x="610" y="545" width="240" height="38" rx="6" fill="#f5f6fa" stroke="#e0e4ec"/>
  <text x="625" y="570" font-size="14" fill="#1a2332">wangjg@example.com</text>
  <text x="860" y="570" font-size="12" fill="#4caf50">✅ 已验证</text>

  <!-- 底部按钮 -->
  <line x1="310" y1="620" x2="1120" y2="620" stroke="#f0f2f7" stroke-width="2"/>
  
  <rect x="900" y="640" width="120" height="40" rx="8" fill="#e0e4ec"/>
  <text x="960" y="666" text-anchor="middle" font-size="15" fill="#666">取消</text>
  
  <rect x="1040" y="640" width="120" height="40" rx="8" fill="url(#brandGrad)"/>
  <text x="1100" y="666" text-anchor="middle" font-size="15" font-weight="bold" fill="#fff">保存修改</text>

  <!-- 右侧小滨 AI 助手 -->
  <rect x="840" y="660" width="220" height="105" rx="10" fill="#ffffff" stroke="#e0e4ec" filter="url(#shadow)"/>
  <circle cx="860" cy="685" r="14" fill="#1a237e"/>
  <text x="860" y="690" text-anchor="middle" font-size="10" fill="#fff" font-weight="bold">小滨</text>
  <text x="885" y="690" font-size="13" font-weight="bold" fill="#1a2332">AI 助手</text>
  <rect x="845" y="705" width="200" height="45" rx="6" fill="#e8eaf6" stroke="#c5cae9"/>
  <text x="860" y="725" font-size="11" fill="#1a237e">💡 温馨提示</text>
  <text x="860" y="742" font-size="10" fill="#4a5568">· 修改手机号/邮箱需双因子验证</text>
  <text x="860" y="752" font-size="10" fill="#4a5568">· 银行账号变更需验证登录密码</text>
</svg>

3. 各功能模块详细说明

3.1 左侧菜单栏

菜单项 图标 说明 高亮规则
个人资料 👤 基本信息维护(姓名、身份证、单位、职称、联系方式等) 默认高亮
专业资质 🎓 职称证书、执业资格证书的上传与更新,AI辅助识别 点击切换
银行账户 🏦 维护开户行、户名、银行账号,用于评审劳务报酬发放 仅适用外部专家
安全设置 🔐 修改密码、更换手机号/邮箱、登录设备管理、查看登录日志 密码修改和更换手机、邮箱仅适用外部专家。

3.2 个人资料(默认激活页)

页面功能

  • 展示并允许修改专家的基本档案信息。
  • 所有字段均来自注册时提交的数据,除联系方式外,其他字段(姓名、身份证、职称等)变更需经过“AI审核”或“人工复核”(与供应商营业执照变更逻辑一致,确保资质真实性)。

字段列表

字段名 组件类型 是否必填 适用对象 备注
真实姓名 只读文本 全体 变更需提交证明材料人工审核
性别 只读文本 全体 从身份证自动识别
身份证号码 只读(脱敏) 外部专家 变更需人工审核(关键标识)
出生日期 只读文本 外部专家 从身份证自动计算
工作单位 文本输入框 全体 可修改(需人工复核)
现从事专业 文本输入框 全体 可修改
技术职称 下拉选择 全体 高级/副高级/中级/初级
职称专业 文本输入框 全体 如:化学工程与工艺
手机号码 文本输入框 外部专家 修改需双因子验证(旧+新)
电子邮箱 文本输入框 外部专家 修改需双因子验证(旧+新)

关键字段变更规则

字段 变更是否需要审核 审核方式
姓名 需上传身份证正反面扫描件,AI比对+人工复核
身份证号 是(阻断) 系统唯一标识,变更走特殊流程(人工/线下)
职称/专业 需上传新职称证书扫描件,AI识别+人工审核
工作单位 人工审核(原单位离职风险)
手机/邮箱 否(即时生效) 双因子验证通过即可

3.3 专业资质

页面功能

  • 展示当前上传的职称/执业资格证书文件列表(类似供应商的资质文件管理)。
  • 支持上传新证书、重命名、删除旧证书。
  • AI 自动识别证书真伪(防篡改检测)和信息提取(证书编号、发证机关、有效期等)。

文件列表示例

文件名称 上传时间 大小 状态 操作
职称证书_教授.pdf 2026-06-15 2.1MB 已认证 重命名 / 删除
注册化工工程师资格证书.pdf 2026-05-20 3.4MB 审核中 删除

操作

  • 上传新资质文件(支持 PDF/JPG/PNG,≤20MB)。
  • 删除/重命名。
  • 点击文件名预览文件。

3.4 银行账户

页面功能

  • 维护专家的银行账户信息,用于支付评审报酬。
  • 字段:开户银行名称、开户行网点、户名、银行账号。
  • 银行账号加密存储AES-256-GCM,与全局安全策略一致)。
  • 修改需验证当前登录密码(或短信验证码)防止盗用。

字段列表

字段名 组件类型 是否必填 备注
开户银行名称 下拉选择/文本输入 如:中国银行、工商银行
开户行网点 文本输入框 如:中国银行北京分行营业部
户名 只读文本 与专家真实姓名一致(自动关联)
银行账号 文本输入框(掩码) 显示后4位,修改时需输入完整账号
确认银行账号 文本输入框(掩码) 修改时需二次输入确认

安全要求

  • 银行账号仅显示后 4 位(如 **** **** **** 8888)。
  • 修改时需进行身份二次验证(短信验证码或当前登录密码)。

3.5 安全设置

功能与供应商安全设置一致,包括:

功能项 验证强度 说明
修改登录密码 高(验证旧密码) 强制密码复杂度;修改后清除所有会话,重新登录
更换绑定手机号 最高(旧+新双因子) 新号全局唯一,30天内限3次
更换绑定邮箱 最高(旧+新双因子) 新邮箱全局唯一,30天内限3次
登录设备管理 中(登录态+二次确认) 查看在线设备列表,支持“踢出所有设备”
登录日志查看 低(仅登录态) 最近90天登录记录,异常登录自动标记(红底)

4. 关键业务流程

4.1 联系人信息变更(手机号/邮箱)流程

flowchart TD
    A[专家点击修改手机号] --> B[输入新手机号]
    B --> C[系统校验新号是否已被占用]
    C -->|已被占用| D[提示“该手机号已被其他专家绑定”]
    C -->|未被占用| E[发送验证码至旧手机]
    E --> F[专家输入旧手机验证码]
    F --> G{验证通过?}
    G -->|否| H[提示错误,可重试(5次锁定)]
    G -->|是| I[发送验证码至新手机]
    I --> J[输入新手机验证码]
    J --> K{验证通过?}
    K -->|否| L[提示错误]
    K -->|是| M[提交变更请求]
    M --> N[数据库更新手机号]
    N --> O[更新登录名(若为登录凭证)]
    O --> P[清除所有验证码缓存]
    P --> Q[记录审计日志]
    Q --> R[发送通知至新旧手机号]

4.2 资质证书更新(AI审核)流程

flowchart TD
    A[专家上传新职称证书] --> B[文件上传至OSS]
    B --> C[调用OCR服务提取文字字段]
    C --> D[AI真实性审查(ELA/翻拍检测)]
    D -->|不通过| E[驳回:证书疑似伪造或翻拍]
    D -->|通过| F[AI提取信息:证书编号/发证机关/有效期等]
    F --> G[与数据库现有字段比对]
    G --> H{关键信息是否变更?}
    H -->|否| I[仅更新文件URL]
    H -->|是| J[记录变更差异,触发人工复核]
    J --> K[推送待办至管理员]
    K --> L[管理员审核]
    L -->|通过| M[更新主表+记录审计]
    L -->|不通过| N[驳回并通知专家]

4.3 银行账户修改流程

flowchart TD
    A[专家点击“修改银行账户”] --> B[弹窗显示当前账户信息(脱敏)]
    B --> C[输入新开户行、新账号、确认账号]
    C --> D[点击“下一步”]
    D --> E[发送短信验证码至绑定手机]
    E --> F[输入短信验证码]
    F --> G{验证通过?}
    G -->|否| H[提示错误,可重试]
    G -->|是| I[提交变更请求]
    I --> J[数据库更新银行账号(加密存储)]
    J --> K[记录审计日志(含新旧账号)]
    K --> L[发送通知至手机/邮箱]

4.4 安全设置 —— 修改密码流程

sequenceDiagram
    participant U as 专家
    participant FE as 前端
    participant Svc as 账户服务
    participant DB as 数据库
    participant Cache as Redis

    U->>FE: 填写旧密码+新密码
    FE->>FE: 前端校验(非空/强度/新旧不同)
    FE->>Svc: PUT /api/v1/expert/password
    Svc->>DB: 查询当前密码哈希
    DB-->>Svc: password_hash
    Svc->>Svc: 比对旧密码
    alt 旧密码错误
        Svc->>Cache: INCR fail_count
        alt fail_count >= 5
            Svc-->>FE: 403 账号已锁定30分钟
        else <5
            Svc-->>FE: 401 当前密码错误
        end
    else 旧密码正确
        Svc->>Cache: DEL fail_count
        Svc->>Svc: 新密码哈希
        Svc->>DB: UPDATE password_hash
        Svc->>Cache: DEL 所有会话
        Svc-->>FE: 200 成功,请重新登录
        FE->>FE: 清除本地Token,跳转登录页
    end

5. 数据模型

5.1 专家信息表 t_expert_profile(核心字段)

字段名 类型 约束 说明
expert_id VARCHAR(32) PK 专家档案编号
user_id VARCHAR(32) FK 关联STP用户账号表
real_name VARCHAR(64) NOT NULL 真实姓名
id_card_no VARCHAR(128) NOT NULL, UNIQUE 身份证号(AES-256加密)
id_card_md5 CHAR(32) UNIQUE MD5盲索引
gender TINYINT 1-男,2-女
birth_date DATE 出生日期
company VARCHAR(128) 工作单位
profession VARCHAR(64) NOT NULL 从事专业
title VARCHAR(32) NOT NULL 职称等级
title_major VARCHAR(64) 职称专业
phone VARCHAR(128) NOT NULL, UNIQUE 手机号(加密)
phone_md5 CHAR(32) UNIQUE MD5
email VARCHAR(128) NOT NULL 邮箱
bank_name VARCHAR(64) 开户银行
bank_branch VARCHAR(128) 开户行网点
bank_account VARCHAR(128) 银行账号(加密)
bank_account_md5 CHAR(32) MD5
status VARCHAR(20) NOT NULL ACTIVE/LOCKED/REJECTED
activated_at DATETIME 激活时间
updated_at DATETIME 更新时间

5.2 资质证书表 t_expert_qualification

字段名 类型 说明
id BIGINT PK
expert_id VARCHAR(32) FK
file_name VARCHAR(256) 文件显示名称
file_url VARCHAR(512) OSS存储URL
file_size BIGINT 文件大小(字节)
ocr_result JSON OCR识别结果(含证书编号、发证机关、有效期)
audit_status VARCHAR(20) PASS / PENDING / FAIL
audit_comment TEXT 审核备注
upload_time DATETIME 上传时间
status VARCHAR(20) ACTIVE / DELETED

6. API 接口设计

6.1 获取专家信息

项目 内容
路径 GET /api/v1/expert/profile
响应 返回完整的专家信息(敏感字段脱敏)

6.2 更新专家信息(普通字段)

项目 内容
路径 PUT /api/v1/expert/profile
请求体 { "company": "新单位", "profession": "新专业" }
限制 姓名、身份证号、职称不允许通过此接口修改(或触发审核)

6.3 更新手机号/邮箱

项目 内容
路径 PUT /api/v1/expert/contact
请求体 { "field":"phone", "newValue":"...", "oldOtpToken":"...", "newOtpToken":"..." }

6.4 上传资质证书

项目 内容
路径 POST /api/v1/expert/qualification
方法 multipart/form-data
响应 { "fileId":"...", "auditStatus":"PENDING" }

6.5 删除资质证书

项目 内容
路径 DELETE /api/v1/expert/qualification/{fileId}

6.6 更新银行账户

项目 内容
路径 PUT /api/v1/expert/bank-account
请求体 { "bankName":"...", "bankBranch":"...", "bankAccount":"...", "confirmAccount":"...", "smsCode":"..." }

6.7 修改密码

项目 内容
路径 PUT /api/v1/expert/password
请求体 { "oldPassword":"...", "newPassword":"..." }

7. 业务规则汇总

ID 规则 适用场景
R01 身份证号全局唯一,不可重复注册(包括审核中状态) 注册/信息变更
R02 修改手机号/邮箱必须双因子验证(旧+新),即时生效 联系人变更
R03 修改姓名、职称、身份证号必须经 AI 审核或人工复核 个人资料变更
R04 银行账号加密存储,修改需短信验证码二次确认 银行账户
R05 上传资质证书自动触发 AI 真实性审查(ELA/翻拍检测) 专业资质
R06 所有信息变更均需记录审计日志(哈希链防篡改) 全场景
R07 专家账户锁定后,不可参与评标抽取(需管理员解封) 违规处理
R08 修改银行账号后,同步通知管理员(用于财务系统更新) 银行账户

8. 安全与合规

安全维度 措施
敏感信息加密 身份证号、手机号、银行账号使用 AES-256-GCM 字段级加密
脱敏展示 身份证号 110101********4477,手机号 138****8000,银行账号 **** **** **** 8888
审计追溯 所有变更操作(含IP、时间、新旧值)写入哈希链,保留≥7年
密码安全 同平台全局策略(Argon2id哈希,强度要求≥8位含大小写数字特殊字符)