Files
guoju0808/详细设计方案.md
T
郭庆泰 5a0a892574 feat: 邀请函邮件发送 + 首次设密/密码为空 + 姓名单一可信源
邀请发送 (菜单暂隐藏, 待确认参数见 发送邀请-待确认参数.md):
- 后端: BizInvite / BizInviteRecipient + Controller/Service/Mapper/XML
- 邮件: InviteMailSender (spring-boot-starter-mail SMTP) + application*.yml 邮件配置
- 上传进度: UploadProgressRegistry + UploadProgressController
- 前端: InviteList / InviteNew / InviteDetail / InviteView + api/business/invite.js
- 原型: proto/html/components/invite-detail / new-invitation / send-invitation

登录/账号:
- 首次设密: /getInfo 返回 isPasswordEmpty, SysProfileController 密码为空时跳过旧密码校验, ForcePasswordDialog 强制弹窗
- 姓名单一可信源 resolveDisplayName: doctor→biz_expert.name, sponsor/executor→biz_person.name, 其余回退 nick_name
- OA compliance 门禁改为按手机号查 ecology 视图 (不再限定 manager/leader)

其它:
- OSS zip 在线查看 (列清单+取单文件, 公开只读) + SecurityConfig permitAll
- doctor 项目详情 ProjectDetail.vue
- 数据库/测试/设计文档 (md) 入库
2026-09-10 20:40:49 +08:00

716 lines
45 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 详细设计方案
> 版本:V2.0
> 范围:合规管理平台(业务系统)整体设计
> 读者:甲方 / 业务方
> 配套文档:《数据库设计文档 V2.0》(表结构与字段细节,本文不再重复展开)
---
## 一、概述
### 1.1 项目定位
本平台是一个面向「医疗合规项目」的**全流程协同管理平台**,覆盖从项目申报、立项、分配、公示、执行、材料审核、结算到完结的完整业务闭环。平台连接六类角色,把原本分散在线下、依赖人工催办与纸质签字的环节统一搬到线上,实现流程可追踪、材料可归档、费用可核算、签字可验真。
### 1.2 建设目标
1. **全流程线上化**:投稿、立项、分配、公示、报名、执行、材料审核、结算、完结,全程在线流转。
2. **多角色协同**:医生、执行方、支持方、合规人员、项目负责人、后台管理员,各司其职、权限隔离。
3. **材料与费用规范化**:会议材料分类上传、发票自动识别、劳务费 / 会务费自动汇总。
4. **签署电子化**:医生在线填写劳务信息、手写签名,自动生成 PDF 劳务协议并归档。
5. **消息实时触达**:短信 + 站内信 + 页面角标实时推送,关键节点主动通知。
### 1.3 术语定义
| 术语 | 含义 |
|---|---|
| 医生(专家) | 参与项目 / 会议的医务人员,注册后需资质审核通过方可登录 |
| 执行方 | 承接项目并负责会议执行、材料上传、建会的单位(含主账号 + 执行人员子账号) |
| 支持方 | 项目申办 / 资金支持单位,承担材料二级审核(监察)职责 |
| 合规人员 | 平台核心审核与项目管理角色,负责材料一级审核、结算、完结 |
| 监察员 | 支持方下派到项目 / 会议的监督人员,负责材料二级审核 |
| 项目负责人 | 只读查看本人负责项目的角色 |
| 劳务电子签 | 医生在线签署劳务协议、生成 PDF 归档的全过程 |
| 策划方案 | 医生 / 执行方 / 支持方投稿的项目方案,审核通过后立项为正式项目 |
| 专项计划 | 项目方向的选项来源,由后台管理员维护 |
| 主账号 / 子账号 | 执行方、支持方机构的账号形态:主账号代表机构,子账号为机构下属人员 |
---
## 二、系统总体设计
### 2.1 技术架构
系统采用「前后端分离」架构,面向不同使用场景提供多个入口:
```
┌─────────────────────────────────────────────────────┐
│ 前端(多端) │
│ 管理后台 Web(六类角色) │ 公开门户(公示/注册/协议) │
│ H5 移动端(扫码签署 / 拍照上传) │
└───────────────────────────┬─────────────────────────┘
│ HTTP 接口(JWT 鉴权)
┌───────────────────────────▼─────────────────────────┐
│ 业务后端(API) │
│ 账号权限 │ 项目 │ 会议 │ 材料 │ 审核 │ 费用 │ 电子签 │ 消息 │
└───────┬──────────────┬───────────────┬───────────────┘
│ │ │
┌────▼───┐ ┌─────▼─────┐ ┌─────▼─────┐
│ 数据库 │ │ 对象存储 │ │ 外部服务 │
│(业务数据)│ │(文件/PDF) │ │ OCR/短信/微信│
└────────┘ └───────────┘ └───────────┘
```
- **后端**Java + Spring Boot,业务模块统一以 `/business/*` 对外提供接口,鉴权采用 JWT。
- **前端**Vue 3 + Element Plus,按角色划分为六套后台菜单 + 一套公开门户 + H5 移动端。
- **数据库**:MySQL,业务表逻辑删除、快照留档。
- **文件**:统一对象存储(OSS),材料、凭证、PDF 协议、海报等文件云端存储。
- **外部服务**:发票 OCR 识别、短信验证码、微信分享、OA(ecology)项目信息拉取。
### 2.2 角色与账号模型
平台共六类角色,角色是账号的固有属性,由 `sys_user.role_type` 单一字段确定:
| 角色 | 业务定位 | 账号形态 |
|---|---|---|
| 后台管理员(admin) | 系统维护、基础数据、后台用户 | 无企业归属 |
| 合规人员(manager) | 核心审核与项目管理 | 无企业归属 |
| 医生(doctor) | 投稿、参会、签署劳务 | 无企业归属 |
| 执行方(executor) | 承接项目、建会、上传材料 | 主账号(注册即建单位)+ 子账号(执行人员) |
| 支持方(sponsor) | 申办、监察、查看项目 | 主账号 + 子账号(监察员) |
| 项目负责人(leader) | 只读查看负责的项目 | 无企业归属 |
执行方、支持方机构内部区分「主账号(MAIN)/ 子账号(SUB)」:
- **主账号**:代表机构,注册时创建,关联到机构(`biz_org.user_id`)。
- **子账号**:机构下属人员,通过 `parent_user_id` 关联到主账号,数据权限按「本人」严格隔离。
### 2.3 功能架构总览
| 功能域 | 核心能力 |
|---|---|
| 门户与访问 | 首页、项目公示、公示详情、注册、登录、协议、专项计划 |
| 账号与组织 | 用户 / 角色 / 机构 / 人员 / 科室职称字典管理 |
| 医生管理 | 医生注册、资质审核、账号开通、档案维护 |
| 策划方案 | 医生 / 执行方 / 支持方投稿、合规审核、专项计划维护 |
| 项目管理 | 立项、分配、公示、意向、报名、评分 |
| 会议管理 | 建会、参会人、材料、发票、两级审核、费用、结算、完结 |
| 劳务电子签 | 推送签署、填写劳务信息、手写签名、PDF 归档 |
| 消息通知 | 站内信、短信、页面角标实时推送 |
| 内容管理 | 协议文章、公益支持函、邀请函、劳务协议模板 |
---
## 三、账号与认证设计
### 3.1 登录(短信验证码登录)
平台采用**短信验证码登录**(无密码登录),接口如下:
| 接口 | 方法 | 说明 |
|---|---|---|
| `/business/auth/smsSendCode` | POST | 发送登录短信验证码(手机号须已注册;合规人员 / 项目负责人可从 OA 视图自动建号后放行发码) |
| `/business/auth/smsLogin` | POST | 校验短信验证码,颁发 JWT Token |
短信验证码的通用发送 / 校验接口(登录与各注册场景共用):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/business/sms/send` | GET | 发送短信验证码(返回 uuid,前端校验时回传) |
| `/business/sms/verify` | POST | 校验短信验证码 |
| `/business/auth/registerSendSms` | POST | 注册专用发码(发码前校验手机号未被注册) |
短信验证码登录的后端校验链路(按顺序):
1. 校验手机号格式(11 位)与验证码非空;
2. 校验短信验证码(`verifyCode`);
3. 按手机号查用户(合规人员 / 项目负责人若不在本地,会从 OA ecology 视图自动建档);
4. 校验账号状态:已删除、已停用均拒绝登录;
5. 子账号专属校验:主账号被停用 / 不存在时拒绝登录(「您所属的机构已禁用」);
6. 医生待审核拦截:`role_type=doctor` 且档案审核状态为「待审核」时拒绝登录(「您的信息正在审核中」);
7. 颁发 JWT Token 并记录登录日志。
### 3.2 注册(三类主体)
| 主体 | 接口 | 注册结果 |
|---|---|---|
| 医生(专家) | `/business/auth/registerExpert` | 创建 `sys_user`(用户名 = 手机号,`role_type=doctor`)+ 医生档案(状态 = 待审核);审核通过前不能登录 |
| 执行方(供应商) | `/business/auth/registerExecutor` | 创建主账号 `sys_user``role_type=executor`+ 执行机构 `biz_org` + 本人人员档案 |
| 支持方 | `/business/auth/registerSponsor` | 从已有支持方企业中选一家,创建**子账号** `sys_user``account_type=SUB``role_type=sponsor`+ 人员档案 |
三类注册均需:短信验证码校验、用户名 / 手机号唯一性校验、密码长度(6–20 位)校验。医生注册额外要求手机号格式与密码 6–20 位。
### 3.3 忘记密码
| 接口 | 方法 | 说明 |
|---|---|---|
| `/business/auth/forgotSendSms` | POST | 发送短信(手机号须已注册) |
| `/business/auth/resetPassword` | POST | 校验短信验证码后重置密码 |
### 3.4 登录状态与角色跳转
登录成功后,前端根据返回的用户角色(`role_type` 单一可信源)跳转到各自首页:
| 角色 | 首页 |
|---|---|
| admin | `/admin/workbench`(工作台) |
| manager | `/manager/workbench`(工作台) |
| doctor | `/doctor/home`(首页) |
| executor | `/executor/overview`(首页) |
| sponsor | `/sponsor/home`(首页) |
| leader | `/leader/home`(首页) |
---
## 四、角色权限与数据可见性
### 4.1 权限矩阵
| 能力 | 后台管理员 | 合规人员 | 医生 | 执行方 | 支持方 | 项目负责人 |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| 维护科室 / 职称字典(写) | ✓ | — | — | — | — | — |
| 维护专项计划 | ✓ | — | — | — | — | — |
| 维护协议文章 | ✓ | — | — | — | — | — |
| 配置劳务协议模板 | ✓ | — | — | — | — | — |
| 后台新建用户 | ✓ | — | — | — | — | — |
| 维护机构 / 人员 | ✓ | ✓ | — | 本人机构 | 本人机构 | — |
| 审核医生资质 | ✓ | ✓ | — | — | — | — |
| 新建 / 编辑项目 | ✓ | ✓ | — | — | — | — |
| 删除项目 | ✓ | — | — | — | — | — |
| 删除公示公告 | ✓ | ✓ | — | — | — | — |
| 分配执行单位 / 场次金额 | ✓ | ✓ | — | — | — | — |
| 分配监察员 | — | — | — | — | ✓ | — |
| 分配执行人 | — | — | — | ✓ | — | — |
| 投稿策划方案 | — | — | ✓ | ✓ | ✓ | — |
| 审核策划方案 | — | ✓ | — | — | — | — |
| 建会 / 编辑会议 | ✓ | ✓ | — | ✓ | — | — |
| 删除会议 | ✓ | ✓ | — | — | — | — |
| 上传 / 提交材料 | — | — | — | ✓ | — | — |
| 材料一级审核(合规) | — | ✓ | — | — | — | — |
| 材料二级审核(监察) | — | — | — | — | ✓ | — |
| 结算 / 完结 / 解冻 | ✓ | ✓ | — | — | — | — |
| 项目评分 | ✓(按合规口径) | ✓ | — | — | ✓ | — |
| 签署劳务(电子签) | — | — | ✓ | — | — | — |
| 推送电子签 / 邀请参会 | ✓ | ✓ | — | — | — | — |
### 4.2 数据可见性(数据隔离规则)
数据隔离在**后端**强制实施,每个角色的可见范围如下:
| 角色 | 项目可见范围 | 会议可见范围 |
|---|---|---|
| 后台管理员 | 全部项目 | 全部会议 |
| 合规人员 | 本人创建的项目(`create_user_id` | 本人创建项目下的会议 |
| 医生 | 本人报名的项目(`biz_execution_intent` 反查) | 本人参加的会议(参会人中间表反查) |
| 执行方(主账号) | 分配给本单位的项目(执行方分配 / 执行单位归属) | 本单位执行单位下的会议 |
| 执行方(子账号 / 执行人) | 被分配为执行人的项目(严格隔离,不回退主账号) | 本人创建的会议 |
| 支持方(主账号) | 本单位申办的项目(`sponsor_admin_user_id` / `sponsor_org_id` | 申办项目下的会议 |
| 支持方(子账号 / 监察员) | 被分配为监察员的项目(严格隔离,不回退主账号) | 被分配监察的会议 |
| 项目负责人 | 本人负责的项目(`lead_user_id` | 本人负责项目下的会议 |
补充可见性要点:
- **医生**:仅可见「我参与的会议」「我报名的项目」及本人投稿。
- **执行方子账号**:场次 / 金额按「本公司(主账号)维度」聚合展示,但会议列表范围仍是「本人创建的会议」。
- **支持方子账号**:监察员仅可见被分配监察的会议;支持方查看会议参会人时,敏感信息(姓名 / 手机号 / 银行卡号 / 账户名称 / 身份证号)在后端脱敏后下发。
- **支持方**:已完结且未「开通」的项目在支持方项目列表中不可见(项目「开通」开关,见 5.5 节)。
- **项目负责人**:全程只读。
- **门户(匿名)**:仅可访问公示、注册、登录、协议等公开内容。
---
## 五、功能模块详细设计
### 5.1 公开门户
公开门户无需登录,主要接口:
| 接口 | 方法 | 说明 |
|---|---|---|
| `/business/public/index` | GET | 首页数据(已发布项目、策划方案、机构介绍) |
| `/business/public/announcements` | GET | 已发布项目公示列表(按发布时间倒序) |
| `/business/public/project/{projectId}` | GET | 公示详情 |
| `/business/public/supportLetter/{annId}` | GET | 支持函详情 |
| `/business/public/invitation/{annId}` | GET | 邀请函详情 |
| `/business/public/article/{type}` | GET | 协议 / 隐私政策(`type=agreement/privacy` |
| `/business/public/specialPlan/list` | GET | 专项计划列表 |
| `/business/public/specialPlan/{id}` | GET | 专项计划详情 |
| `/business/public/biddingNotice` | GET | 按项目编号查外部招标平台公告并返回跳转地址 |
| `/business/public/wx/jssdk` | GET | 微信 JS-SDK 分享签名配置 |
| `/business/auth/sponsorOrgOptions` | GET | 支持方注册企业下拉(匿名) |
### 5.2 账号与组织管理
**机构管理**(支持方 / 执行方共用,`/business/org`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/list` | GET | 机构列表(按 `orgType` 区分支持方 / 执行方) |
| `/sponsorOptions``/executorOptions` | GET | 机构下拉选项(供项目分配弹窗) |
| `/myCompany` | GET | 当前登录支持方所属公司(供账号页回显) |
| `/add``/edit` | POST / PUT | 新增 / 编辑机构 |
| `/toggleStatus` | PUT | 启用 / 禁用机构(同步主账号状态) |
| `/remove` | DELETE | 删除机构 |
| `/importTemplate``/importData` | GET / POST | 机构批量导入(只导机构,不建人员账号) |
**人员管理**`/business/person`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/list` | GET | 人员列表(主账号自动隔离到「本人 + 子账号」对应人员) |
| `/sponsorList``/executorList` | GET | 支持方 / 执行方端专属人员列表(按机构圈人) |
| `/add` | POST | 新建人员(同时创建 `sys_user` 子账号,默认密码 123456) |
| `/edit``/remove` | PUT / DELETE | 编辑 / 删除人员 |
| `/profile` | PUT | 个人资料编辑(本人姓名 / 手机号) |
| `/changeAdmin` | PUT | 更换机构管理员(人员晋升为 MAIN,原管理员降为 SUB) |
| `/resetPassword` | PUT | 重置人员登录密码(默认 123456) |
| `/sponsorImport``/executorImport` | POST | 人员批量导入(executor 模板多一个「邮箱」必填列) |
**业务字典**(科室 / 医生职称,`/business/dict`):读接口(list / active / getById)对所有登录用户开放;写接口(POST / PUT / DELETE)仅后台管理员可操作。
**后台新建用户**`/business/adminUser/create`):仅后台管理员可调用,按角色级联创建用户。
### 5.3 医生(专家)管理
医生档案是劳务结算与电子签的数据源,接口(`/business/expert`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/list` | GET | 医生列表 |
| `/getInfo/{expertId}` | GET | 医生详情 |
| `/profile` | GET | 当前登录医生的档案(按 userId 路由) |
| `/byPhone/{phone}` | GET | 按手机号查医生(参会人弹窗放大镜回填) |
| `/add` | POST | 新建医生(同时创建 `sys_user`,用户名 = 密码 = 手机号) |
| `/edit` | PUT | 编辑医生档案 |
| `/status` | PUT | 启用 / 禁用(同步 `biz_expert.status` + `sys_user.status` |
| `/profile`(PUT) | PUT | 医生个人档案更新(后端强制注入当前用户) |
| `/remove` | DELETE | 删除医生 |
| `/export` | POST | 导出医生列表 |
| `/importTemplate``/importData` | GET / POST | 医生批量导入 |
医生档案关键字段:姓名、手机号、工作单位、科室、职称、地区、身份证号、银行卡号、开户行、执业证书 / 职称证书附件、审核状态(待审核 / 通过 / 拒绝)、启停状态。
### 5.4 策划方案与专项计划
**策划方案**`/business/projectPlan`):医生、执行方、支持方均可投稿(`isSubmitterRole` = 非 admin / manager),投稿角色只能看到 / 只能改自己投的稿(后端强制 `submitter_id` 写自己);管理角色(admin / manager)查看时排除未提交草稿(`status='0'`),用于审核。
- 投稿角色投稿默认状态「未提交」,提交后进入「待审核」;
- 合规人员审核通过时填写项目编号,方案立项为正式项目。
**专项计划**`/business/specialPlan`):后台管理员维护「项目方向」选项(`/list``business:specialPlan:list` 权限;`/options` 对登录用户开放供下拉填充)。作为投稿与立项的选项来源。
### 5.5 项目管理
项目管理接口(`/business/project`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/list` | GET | 项目列表(manager 只看本人创建,leader 只看本人负责) |
| `/myProjects` | GET | 我报名的项目(`biz_execution_intent` 反查) |
| `/sponsorList` | GET | 支持方项目列表(MAIN / SUB 分流) |
| `/executorList` | GET | 执行方项目列表(主账号 / 执行人分流) |
| `/projectNoOptions` | GET | 项目编号下拉 |
| `/getInfo/{projectId}` | GET | 项目详情 |
| `/assignedSessions` | GET | 执行方建会「总场次」口径(分配给本单位的场次) |
| `/add``/edit` | POST / PUT | 新建 / 编辑项目 |
| `/remove` | DELETE | 删除项目(仅 admin,软删除级联) |
| `/announcement` | DELETE | 删除公告(admin / manager |
| `/assigns` | GET / POST / DELETE | 执行方分配(查 / 保存 / 清空) |
| `/sponsorAssign``/sponsorAssigns` | POST / GET | 支持方分配监察员 |
| `/executorAssign``/executorAssigns` | POST / GET | 执行方分配执行人 |
| `/listByRole` | GET | 按 `role_type` 查用户列表(下拉用) |
| `/sponsorAssignBatch` | POST | 支持方批量分配监察员(多项目) |
| `/rate``/ratings` | POST / GET | 项目评分(写入 / 查询) |
| `/export``/ratingExport``/signupExpertExport` | POST | 项目 / 评价 / 报名专家导出 |
**项目分配**要点:
- 合规人员(或管理员)给项目分配执行单位,按场次 + 金额拆分;已结题项目不能再分配。
- 支持方给项目分配监察员(一项目支持多名监察员);执行方给项目分配执行人。
- 分配结果会向被分配方发送站内信通知(内容未变化时不重复通知)。
**项目评分**要点:
- 评分人角色由后端按登录人 `role_type` 派生(不信任前端):admin / manager → 合规口径(`manager`),sponsor → 支持方口径(`sponsor`),其他角色不可评分。
- 评分维度 4 个:质量、响应、配合、合规。
- 聚合分 = 该角色所有评分记录 4 维度值的平均(保留 1 位小数,多人评分取平均而非覆盖),实时回写到项目 `manager_score` / `sponsor_score`
- 评分明细公开可读(任何角色可查 `GET /ratings`)。
**项目公示与意向**
- 项目发布(`is_published`)后进入门户「项目公示」。
- 公示详情页面向访客提供两个匿名意向入口:公益支持(支持意向)、项目执行申请(执行意向),接口为 `/business/publicity/supportIntent``/business/publicity/executionIntent`(提交时按 `projectId + 手机号` 查重,已登录自动回填 `user_id`)。
- 医生「立即报名」走 `/business/executionIntent/signup`(写入报名意向,按 `userId + projectNo` 查重)。
- 合规人员可查看、导出支持意向 / 执行意向数据(`/business/publicitySupportIntent``/business/publicityExecutionIntent`)。
**项目开通**
- 经理可对项目「开通」(置 `open_status=Y` 并设置开通截止日 `open_deadline`),到期(截止日 ≤ 当天)由后台每天 00:05 自动回收为「未开通」。
- 已完结且未「开通」的项目对支持方不可见(与结题状态配合,控制支持方可见范围)。
**项目金额与进度口径**(查询时实时汇总,非静态落库):
- 项目总金额 / 可用金额 / 已付劳务费 / 已付会务费为查询时实时计算(按分配与会议费用汇总反推),避免人工结算回写不一致。
- 已执行场次 / 待执行场次按项目下会议执行状态实时聚合(「冻结中」计入已执行)。
### 5.6 会议管理
会议管理接口(`/business/meeting`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/list` | GET | 会议列表(按角色数据隔离) |
| `/getInfo/{meetingId}` | GET | 会议详情(executor 返回分配给本单位的场次作为总期数) |
| `/add``/edit` | POST / PUT | 建会 / 编辑(executor 有期数上限与重复校验) |
| `/generate-poster` | POST | 生成会议日程海报(叠加会议信息 → 上传 OSS) |
| `/remove` | DELETE | 删除会议(admin / manager,软删除级联 5 张子表) |
| `/submit-material` | POST | 执行方提交材料(劳务 / 会务分轨多选) |
| `/audit-compliance` | POST | 材料一级审核(合规人员,分轨) |
| `/batch-audit-compliance` | POST | 批量材料一级审核(合规人员) |
| `/audit-supervision` | POST | 材料二级审核(支持方监察员,分轨) |
| `/settle``/finish``/unfreeze` | POST | 结算 / 完结 / 解冻(manager / admin |
| `/audit-trail` | GET | 审核轨迹(审核日志列表) |
**建会校验**(执行方):执行机构人员建会时,会议期数不得超过分配给本公司的场次;本机构已创建同项目、同期数的会议则拒绝重复;会议时间区间必须在项目起止时间区间内(闭区间)。
**参会人管理**`/business/meetingAttendee`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/unsigned` | GET | 当前用户「待签署」的会议(用于医生工作台) |
| `/invited` | GET | 当前用户「待参加」的会议 |
| `/invitation/{attendeeId}` | GET | 会议邀请函详情(仅参会人本人可见,点开即自动报名) |
| `/list/{meetingId}` | GET | 某会议全部参会人(支持方查看时脱敏) |
| `/add` | POST | 按手机号新增参会人(定位 / 新建 `sys_user` 医生账号) |
| `/edit``/remove` | PUT / DELETE | 编辑 / 删除参会人 |
| `/diff` | POST | 新增 / 编辑前比对医生档案,返回不一致字段(前端二次确认) |
| `/esign` | POST | 推送电子签(逐条发短信 + 站内信 + 置 `is_esigned` |
| `/invite` | POST | 邀请参会(逐条发站内信 + 置 `is_invited` |
| `/handsign` | PUT | 更新手写签名(Base64 |
| `/laborProtocol` | PUT | 更新劳务协议 URL(首次回填时发「待签」通知) |
| `/importTemplate``/importData` | GET / POST | 参会人批量导入(两段式:dry-run 比对 → force 入库) |
| `/export` | POST | 导出参会人档案 |
| `/agreementTemplate``/uploadAgreements` | GET / POST | 劳务协议目录模板下载 / zip 上传回填 |
| `/expertPhotoTemplate``/uploadExpertPhotos` | GET / POST | 专家照片目录模板下载 / zip 上传回填 |
参会人记录包含**签字快照**(姓名、手机号、单位、科室、职称、身份证、银行卡、开户行、账户名称等,从医生档案预填、可改)与**劳务信息**(劳务形式、应发金额、个税、实发金额、增值税及附加、摘要、现场照片),以及签字结果(手写签名、签字时间、签字 IP、劳务协议 URL、脱敏版协议 URL)。
**会议材料**`/business/meetingMaterial`,单表设计,GET 查 / PUT 全删全插):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/{meetingId}` | GET | 查该会议所有材料记录 |
| `/{meetingId}` | PUT | 保存材料(全删全插,`creator_id` 后端兜底) |
| `/saveVouchers` | POST | 合规 / 管理员随时保存付款凭证(劳务 + 会务凭证) |
| `/cameraUpload` | POST | 扫码拍照回传(H5 端直传 OSS 后回传 URL,白名单校验) |
| `/downloadZip``/downloadLaborZip` | GET | 下载会务 / 劳务材料 zipadmin / manager |
| `/batchDownloadZip``/batchDownloadLaborZip` | POST | 多会议合并下载(admin / manager |
| `/serviceTemplate``/uploadServiceMaterials` | GET / POST | 会务材料目录模板下载 / zip 上传回填 |
材料分为 4 大类、17 子类:
| 大类 | 子类 |
|---|---|
| 会务材料(SERVICE) | 物料制作、酒店、大交通、小交通、执行、设计、其他、结算、发票(`M_*` |
| 劳务材料(LABOR) | 明细、协议、企业效益、电子签到、签到表、全景、专家照片(`L_*` |
| 会务凭证(SERVICE_VOUCHER | `SV_PAYMENT` |
| 劳务凭证(LABOR_VOUCHER | `LV_PAYMENT` |
**发票识别**`/business/meeting/invoice`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/recognize` | POST | 提交发票识别(后台异步 OCR,zip 自动解压;替换场景携带 `oldMaterialId` 先清旧发票) |
| `/list` | GET | 查某会议下所有发票明细 |
**会议级分配**`/business/meeting/supervisor``/business/meeting/executor`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/business/meeting/supervisor/list/{meetingId}` | GET | 查该会议分配的监察员 |
| `/business/meeting/supervisor/{meetingId}` | PUT | 分配监察员(全删全插,传入支持方企业 `org_id` 列表) |
| `/business/meeting/executor/list/{meetingId}` | GET | 查该会议分配的执行人员 |
| `/business/meeting/executor/{meetingId}` | PUT | 分配执行人员(全删全插,传入执行方企业 `org_id` 列表) |
会议级监察员与项目级监察员共同决定「材料二级审核」的授权主体:项目级监察员 / 会议级监察机构 / 支持方主账号三类主体均可监察。
**批量上传回填机制**(劳务协议 / 专家照片 / 会务材料共用):目录模板下载 → 本地按模板归档 → zip 上传 → 后台异步解压、逐条回填。上传接口返回 `jobId`,前端轮询 `GET /business/upload/progress/{jobId}`(返回已完成 / 总数 / 是否结束 / 错误 / 结果)直至结束,拿到逐条成功 / 失败结果。
### 5.7 材料两级审核
会议材料(劳务材料 + 会务材料)提交后经两级审核,劳务 / 会务两轨独立流转:
```
执行方提交材料(分轨:劳务 LABOR / 会务 SERVICE,可多选)
→ ① 合规人员审核(一级,逐轨)
├─ 拒绝 → 退回执行方(意见必填,提交截止时间重新计算)
└─ 通过 → 进入二级
→ ② 支持方监察员审核(二级,逐轨)
├─ 拒绝 → 退回执行方并通知(待整改)
└─ 通过 → 审核通过,进入待结算(并写入监察意见)
```
- 每轨单轨状态机:`未提交(N) → 已提交待合规审(C0) → 已通过合规待支持方审(C1) → 审核通过(A)`,任一步可被 `退回(R)` 打断。
- 合规人员支持**批量审核**(一次对多个会议的合规审中材料执行同一结果,逐条处理、状态不符跳过)。
- 每次审核动作均记录审核日志,同时保存当时各角色看到的阶段状态快照,形成完整追溯链。
- 支持方监察权限与列表可见性同源:项目级监察员 / 会议级监察机构 / 支持方主账号三类主体均可监察。
### 5.8 费用汇总与结算
**费用口径**
- 劳务费 = 参会人应发金额(`fee_pre_tax`)合计;
- 会务费 = 会议发票(`M_INVOICE`)及子类发票金额合计;
- 总费用 = 劳务费 + 会务费。
**费用汇总**:材料保存 / 发票 OCR 完成后立即同步重算;后台每分钟扫描 `fee_calc_status=0` 的会议兜底重算(多线程无锁、幂等)。费用汇总状态 `fee_calc_status``0` 待汇总(费用变化后重置)、`1` 已汇总;结算要求已汇总完成(`fee_calc_status=1`)。
**结算流程**(合规人员 / 管理员手动点击):
1. 前置:劳务、会务两轨材料均已「审核通过」;
2. 前置:会议费用已汇总完成(`fee_calc_status=1`);
3. 前置:劳务凭证(`LV_PAYMENT`)、会务凭证(`SV_PAYMENT`)均已上传保存(凭证由合规人员在「凭证」标签页随时上传保存,结算时校验是否已存在);
4. 结算即终态:结算时直接落「已结算」+「已完结」标记(省去二次完结动作)。
**解冻**:会议冻结后,合规 / 管理员可手动解冻,清除冻结标记、保留冻结历史(列表据此显示「超时提交」),提交截止时间重新计算。
### 5.9 劳务电子签
参会医生在会议执行后完成劳务签署,全流程线上化。签署接口(`/business/sign`):
| 接口 | 方法 | 说明 |
|---|---|---|
| `/info?attendeeId=X` | GET | 拉取填写页全部数据 |
| `/resolve?meetingId=X` | GET | 扫码入口(只有 meetingId 时返回会议信息与参会人 id) |
| `/saveProfile` | POST | 保存医生填写的劳务字段 |
| `/contract?attendeeId=X` | GET | 拉取完整协议 HTML(占位符已替换) |
| `/submit` | POST | 提交签字(手写签名 + 协议正文 → 生成 PDF 归档) |
流程:
1. **推送电子签**:管理方在会议详情向参会医生发起电子签,医生收到短信与站内信(含签署链接)。
2. **填写劳务信息**:医生填写姓名、手机号、单位、科室、职称、身份证附件、银行卡等劳务信息。
3. **手写签名**:展示劳务协议正文,医生在手写签名画板签名确认(记录签字时间与 IP)。
4. **生成 PDF**:系统按劳务协议模板自动填入信息,生成 PDF 劳务协议并归档(同时生成脱敏版协议)。
5. **查看归档**:签署后医生可查看 / 下载签字 PDF;重复打开链接直接展示已签协议。
### 5.10 消息通知
- **站内信**`/business/message`):个人消息中心,含未读统计、单条 / 全部标记已读、详情、管理员群发与批量删除。
- **实时推送**`/business/message/stream`):SSE 实时推送当前用户的未读信号(只推「有新消息 + 未读数」信号,不带消息体),页面顶部消息铃铛即时刷新与角标消减;心跳 25 秒一条防断连。
- **短信**:关键节点(登录验证码、注册、电子签、审核结果等)短信触达。
### 5.11 内容管理
| 模块 | 接口 | 说明 |
|---|---|---|
| 协议文章 | `/business/article` | 用户协议 / 隐私政策,后台编辑启用 / 停用 |
| 支持函 | `/business/supportLetter` | 公益支持函,公示关联,可查看 / 下载 / 分享 |
| 邀请函 | `/business/invitation` | 专家参与邀请函,公示关联 |
| 劳务协议模板 | `/business/laborProtocolTemplate` | 劳务协议模板,全局共享,`default_flag='Y'` 同一时刻仅 1 条默认 |
### 5.12 工作台统计
各角色首页 / 工作台的统计指标由独立统计端点提供:
| 角色 | 端点 | 统计口径 |
|---|---|---|
| 合规人员 | `GET /business/dashboard/manager` | 项目总数、会议总数、专家总数、待办会议(未开始)、进行中会议(执行中 / 待合规 / 待支持方 / 待整改)、已办结会议(已结算 / 已完结) |
| 支持方 / 项目负责人 | `GET /business/meeting/stageStats` | 按会议阶段分组计数;支持方主账号统计本单位全部项目会议、监察员统计本人负责项目会议、项目负责人统计本人负责项目会议;前端据此算「已执行 / 未执行」 |
---
## 六、核心状态机与流程
### 6.1 项目全生命周期
```
医生注册·资质审核 → 投稿·立项 → 项目创建·分配·公示
→ 公示意向·报名 → 执行方建会·上传材料 → 医生签署劳务
→ 材料两级审核·结算·完结
```
| 环节 | 主要动作 | 责任角色 |
|---|---|---|
| 1. 注册与资质审核 | 医生提交资质,审核通过后开通账号 | 医生 / 合规人员 / 管理员 |
| 2. 投稿与立项 | 投稿策划方案,审核通过后立项 | 医生 / 执行方 / 支持方 / 合规人员 |
| 3. 项目创建与分配 | 新建项目,分配支持 / 执行单位,发布公示 | 合规人员 / 管理员 |
| 4. 公示与报名 | 门户公示,访客意向 / 医生报名 | 匿名访客 / 医生 |
| 5. 建会与材料 | 执行方建会、上传材料、提交审核 | 执行方 |
| 6. 签署劳务 | 医生电子签,生成 PDF 协议 | 医生 |
| 7. 审核结算完结 | 材料两级审核、结算、完结 | 合规人员 / 支持方 |
### 6.2 会议阶段状态机(事实 + 推导模型)
会议阶段采用「**事实 + 推导**」模型:数据库只存「事实」字段(是否执行 / 是否结算 / 是否完结 / 是否冻结 + 劳务 / 会务两轨各自审核阶段 + 合规通过标记 + 审核时间),各角色看到的「阶段名称」由后端实时推导。
**物理阶段**10 值,`current_stage` 缓存,用于列表筛选):
```
NOT_STARTED(未开始) → RUNNING / IN_PROGRESS(执行中) → 已执行
→ AWAITING_COMPLIANCE(待合规审核) → AWAITING_SUPERVISION(待支持方审核)
→ AWAITING_SETTLEMENT(待结算) → SETTLED(已结算) → FINISHED(已完结)
异常分支:RECTIFYING(待整改,退回后)、FROZEN(冻结中,逾期未提交)
```
| 物理阶段 | 中文名 | 说明 |
|---|---|---|
| NOT_STARTED | 未开始 | 会议已建,尚未到开始时间 |
| RUNNING / IN_PROGRESS | 执行中 | 已到开始时间,进行中 |
| 已执行(`is_executed=1` | 已执行 | 已到结束时间 |
| AWAITING_COMPLIANCE | 待合规审核 | 材料已提交,待合规一级审核 |
| AWAITING_SUPERVISION | 待支持方审核 | 合规通过,待支持方二级审核 |
| AWAITING_SETTLEMENT | 待结算 | 两轨审核通过,待结算 |
| SETTLED | 已结算 | 结算完成 |
| FINISHED | 已完结 | 完结 |
| RECTIFYING | 待整改 | 材料被退回 |
| FROZEN | 冻结中 | 逾期未提交被冻结 |
**时间驱动**(后台每分钟执行):
| 事件 | 结果 |
|---|---|
| 会议开始时间到 | 置「执行中」 |
| 会议结束时间到 | 置「已执行」(`is_executed=1` |
| 提交截止时间到 且 任一轨未提交 / 已退回 | 置「冻结」(`is_frozen=1` |
**单轨状态码**(劳务 / 会务各自独立):`R(退回)=0 < N(未提交)=1 < C0(待合规审)=2 < C1(待支持方审)=3 < A(通过)=4`,会议级物理阶段 = 两轨取最小进度。
**各角色展示阶段名**(同一会议,不同角色看到不同措辞):
- 固定顶格:冻结中 → 已完结 → 已结算。
- 三流程角色(执行方 / 支持方 / 合规人员)两轨合并,并按劳务 / 会务前缀区分(如「劳务待审核」「会务待整改」)。
- 待办态最高优先:合规人员优先「待合规审核」,支持方优先「待支持方审核」,执行方优先「待整改」。
### 6.3 材料审核状态机(单轨)
```
N(未提交) → C0(已提交·待合规审) → C1(合规通过·待支持方审) → A(审核通过)
↘ R(退回) ↙ —— 任一步被拒后回到 R,重新提交回到 C0
```
- 提交门槛:劳务轨 = 至少 1 名参会人;会务轨 = 至少 1 条会务材料。
- 退回后提交截止时间重新计算(now + 项目天数)。
### 6.4 结算流程
```
两轨材料审核通过(APPROVED
→ 会议费用汇总完成(fee_calc_status=1
→ 劳务凭证 + 会务凭证已上传
→ 合规人员 / 管理员点击「结算」
→ 置「已结算」+「已完结」(结算即终态)
```
### 6.5 医生注册与资质审核流程
```
医生注册(提交姓名/单位/科室/职称/执业证书/职称证书 + 短信验证码)
→ 待审核(此时不能登录)
→ 合规人员 / 管理员审核
├─ 通过 → 医生可登录,看到「我参与的会议 / 我报名的项目」
└─ 拒绝 → 通知医生补充材料重新提交
```
### 6.6 劳务电子签流程
```
管理方推送电子签(短信 + 站内信)
→ 医生扫码 / 打开链接(登录后访问)
→ 第一步:填写劳务信息(身份、银行等)
→ 第二步:手写签名确认
→ 第三步:签字成功,系统生成 PDF 劳务协议并归档
```
### 6.7 关键接口数据流转(请求示例)
核心审核链路的请求报文如下(`meetingId` 为路径参数):
| 环节 | 接口 | 请求体 |
|---|---|---|
| 提交材料 | `POST /business/meeting/{meetingId}/submit-material` | `{ "types": ["LABOR","SERVICE"] }`(劳务 / 会务分轨多选) |
| 材料一级审核 | `POST /business/meeting/{meetingId}/audit-compliance` | `{ "items": [{ "type": "LABOR", "approved": true }], "opinion": "通过" }`(拒绝时 `opinion` 必填) |
| 材料二级审核 | `POST /business/meeting/{meetingId}/audit-supervision` | 同上(`items` + `opinion` |
| 批量一级审核 | `POST /business/meeting/batch-audit-compliance` | `{ "meetingIds": [1,2], "approved": true, "opinion": "通过" }` |
| 结算 | `POST /business/meeting/{meetingId}/settle` | 无请求体(路径参数即可,前置条件由后端校验) |
| 完结 / 解冻 | `POST /business/meeting/{meetingId}/finish``/unfreeze` | 无请求体 |
建会请求体为 `BizMeeting`(会议名称、所属项目、期数、起止时间、参会人 `attendeeUserIds` 数组等);电子签签署 `POST /business/sign/submit` 提交手写签名与协议正文,生成 PDF 归档。
---
## 七、端与页面设计
### 7.1 公开门户(Web,无需登录)
首页、项目公示、公示详情、支持函详情、邀请函详情、医生注册、执行单位(供应商)注册、支持方注册、登录、协议(用户协议 / 隐私政策)、专项计划详情。
### 7.2 管理后台(Web,按角色分菜单)
| 角色 | 菜单 |
|---|---|
| 后台管理员 | 工作台、用户管理、角色管理、项目管理、会议管理、科室管理、职称管理、专家管理、支持单位管理、执行单位管理、支持单位下人员、执行单位下人员、协议管理、专项计划管理、项目类别管理、劳务协议配置、消息通知、账号信息 |
| 合规人员 | 工作台、策划方案管理、项目管理、项目分配、会议管理、专家审核、支持单位管理、执行单位管理、支持单位下人员、执行单位下人员、支持意向、执行意向、消息通知、账号管理 |
| 医生 | 首页、我参与的会议、我报名的项目、我的项目策划方案、消息通知、账号信息(隐藏页:填写劳务信息 / 签署劳务协议 / 签字成功 / 会议邀请函) |
| 执行方 | 首页、我的项目策划方案、会议列表、项目列表、人员管理、劳务凭证、消息通知、账号信息 |
| 支持方 | 首页、我的项目策划方案、项目管理、我的项目、会议列表、人员管理、消息通知、账号信息 |
| 项目负责人 | 首页、项目列表、会议列表、消息通知、账号信息 |
### 7.3 移动端(H5
- **扫码签署**:医生扫码进入劳务电子签,完成填写信息与手写签名。
- **拍照上传**:身份证正反面、签到表等现场照片,通过移动相机采集并上传(后端白名单校验后归档,签到表自动生成高斯模糊脱敏版)。
- **兼容手机浏览器**:无需安装 App,扫码即用。
---
## 八、关键技术能力
| 能力 | 说明 |
|---|---|
| 发票自动识别 | 上传发票图片(或 zip),后台异步 OCR 识别金额等字段,减少人工录入 |
| 对象存储 | 材料、凭证、PDF 协议、海报等文件统一云端存储,可预览 / 下载 / 打包 |
| 短信服务 | 登录验证码、注册、电子签、审核结果等关键节点短信触达 |
| 微信分享 | 邀请函 / 支持函等生成 PDF 与分享链接,便于微信传播 |
| 实时消息 | 站内信 SSE 实时推送,顶部角标即时更新 |
| 数据脱敏 | 签到表、参会人敏感信息(手机、银行卡、身份证)展示时自动打码,支持方只见脱敏版 |
| OA 对接 | 新建项目时按项目编号拉取 OA(ecology)项目信息自动回填 |
| 海报生成 | 会议日程海报自动生成并叠加会议信息 |
| 供应商账号同步 | 从外部供应商平台定时拉取账号(加密传输),自动同步到执行方机构 / 人员 / 登录账号 |
### 8.1 外部数据集成
- **OAecology)项目信息拉取**:新建项目时按项目编号从 OA 拉取项目信息自动回填。
- **供应商账号同步**:后台定时从外部供应商平台拉取账号(传输加密、本地解密),按邮箱自动同步到执行方机构、人员与登录账号,避免人工重复录入;触发时机为系统启动后立即全量(近 30 天)、每分钟增量(近 5 分钟)、每晚 2 点全量。
---
## 九、数据设计概览
数据模型按业务域划分,详见配套文档《数据库设计文档 V2.0》:
| 域 | 主要表 |
|---|---|
| 组织与人员 | 机构、人员、医生(专家)、科室、职称 |
| 项目 | 项目、执行方分配、支持方分配、执行方(执行人)分配、策划方案、专项计划、项目评分 |
| 公示与意向 | 项目公告、支持意向、执行意向、报名意向 |
| 会议 | 会议、参会人、材料、发票、执行人员、监察员、审核日志、结算、邀请函、劳务电子签、劳务协议模板 |
| 内容与消息 | 协议文章、资源、消息、支持函 |
设计要点:
- 业务表统一逻辑删除,删除后保留记录、可追溯。
- 主键采用雪花 ID / 自增 ID,关键编号(如凭证编号)唯一。
- 金额统一保留两位小数。
- 开关 / 状态字段采用「是 / 否」或「启用 / 停用」等明确取值(`char(1)``Y` / `N`)。
- 参会人、凭证等采用快照机制,与源数据解耦,保证历史归档稳定。
### 9.1 核心实体字段速览
> 以下仅列业务关键字段,字段类型、约束、索引详见《数据库设计文档 V2.0》。
- **项目**:项目编号、项目名称、项目形式、总场次、总金额、可用金额、已付劳务费、已付会务费、已执行 / 待执行场次、管理费及税金、角色劳务设置、起止时间、提交材料截止天数、支持方企业、项目负责人、是否招标、支持合同 / 执行合同 / 邀请函 / 支持函 / 公示 / 日程文件、是否完结、是否结算、是否发布、发布时间、开通状态、开通截止日、合规评分、支持方评分。
- **会议**:会议名称、所属项目、项目编号、业务 ID、项目形式、执行方归属、开始 / 结束时间、总期数、期数、地址、备注、当前阶段、劳务 / 会务审核阶段、是否执行 / 结算 / 完结 / 冻结及对应时间、提交截止时间、监察意见 / 监察人 / 监察时间、邀请函 / 日程 / 海报文件、劳务费用、会务费用、总费用、费用汇总状态、劳务签署标记。
- **机构**:机构名称、机构类型(支持方 / 执行方)、主账号、企业性质、地址、税号、联系人、联系电话、状态、意向次数(支持方)、同步来源标记。
- **人员**:姓名、手机号、所属公司、部门、职务、关联登录账号、邮箱、账号类型(主 / 子)、主账号、启停状态。
- **策划方案**:方案名称、项目方向(专项计划)、类别、项目形式、设计文件、学科方向、状态、是否结算、项目编号、审核意见 / 审核人 / 审核时间、投稿人、提交时间。
- **项目评分**:项目、评分人、评分人角色、质量 / 响应 / 配合 / 合规四维得分、备注、评分时间。
- **公示意向(支持 / 执行)**:项目、姓名、手机号、工作单位、部门、职务、来源、意向状态、备注(支持匿名提交)。
- **报名意向**:用户、项目、姓名、工作单位、部门、职务、手机号、入职状态。
- **消息**:接收人、类型(通知 / 待办 / 系统)、标题、内容、业务类型、关联业务 ID、已读标记、已读时间。
- **会议审核日志**:会议、审核人、意见、审核类型(材料 / 凭证)、审核结果(通过 / 退回)、材料类型、各角色当时展示状态快照、审核时间。