You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

573 lines
13 KiB

2 weeks ago
# 医生消息任务接口文档
## 通用说明
### 响应格式
所有接口返回 JSON,严格遵循以下格式:
```json
{
"code": 0,
"message": "success",
"data": {}
}
```
- `code`:0 表示成功,非 0 表示失败
- `message`:成功时为 "success",失败时为错误描述
- `data`:业务数据,失败时为 null
### 数据命名规则
`data` 中所有字段使用**小驼峰**命名法(如 `patientNum`、`sendTime`)。
### 登录校验
所有接口需通过请求头 `loginState` 或请求参数 `loginState` 传递登录态,未登录返回 code=403。本模块所有接口需医生身份登录。
### 错误码
| code | 说明 |
|------|------|
| 0 | 成功 |
| 1 | 参数缺失或业务异常 |
| 403 | 需要登录 |
---
## 一、筛选患者人数
- **路由**:`?r=igg4/doctor/task/filter-patient-num`
- **请求方式**:GET
- **说明**:根据筛选条件获取符合条件的患者人数
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| SelectAll | int | 否 | 全选:0-否,1-是;为1时跳过其余筛选条件 |
| BindStartDate | string | 否 | 绑定日期开始,格式 YYYY-MM-DD |
| BindEndDate | string | 否 | 绑定日期结束,格式 YYYY-MM-DD |
| ConfirmedIgg4 | int | 否 | 确诊IGG4-RD:0-全部,1-是,2-否 |
| MedicationType | string | 否 | 正在使用的药物,逗号分隔选项值(如"2,3"),空或0表示全部。可选值见下面枚举表 |
#### ConfirmedIgg4 枚举
| 值 | 说明 |
|----|------|
| 0 | 全部 |
| 1 | 是(确诊患者) |
| 2 | 否(非确诊患者,含未填写和疑似) |
#### MedicationType 枚举
| 值 | 说明 |
|----|------|
| 0 | 全部 |
| 2 | 激素 |
| 3 | 免疫抑制剂 |
| 4 | 靶向CD19生物制剂(伊奈利珠单抗) |
| 5 | 靶向CD20生物制剂(利妥昔单抗等) |
### 请求示例
```
?r=igg4/doctor/task/filter-patient-num&SelectAll=0&BindStartDate=2026-01-01&BindEndDate=2026-06-30&ConfirmedIgg4=1&MedicationType=2,3
```
### 响应示例
```json
{
"code": 0,
"data": {
"PatientNum": "1"
}
}
```
### 业务逻辑说明
1. 基础条件:患者状态有效、属于当前医生、有绑定用户
2. SelectAll=1 时跳过所有筛选直接返回
3. 绑定时间范围:按 `InviteTime` 字段筛选,使用 BETWEEN 逻辑
4. 确诊IGG4-RD:选"是"时匹配 `IsSuspectedPatient=2`,选"否"时排除 `IsSuspectedPatient=2`(保留未填写和疑似患者)
5. 药物筛选:关联 `t_patient_health_questionnaire_latest` 表(QuestionNo=4),使用 `FIND_IN_SET` 匹配多选答案,多个选项值之间为 OR 关系
---
## 二、获取任务模板
- **路由**:`?r=igg4/doctor/task/get-template`
- **请求方式**:GET
- **说明**:获取所有消息推送模板,按模板类型分组
### 请求参数
### 响应示例
```json
{
"code": 0,
"data": [
{
"templateType": 1,
"templateTypeText": "复诊提醒",
"templateList": [
{
"id": 1,
"templateType": 1,
"interactMsgContent": "互动消息内容",
"templateIndex": "模板index",
"templateContent": "模板内容JSON"
}
]
}
]
}
```
#### TemplateType 枚举
| 值 | 说明 |
|----|------|
| 1 | 复诊提醒 |
| 2 | 激素风险提醒 |
### 业务逻辑说明
1. 查询所有模板记录,按 `TemplateType` 升序、`Id` 升序排列
2.`TemplateType` 分组返回,每组包含类型编号、类型文本和模板列表
---
## 三、创建任务
- **路由**:`?r=igg4/doctor/task/create`
- **请求方式**:POST
- **说明**:创建消息推送任务,使用数据库事务
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| FilterCondition | object | 否 | 筛选条件JSON对象,结构同"筛选患者人数"接口参数 |
| PushTemplateId | int | 是 | 推送模板ID |
| IsSendNow | int | 是 | 是否立即发送:0-否,1-是 |
| SendTime | string | 条件必填 | 发送时间(IsSendNow=0时必填),格式 YYYY-MM-DD HH:mm:ss |
| PatientNum | int | 是 | 患者人数 |
#### FilterCondition 结构
| 字段 | 类型 | 说明 |
|------|------|------|
| SelectAll | int | 全选:0-否,1-是 |
| BindStartDate | string | 绑定日期开始 |
| BindEndDate | string | 绑定日期结束 |
| ConfirmedIgg4 | int | 确诊IGG4-RD:0-全部,1-是,2-否 |
| MedicationType | string | 正在使用的药物,逗号分隔 |
### 请求示例
```json
{
"FilterCondition": {
"SelectAll": 0,
"BindStartDate": "2026-01-01",
"BindEndDate": "2026-06-30",
"ConfirmedIgg4": 1,
"MedicationType": "2"
},
"PushTemplateId": 2,
"IsSendNow": 1,
"SendTime": "",
"PatientNum": 25
}
```
### 响应示例(成功)
```json
{
"code": 0,
"data": "创建成功"
}
```
### 响应示例(失败)
```json
{
"code": 1,
"data": "每个医生每天只能创建一次任务"
}
```
### 业务逻辑说明
1. 校验医生存在(逻辑删除标记 `DeleteTime` 为空)
2. 校验模板存在
3. 每个医生每天只能创建一次任务(当天已有状态为待发送/发送中/暂停/已发送/已停止的任务则不可再创建)
4. IsSendNow=1 时,SendTime 自动设为当前时间
5. 自动生成 IdNumber(`YmdHis` + 3位随机数)
6. IsDoctorCreate=1(医生端创建),CreateWorkerId 为空
7. 生成模板消息内容(调用 `transformTemplateContent` 转化模板变量)
8. 保存任务后,自动调用 `generateUserRecord` 生成用户发送记录
9. 更新任务的 ActualPatientNum 和 IsInsertUser 字段
---
## 四、获取任务列表
- **路由**:`?r=igg4/doctor/task/list`
- **请求方式**:GET
- **说明**:获取当前医生的任务列表,支持分页,按创建时间降序排列
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| count | int | 否 | 每页条数,默认10 |
| page | int | 否 | 页码,从1开始 |
### 请求示例
```
?r=igg4/doctor/task/list&count=10&page=1
```
### 响应示例
```json
{
"code": 0,
"data": {
"list": [
{
"Id": 1,
"IdNumber": "20260702143025123",
"DoctorId": 5,
"FilterCondition": {
"SelectAll": 0,
"BindStartDate": "2026-01-01",
"BindEndDate": "2026-06-30",
"ConfirmedIgg4": 1,
"MedicationType": "2"
},
"TemplateType": 1,
"CreateTime": "2026-07-02 14:30:25",
"IsSendNow": 1,
"SendTime": "2026-07-02 14:30:25",
"Status": 4,
"PatientNum": 25,
"ActualPatientNum": 23
}
],
"pages": 3,
"count": 28,
"page": 1
}
}
```
### 响应字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| Id | int | 任务ID |
| IdNumber | string | 任务编号 |
| DoctorId | int | 医生ID |
| FilterCondition | object | 筛选条件JSON对象 |
| TemplateType | int | 模板类型 |
| CreateTime | string | 创建时间 |
| IsSendNow | int | 是否立即发送:0-否,1-是 |
| SendTime | string | 发送时间 |
| Status | int | 任务状态 |
| PatientNum | int | 患者人数 |
| ActualPatientNum | int | 实际发送患者人数 |
#### FilterCondition 结构说明
| 字段 | 类型 | 说明 |
|------|------|------|
| SelectAll | int | 全选:0-否,1-是 |
| BindStartDate | string | 绑定日期开始 |
| BindEndDate | string | 绑定日期结束 |
| ConfirmedIgg4 | int | 确诊IGG4-RD:0-全部,1-是,2-否 |
| MedicationType | string | 正在使用的药物,逗号分隔 |
#### TemplateType 枚举
| 值 | 说明 |
|----|------|
| 1 | 复诊提醒 |
| 2 | 激素风险提醒 |
#### Status 枚举
| 值 | 说明 |
|----|------|
| 1 | 待发送 |
| 2 | 发送中 |
| 3 | 暂停 |
| 4 | 已发送 |
| 5 | 已停止 |
| 6 | 已取消 |
### 业务逻辑说明
1. 仅查询 `DeleteTime` 为空的任务
2. FilterCondition 字段从 JSON 字符串解码为数组返回
3. 返回字段包含:Id, IdNumber, DoctorId, FilterCondition, TemplateType, CreateTime, IsSendNow, SendTime, Status, PatientNum, ActualPatientNum
4. 分页参数:pages 为总页数,count 为总记录数,page 为当前页码(从1开始)
---
## 五、获取任务详情
- **路由**:`?r=igg4/doctor/task/detail`
- **请求方式**:GET
- **说明**:获取单个任务的详细信息,包含发送统计
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| TaskId | int | 是 | 任务ID |
### 请求示例
```
?r=igg4/doctor/task/detail&TaskId=1
```
### 响应示例
```json
{
"code": 0,
"data": {
"Id": 1,
"IdNumber": "20260702143025123",
"DoctorId": 5,
"FilterCondition": {
"SelectAll": 0,
"BindStartDate": "2026-01-01",
"BindEndDate": "2026-06-30",
"ConfirmedIgg4": 1,
"MedicationType": "2"
},
"TemplateType": 1,
"PushTemplateId": 2,
"TemplateMsgContent": "{...}",
"InteractMsgContent": "互动消息内容",
"IsSendNow": 1,
"SendTime": "2026-07-02 14:30:25",
"PatientNum": 25,
"ActualPatientNum": 23,
"IsInsertUser": 1,
"Status": 4,
"IsDoctorCreate": 1,
"WorkerId": "",
"DeleteTime": null,
"CreateTime": "2026-07-02 14:30:25",
"UpdateTime": "2026-07-02 14:30:30",
"SendDetail": {
"TaskId": 1,
"SumSendCount": 23,
"SendCount": 20,
"UnSendCount": 3,
"InteractSendSuccessCount": 18,
"InteractSendFailCount": 2,
"PushSendSuccessCount": 16,
"PushSendFailCount": 4,
"PushClickCount": 10,
"InteractReadCount": 15,
"InteractUnReadCount": 5,
"PushUnClickCount": 10
}
}
}
```
#### SendDetail 字段说明
| 字段 | 说明 |
|------|------|
| sumSendCount | 总人数(去重) |
| sendCount | 已发送人数 |
| unSendCount | 未发送人数 |
| InteractSendSuccessCount | 互动消息发送成功人数 |
| InteractSendFailCount | 互动消息发送失败人数(派生值:SendCount - InteractSendSuccessCount) |
| PushSendSuccessCount | Push消息发送成功人数 |
| PushSendFailCount | Push消息发送失败人数 |
| PushClickCount | Push消息点击人数 |
| InteractReadCount | 互动消息已读人数 |
| InteractUnReadCount | 互动消息未读人数(派生值:sendCount - InteractReadCount) |
| PushUnClickCount | Push消息未点击人数(派生值:sendCount - PushClickCount) |
### 业务逻辑说明
1. 校验任务存在且 `DeleteTime` 为空,否则抛出"任务不存在"
2. FilterCondition 从 JSON 字符串解码为数组
3. 根据 PushTemplateId 查询模板,补充 TemplateType 和 InteractMsgContent 字段
4. 通过 `TZdDoctorMsgTaskUserMessage::taskDetail` 获取发送统计数据,包含派生的失败/未读/未点击人数
---
## 六、删除任务
- **路由**:`?r=igg4/doctor/task/delete`
- **请求方式**:POST
- **说明**:逻辑删除已取消的任务,使用数据库事务
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| TaskId | int | 是 | 任务ID |
### 请求示例
```json
{
"TaskId": 1
}
```
### 响应示例(成功)
```json
{
"code": 0,
"data": "删除成功"
}
```
### 响应示例(失败)
```json
{
"code": 1,
"msg": "当前任务状态不能删除",
}
```
### 业务逻辑说明
1. 校验任务存在、属于当前医生且 `DeleteTime` 为空,否则抛出"任务不存在"
2. 只有状态为"已取消"(Status=6)的任务才能删除
3. 设置 `DeleteTime` 为当前时间(软删除)
---
## 七、停止任务
- **路由**:`?r=igg4/doctor/task/stop`
- **请求方式**:POST
- **说明**:停止正在发送中或暂停的任务,使用数据库事务
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| TaskId | int | 是 | 任务ID |
### 请求示例
```json
{
"TaskId": 1
}
```
### 响应示例(成功)
```json
{
"code": 0,
"data": "停止成功"
}
```
### 响应示例(失败)
```json
{
"code": 1,
"msg": "当前任务状态不能停止",
}
```
### 业务逻辑说明
1. 校验任务存在、属于当前医生且 `DeleteTime` 为空,否则抛出"任务不存在"
2. 只有状态为"发送中"(Status=2)或"暂停"(Status=3)的任务才能停止
3. 将状态更新为"已停止"(Status=5)
---
## 八、取消任务
- **路由**:`?r=igg4/doctor/task/cancel`
- **请求方式**:POST
- **说明**:取消待发送的任务,使用数据库事务
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| TaskId | int | 是 | 任务ID |
### 请求示例
```json
{
"TaskId": 1
}
```
### 响应示例(成功)
```json
{
"code": 0,
"data": "取消成功"
}
```
### 响应示例(失败)
```json
{
"code": 1,
"msg": "当前任务状态不能取消",
}
```
### 业务逻辑说明
1. 校验任务存在、属于当前医生且 `DeleteTime` 为空,否则抛出"任务不存在"
2. 只有状态为"待发送"(Status=1)的任务才能取消
3. 将状态更新为"已取消"(Status=6)
---
## 附录
### 附录A:任务状态流转
```
待发送(1) ──发送调度──> 发送中(2) ──发送完成──> 已发送(4)
│ │ ↑
│取消 │ │暂停
↓ ↓ │
已取消(6) <────────── 暂停(3)─┘
│ │
│删除(软删) │停止
↓ ↓
(DeleteTime非空) 已停止(5)
```