# 医生消息任务接口文档 ## 通用说明 ### 响应格式 所有接口返回 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) ```