百度外呼录音获取。

This commit is contained in:
haown 2024-11-06 10:44:35 +08:00
parent 87175fac69
commit 403603ab7b
31 changed files with 707 additions and 44 deletions

View File

@ -30,6 +30,8 @@ xinelu:
rich-text-picture-url: /richTextPictureUrl
# 资讯富文本的上传路径
info-rich-text-picture-url: /infoRichTextPictureUrl
# 资讯富文本的上传路径
phone-dial-record-video: /phoneDialRecordVideo
# 开发环境配置
server:

View File

@ -86,6 +86,11 @@ public class SystemBusinessConfig {
*/
private String richTextPictureUrl;
/**
* AI电话录音地址
*/
private String phoneDialRecordVideo;
public String getName() {
return name;
}
@ -232,4 +237,12 @@ public class SystemBusinessConfig {
public void setInfoRichTextPictureUrl(String infoRichTextPictureUrl) {
this.infoRichTextPictureUrl = infoRichTextPictureUrl;
}
public String getPhoneDialRecordVideo() {
return phoneDialRecordVideo;
}
public void setPhoneDialRecordVideo(String phoneDialRecordVideo) {
this.phoneDialRecordVideo = phoneDialRecordVideo;
}
}

View File

@ -49,7 +49,7 @@ public class AgencyController extends BaseController {
*/
@GetMapping("/selectAgencyList")
public AjaxResult selectAgencyByIdList(Agency agency) {
return agencyService.selectAgencyByIdList(agency);
return AjaxResult.success(agencyService.selectAgencyByIdList(agency));
}
/**
@ -60,7 +60,7 @@ public class AgencyController extends BaseController {
if (Objects.isNull(agency) || Objects.isNull(agency.getParentId())) {
return AjaxResult.success();
}
return agencyService.selectAgencyByIdList(agency);
return AjaxResult.success(agencyService.selectAgencyByIdList(agency));
}
/**

View File

@ -96,4 +96,10 @@ public class AIOBController extends BaseController {
public JSONObject taskCallBack(@RequestBody TaskCallbackDto taskCallbackDto) throws ClientException {
return aiobService.taskCallBack(taskCallbackDto.getCallbackType(), taskCallbackDto.getData());
}
@ApiOperation("任务单通电话回调")
@GetMapping("/record")
public String record() throws ClientException {
return aiobService.record("1726726696448834_936326");
}
}

View File

@ -12,6 +12,7 @@ import com.xinelu.common.utils.poi.ExcelUtil;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.dto.manualfollowup.ManualFollowUpDTO;
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
import com.xinelu.manage.dto.signpatientmanageroutenode.CreateAiboActualTimeTaskDto;
import com.xinelu.manage.service.signpatientmanageroute.ISignPatientManageRouteService;
import com.xinelu.manage.vo.manualfollowup.ManualFollowUpVO;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
@ -114,6 +115,20 @@ public class SignPatientManageRouteController extends BaseController {
return getDataTable(list);
}
/**
* @description 随访待办列表-创建实时呼叫任务
* @Param createAiboActualTimeTaskDto 创建百度外呼实时任务传输对象
* @return 结果
* @Author haown
* @Date 2024-11-4 16:06
*/
@ApiOperation("随访待办列表-创建实时呼叫任务")
@PostMapping("/createActualTimeTask")
public R<String> createActualTimeTask(@RequestBody CreateAiboActualTimeTaskDto createAiboActualTimeTaskDto) {
Long memberId = signPatientManageRouteService.createActualTimeTask(createAiboActualTimeTaskDto);
return memberId != null && memberId > 0L ? R.ok() : R.fail();
}
/**
* 查询人工随访患者基本信息
*/

View File

@ -130,6 +130,15 @@ public class SignPatientManageRouteNodeController extends BaseController {
return R.ok(signNodeService.getSpecialDiseaseNode(patientTaskDto));
}
/**
* AI通话获取录音
*/
@ApiOperation("AI通话获取录音")
@GetMapping("/getPhoneDialVideo/{id}")
public R<String> getPhoneDialVideo(@PathVariable("id") Long id) {
return R.ok(signNodeService.getPhoneDialVideo(id));
}
/**
* 测试生成患者档案列表数据用
*/

View File

@ -104,6 +104,17 @@ public class PhoneDialRecord extends BaseEntity {
@Excel(name = "推送结果状态码success成功fail失败")
private String errorStatus;
/**
* 生成通话录音唯一标识,可通过该标识获取录音
*/
@ApiModelProperty(value = "生成通话录音唯一标识,可通过该标识,获取录音")
private String ctUuid;
/**
* 通话录音存储路径
*/
@ApiModelProperty(value = "通话录音存储路径")
private String phoneDialRecordVideo;
@Override
public String toString() {

View File

@ -409,4 +409,5 @@ public class SignPatientManageRouteNode extends BaseEntity {
@ApiModelProperty(value = "第三方返回的任务ID")
private String taskIdExt;
}

View File

@ -3,14 +3,13 @@ package com.xinelu.manage.dto.manualfollowup;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinelu.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import java.time.LocalDate;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
/**
* 人工随访查询DTO
*
@ -79,4 +78,10 @@ public class ManualFollowUpDTO extends BaseEntity {
private String timeSign;
private String phoneNodeExecuteResultStatus;
/**
* AI自动 COMMON手动
*/
@ApiModelProperty(value = "AI自动 或 COMMON手动")
private String phoneDialMethod;
}

View File

@ -0,0 +1,24 @@
package com.xinelu.manage.dto.signpatientmanageroutenode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description: 创建百度外呼实时任务传输对象
* @author: haown
* @create: 2024-11-04 15:54
**/
@ApiModel("创建百度外呼实时任务传输对象")
@Data
public class CreateAiboActualTimeTaskDto {
@ApiModelProperty("任务表ID")
private Long signPatientManageRouteNodeId;
@ApiModelProperty("话术表主键")
private Long scriptInfoId;
@ApiModelProperty("签约路径表主键")
private Long manageRouteId;
}

View File

@ -59,4 +59,10 @@ public class FollowUpRateDto {
@ApiModelProperty(value = "就诊方式门诊OUTPATIENT_SERVICE住院BE_IN_HOSPITAL")
private String visitMethod;
/**
* 统计类型科室dept, 日期date
*/
@ApiModelProperty(value = "统计类型科室dept, 日期date")
private String type;
}

View File

@ -2,6 +2,8 @@ package com.xinelu.manage.mapper.patientvisitrecord;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.dto.patientvisitrecord.PatientVisitRecordDto;
import com.xinelu.manage.dto.statistics.FollowUpRateDto;
import com.xinelu.manage.vo.patientvisitrecord.PatientVisitRecordStatisticVo;
import com.xinelu.manage.vo.patientvisitrecord.PatientVisitRecordVo;
import java.util.List;
import org.apache.ibatis.annotations.Param;
@ -76,4 +78,6 @@ public interface PatientVisitRecordMapper {
*/
PatientVisitRecord getLastRecord(PatientVisitRecordDto patientVisitRecordDto);
List<PatientVisitRecordStatisticVo> getVisitPatientList(FollowUpRateDto queryDto);
}

View File

@ -61,4 +61,6 @@ public interface PhoneDialRecordMapper {
int deletePhoneDialRecordByIds(Long[] ids);
List<PhoneDialRecordVo> getPhoneDialStatistic(FollowUpRateDto queryDto);
PhoneDialRecord getLastRecord(Long manageRouteNodeId);
}

View File

@ -3,6 +3,7 @@ package com.xinelu.manage.mapper.signpatientmanageroutenode;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.dto.signpatientmanageroutenode.PatientTaskDto;
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
import com.xinelu.manage.dto.statistics.FollowUpRateDto;
import com.xinelu.manage.vo.homepage.PatientAndNode;
import com.xinelu.manage.vo.signpatientmanageroutenode.*;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo;
@ -178,4 +179,6 @@ public interface SignPatientManageRouteNodeMapper {
* @return PatientAndNode
*/
List<PatientAndNode> selectNodeExecuteStatus();
List<PatientFollowUpPlanVo> getFollowUpPlan(FollowUpRateDto queryDto);
}

View File

@ -40,7 +40,7 @@ public interface IAgencyService {
* @param agency 机构信息
* @return 机构信息集合
*/
AjaxResult selectAgencyByIdList(Agency agency);
List<Agency> selectAgencyByIdList(Agency agency);
/**
* 新增机构信息

View File

@ -101,7 +101,7 @@ public class AgencyServiceImpl implements IAgencyService {
* @return 机构信息
*/
@Override
public AjaxResult selectAgencyByIdList(Agency agency) {
public List<Agency> selectAgencyByIdList(Agency agency) {
// 查询用户角色
List<SysRole> roleList = SecurityUtils.getLoginUser().getUser().getRoles();
if (CollectionUtils.isNotEmpty(roleList)) {
@ -110,7 +110,7 @@ public class AgencyServiceImpl implements IAgencyService {
agency.setId(SecurityUtils.getLoginUser().getUser().getHospitalAgencyId());
}
}
return AjaxResult.success(agencyMapper.selectAgencyList(agency));
return agencyMapper.selectAgencyList(agency);
}

View File

@ -71,4 +71,6 @@ public interface IAIOBService {
* @Date 2024-9-2 14:20
*/
JSONObject taskCallBack(Integer callbackType, TaskCallbackDataDto data) throws ClientException;
String record(String ccUUID);
}

View File

@ -6,7 +6,9 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.config.SystemBusinessConfig;
import com.xinelu.common.constant.AiboTaskTypeContant;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.constant.PhoneMessageRemindConstants;
import com.xinelu.common.constant.TaskCreateTypeConstant;
import com.xinelu.common.constant.TaskStatisticsTypeConstants;
@ -66,11 +68,19 @@ import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRo
import com.xinelu.manage.vo.aibo.ImportTaskVo;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import com.xinelu.manage.vo.questionsubject.QuestionSubjectVO;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -112,6 +122,9 @@ public class AIOBServiceImpl implements IAIOBService {
@Resource
private RedisCache redisCache;
@Resource
private SystemBusinessConfig systemBusinessConfig;
@Resource
private SignPatientRecordMapper signPatientRecordMapper;
@Resource
@ -364,6 +377,10 @@ public class AIOBServiceImpl implements IAIOBService {
if (ObjectUtils.isNotEmpty(signPatientManageRouteNode)) {
// 标记任务执行状态
signPatientManageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.EXECUTED.getInfo());
// 问卷设置任务完成时间
if (StringUtils.equals(TaskNodeTypeEnum.QUESTIONNAIRE_SCALE.getInfo(), signPatientManageRouteNode.getTaskNodeType())) {
signPatientManageRouteNode.setNodeFinishDate(LocalDateTime.now());
}
//接通状态1-已接通 0-未接通
if (data.getEndType() != null && data.getEndType() == 0) {
// 设置电话拨通情况
@ -444,6 +461,10 @@ public class AIOBServiceImpl implements IAIOBService {
phoneDialRecord.setErrorCode(data.getEndType() == 0 ? 1L : 0);
phoneDialRecord.setErrorStatus(data.getEndType() == 0 ? ErrorStatusEnum.fail.getValue() : ErrorStatusEnum.success.getValue());
phoneDialRecord.setCreateTime(LocalDateTime.now());
phoneDialRecord.setCtUuid(data.getContactUUID());
phoneDialRecord.setPhoneDialRecordVideo(getPhoneDialRecord(data.getContactUUID()));
phoneDialRecordMapper.insertPhoneDialRecord(phoneDialRecord);
// 修改任务统计表数据
@ -462,6 +483,38 @@ public class AIOBServiceImpl implements IAIOBService {
return retObj;
}
@Override public String record(String ccUUID) {
String accessToken = getAccessToken();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", accessToken);
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(null, headers);
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> params = new HashMap<>();
params.put("contactUuid", ccUUID);
params.put("expiration", 1800);
params.put("operation", 3);
ResponseEntity<String> responseEntity = restTemplate.exchange(url + "/v1/record"+"?contactUuid={contactUuid}&expiration={expiration}&operation={operation}", HttpMethod.GET, requestEntity, String.class, params);
//{
// "requestId" : "9c5870a37e2441ad9ccc9100d870054e",
// "time" : 1730701318185,
// "code" : 200,
// "msg" : "OK",
// "data" : [ {
// "recordUrl" : "https://gz.bcebos.com/v1/cc-call-recording/2024/09/19/3849515568332800/14/1726726696417508_628800_1726726696448834_936326_14_18_42.wav?authorization=bce-auth-v1%2FALTAKOVf6H3DUWVqVqc2k43RAa%2F2024-11-04T06%3A21%3A58Z%2F1800%2F%2Fe33651c189f512aaa3c94f68f8136dc69538c680c94c8605696de5a041c36f49",
// "downloadUrl" : "https://gz.bcebos.com/v1/cc-call-recording/2024/09/19/3849515568332800/14/1726726696417508_628800_1726726696448834_936326_14_18_42.wav?responseContentDisposition=attachment%3B%20filename%3D1726726696417508_628800_1726726696448834_936326_14_18_42.wav&authorization=bce-auth-v1%2FALTAKOVf6H3DUWVqVqc2k43RAa%2F2024-11-04T06%3A21%3A58Z%2F1800%2F%2Fa802d88ba4b987f1a0f30ce73b515c8515255b34e5bac4f1d0c27987ac70d68a"
// } ]
//}
JSONObject object = JSON.parseObject(responseEntity.getBody());
if (object == null || object.getInteger("code") == null || object.getInteger("code") != 200) {
return null;
}
JSONArray data = object.getJSONArray("data");
JSONObject obj = data.getJSONObject(0);
return obj.getOrDefault("downloadUrl", null).toString();
}
private void sendSms(Long patientId, SignPatientManageRouteNode signPatientManageRouteNode) throws ClientException {
TextMessage textMessage = textMessageMapper.selectTextMessageById(signPatientManageRouteNode.getPhoneMessageTemplateId());
if (ObjectUtils.isNotEmpty(textMessage)) {
@ -551,7 +604,7 @@ public class AIOBServiceImpl implements IAIOBService {
patientQuestionSubmitResult.setManageRouteId(node.getManageRouteId());
patientQuestionSubmitResult.setManageRouteName(node.getManageRouteName());
patientQuestionSubmitResult.setManageRouteNodeId(node.getId());
patientQuestionSubmitResult.setManageRouteNodeName(node.getManageRouteName());
patientQuestionSubmitResult.setManageRouteNodeName(node.getRouteNodeName());
patientQuestionSubmitResult.setQuestionInfoId(questionInfo.getId());
patientQuestionSubmitResult.setDepartmentId(questionInfo.getDepartmentId());
patientQuestionSubmitResult.setDepartmentName(questionInfo.getDepartmentName());
@ -614,6 +667,32 @@ public class AIOBServiceImpl implements IAIOBService {
});
patientQuestionOptionResultMapper.saveQuestionOptionList(patientQuestionOptionResults);
totalScore[0] = totalScore[0].add(questionSubjectVO.getQuestionScore());
} else {
// 没问到问卷中的问题则保存空问题+空选项
PatientQuestionSubjectResult patientQuestionSubjectResult = new PatientQuestionSubjectResult();
BeanUtils.copyProperties(questionSubjectVO, patientQuestionSubjectResult);
patientQuestionSubjectResult.setId(null);
patientQuestionSubjectResult.setQuestionSubmitResultId(patientQuestionSubmitResult.getId());
patientQuestionSubjectResult.setCreateTime(LocalDateTime.now());
patientQuestionSubjectResultMapper.insertPatientQuestionSubjectResult(patientQuestionSubjectResult);
// 3保存空选项
QuestionSubjectOption questionSubjectOptionQuery = new QuestionSubjectOption();
questionSubjectOptionQuery.setQuestionnaireSubjectId(questionSubjectVO.getId());
List<QuestionSubjectOption> questionSubjectOptions = questionSubjectOptionMapper.selectQuestionSubjectOptionList(questionSubjectOptionQuery);
List<PatientQuestionOptionResult> patientQuestionOptionResults = new ArrayList<>();
questionSubjectOptions.forEach(questionSubjectOption -> {
PatientQuestionOptionResult patientQuestionOptionResult = new PatientQuestionOptionResult();
BeanUtils.copyProperties(questionSubjectOption, patientQuestionOptionResult);
patientQuestionOptionResult.setOptionChooseSign(1);
patientQuestionOptionResult.setId(null);
patientQuestionOptionResult.setCreateTime(LocalDateTime.now());
patientQuestionOptionResult.setQuestionSubjectResultId(patientQuestionSubjectResult.getId());
patientQuestionOptionResults.add(patientQuestionOptionResult);
});
patientQuestionOptionResultMapper.saveQuestionOptionList(patientQuestionOptionResults);
totalScore[0] = totalScore[0].add(BigDecimal.ZERO);
}
});
@ -664,4 +743,43 @@ public class AIOBServiceImpl implements IAIOBService {
scriptInfoTaskInfo.setExecuteTime(executeTime.plusMinutes(signPatientManageRouteNode.getPhoneTimeInterval()));
scriptInfoTaskInfoMapper.insertScriptInfoTaskInfo(scriptInfoTaskInfo);
}
private String getPhoneDialRecord(String ccUuid) {
String url = "";
String downLoadUrl = record(ccUuid);
if (StringUtils.isNotBlank(downLoadUrl)) {
url = systemBusinessConfig.getProfile() + systemBusinessConfig.getPhoneDialRecordVideo() + "/" + ccUuid + ".wav";
File outputPath = new File(url);
File dir = outputPath.getParentFile();
if (!dir.exists()){
dir.mkdirs();
}
try {
outputPath.createNewFile(); // 创建文件
URL fileUrl = new URL(downLoadUrl);
HttpURLConnection connection = (HttpURLConnection)fileUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(outputPath);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("下载完成,目录:" + outputPath);
return Constants.RESOURCE_PREFIX + "/" + systemBusinessConfig.getPhoneDialRecordVideo() + "/" + ccUuid + ".wav";
} else {
System.out.println("下载失败" + connection.getResponseCode());
return null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

View File

@ -6,6 +6,7 @@ import com.xinelu.common.exception.ServiceException;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.dto.manualfollowup.ManualFollowUpDTO;
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
import com.xinelu.manage.dto.signpatientmanageroutenode.CreateAiboActualTimeTaskDto;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.vo.manualfollowup.ManualFollowUpVO;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
@ -14,6 +15,7 @@ import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordSelectVo;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteAuditVo;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 签约患者管理任务路径Service接口
@ -77,6 +79,15 @@ public interface ISignPatientManageRouteService {
*/
List<ManualFollowUpVO> selectManualFollowUpList(ManualFollowUpDTO manualFollowUpDTO);
/**
* @description 随访待办列表-创建实时呼叫任务
* @Param createAiboActualTimeTaskDto 创建百度外呼实时任务传输对象
* @return 结果
* @Author haown
* @Date 2024-11-4 16:06
*/
Long createActualTimeTask(@RequestBody CreateAiboActualTimeTaskDto createAiboActualTimeTaskDto);
/**
* 查询人工随访患者基本信息
* @param id 签约患者管理任务表id

View File

@ -33,6 +33,7 @@ import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AgeUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientquestionoptionresult.PatientQuestionOptionResult;
import com.xinelu.manage.domain.patientquestionsubjectresult.PatientQuestionSubjectResult;
import com.xinelu.manage.domain.patientquestionsubmitresult.PatientQuestionSubmitResult;
@ -45,12 +46,15 @@ import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.domain.signroutetriggercondition.SignRouteTriggerCondition;
import com.xinelu.manage.dto.aibo.ActualTimeTaskDto;
import com.xinelu.manage.dto.manualfollowup.ManualFollowUpDTO;
import com.xinelu.manage.dto.patientquestionoptionresult.PatientQuestionOptionResultDTO;
import com.xinelu.manage.dto.patientquestionsubjectresult.PatientQuestionSubjectResultDTO;
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
import com.xinelu.manage.dto.signpatientmanageroutenode.CreateAiboActualTimeTaskDto;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientquestionoptionresult.PatientQuestionOptionResultMapper;
import com.xinelu.manage.mapper.patientquestionsubjectresult.PatientQuestionSubjectResultMapper;
import com.xinelu.manage.mapper.patientquestionsubmitresult.PatientQuestionSubmitResultMapper;
@ -63,6 +67,7 @@ import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMap
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.mapper.signroutetriggercondition.SignRouteTriggerConditionMapper;
import com.xinelu.manage.service.aibo.IAIOBService;
import com.xinelu.manage.service.patienttaskstatistics.IPatientTaskStatisticsService;
import com.xinelu.manage.service.propagandainfo.IPropagandaInfoService;
import com.xinelu.manage.service.questioninfo.IQuestionInfoService;
@ -89,6 +94,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -99,6 +105,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -155,6 +162,13 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout
@Resource
private IPatientTaskStatisticsService patientTaskStatisticsService;
@Resource
private PatientInfoMapper patientInfoMapper;
@Resource
private IAIOBService aiobService;
@Value("${aiob.callBackUrl}")
private String callBackUrl;
private static final String SUCCESS = "OK";
/**
@ -325,34 +339,6 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout
ArrayList<ManualFollowUpVO> manualFollowUps = new ArrayList<>();
for (ManualFollowUpVO manualFollowUpVO : manualFollowUpVOS) {
//判断路径节点组装数据
// if (manualFollowUpVO.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_DISCHARGE.getInfo()) || manualFollowUpVO.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
// if (manualFollowUpVO.getPatientType().equals(PatientTypeEnum.DISCHARGED_PATIENT.getInfo())) {
// LocalDate localDate = manualFollowUpVO.getDischargeTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
// boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
// if (before) {
// manualFollowUps.add(manualFollowUpVO);
// }
// }
// }
// if (manualFollowUpVO.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_ADMISSION.getInfo())) {
// if (manualFollowUpVO.getPatientType().equals(PatientTypeEnum.IN_HOSPITAL_PATIENT.getInfo())) {
// LocalDate localDate = manualFollowUpVO.getAdmissionTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
// boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
// if (before) {
// manualFollowUps.add(manualFollowUpVO);
// }
// }
// }
// if (manualFollowUpVO.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_CONSULTATION.getInfo()) || manualFollowUpVO.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
// if (manualFollowUpVO.getPatientType().equals(PatientTypeEnum.OUTPATIENT.getInfo()) && manualFollowUpVO.getAdmissionTime() == null) {
// LocalDate localDate = manualFollowUpVO.getVisitTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
// boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
// if (before) {
// manualFollowUps.add(manualFollowUpVO);
// }
// }
// }
//判断路径节点组装数据
LocalDate localDate = null;
if (Objects.nonNull(manualFollowUpVO.getDischargeTime())) {
localDate = manualFollowUpVO.getDischargeTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
@ -379,7 +365,44 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout
return manualFollowUps;
}
/**
/**
* @description 随访待办列表-创建实时呼叫任务
* @Param createAiboActualTimeTaskDto 创建百度外呼实时任务传输对象
* @return 结果
* @Author haown
* @Date 2024-11-4 16:06
*/
@Override public Long createActualTimeTask(CreateAiboActualTimeTaskDto createAiboActualTimeTaskDto) {
ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(createAiboActualTimeTaskDto.getScriptInfoId());
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(createAiboActualTimeTaskDto.getManageRouteId());
PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(signPatientManageRoute.getPatientId());
// 没有任务则创建任务
if (ObjectUtils.isNotEmpty(scriptInfo)) {
ActualTimeTaskDto actualTimeTaskDto = new ActualTimeTaskDto();
actualTimeTaskDto.setRobotId(scriptInfo.getRobotPublishId());
actualTimeTaskDto.setMobile(patientInfo.getPatientPhone());
actualTimeTaskDto.setSecretType(2);
actualTimeTaskDto.setStopDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 17:00:00");
// 查询患者画像信息
List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfo.getId());
// 处理变量
JSONObject jsonObject = new JSONObject();
if (com.xinelu.common.utils.StringUtils.isNotBlank(scriptInfo.getVariables())) {
List<String> variables = Arrays.asList(scriptInfo.getVariables().split("\\|"));
variables.forEach(variable -> {
LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), variable.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
jsonObject.fluentPut(variable, ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
});
}
actualTimeTaskDto.setDialogVar(jsonObject);
actualTimeTaskDto.setCallBackUrl(callBackUrl);
actualTimeTaskDto.setExtJson(createAiboActualTimeTaskDto.getSignPatientManageRouteNodeId()+ "");
return aiobService.createActualTimeTask(actualTimeTaskDto);
}
return 0L;
}
/**
* 查询人工随访患者基本信息
*
* @param id 签约患者管理任务表id

View File

@ -20,7 +20,6 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
/**
* 签约患者管理任务路径节点Service接口
*
@ -131,6 +130,8 @@ public interface ISignPatientManageRouteNodeService {
List<PatientSpecialDiseaseNodeVo> getSpecialDiseaseNode(PatientTaskDto patientTaskDto);
String getPhoneDialVideo(Long id);
/**
* 根据参数列表修改任务
* @param paramsCurrentLists 参数列表

View File

@ -27,6 +27,7 @@ import com.xinelu.manage.domain.patientnodeparamscurrent.PatientNodeParamsCurren
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
import com.xinelu.manage.domain.patienttaskstatistics.PatientTaskStatistics;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.phonedialrecord.PhoneDialRecord;
import com.xinelu.manage.domain.propagandainfo.PropagandaInfo;
import com.xinelu.manage.domain.questioninfo.QuestionInfo;
import com.xinelu.manage.domain.scriptInfo.ScriptInfo;
@ -50,6 +51,7 @@ import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientquestionsubmitresult.PatientQuestionSubmitResultMapper;
import com.xinelu.manage.mapper.patienttaskexecuterecord.PatientTaskExecuteRecordMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.phonedialrecord.PhoneDialRecordMapper;
import com.xinelu.manage.mapper.scriptInfo.ScriptInfoMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
@ -154,6 +156,8 @@ public class SignPatientManageRouteNodeServiceImpl implements ISignPatientManage
private PatientTaskExecuteRecordMapper patientTaskExecuteRecordMapper;
@Resource
private IPatientTaskStatisticsService patientTaskStatisticsService;
@Resource
private PhoneDialRecordMapper phoneDialRecordMapper;
/**
* 查询签约患者管理任务路径节点
@ -579,6 +583,11 @@ public class SignPatientManageRouteNodeServiceImpl implements ISignPatientManage
return specialDiseaseNodeMapper.selectRouteNodeByRouteId(manageRouteList.get(0).getRouteId());
}
@Override public String getPhoneDialVideo(Long id) {
PhoneDialRecord phoneDialRecord = phoneDialRecordMapper.getLastRecord(id);
return ObjectUtils.isEmpty(phoneDialRecord) ? null : phoneDialRecord.getPhoneDialRecordVideo();
}
/**
* 生成有参数得任务
* @param routeNodeId 节点id

View File

@ -1,23 +1,36 @@
package com.xinelu.manage.service.statistics.impl;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.enums.NodeTypeEnum;
import com.xinelu.common.enums.PhoneDialMethodEnum;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.manage.domain.agency.Agency;
import com.xinelu.manage.domain.department.Department;
import com.xinelu.manage.dto.statistics.FollowUpRateDto;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.phonedialrecord.PhoneDialRecordMapper;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper;
import com.xinelu.manage.service.agency.IAgencyService;
import com.xinelu.manage.service.department.IDepartmentService;
import com.xinelu.manage.service.statistics.IStatisticsService;
import com.xinelu.manage.vo.patientvisitrecord.PatientVisitRecordStatisticVo;
import com.xinelu.manage.vo.phonedialrecord.PhoneDialRecordVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientFollowUpPlanVo;
import com.xinelu.manage.vo.statistics.FollowUpDetailVo;
import com.xinelu.manage.vo.statistics.FollowUpNumTrendVo;
import com.xinelu.manage.vo.statistics.FollowUpRateTrendVo;
import com.xinelu.manage.vo.statistics.FollowUpRateVo;
import com.xinelu.manage.vo.statistics.MessageSendVo;
import com.xinelu.system.service.ISysUserService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -40,6 +53,16 @@ public class StatisticsServiceImpl implements IStatisticsService {
private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
@Resource
private SubscribeMessageSendRecordMapper subscribeMessageSendRecordMapper;
@Resource
private PatientVisitRecordMapper patientVisitRecordMapper;
@Resource
private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
@Resource
private IAgencyService agencyService;
@Resource
private IDepartmentService departmentService;
@Resource
private ISysUserService userService;
/**
* @description 随访成功率统计
@ -130,7 +153,101 @@ public class StatisticsServiceImpl implements IStatisticsService {
*/
@Override
public List<FollowUpDetailVo> getFollowUpDetail(FollowUpRateDto queryDto) {
return null;
List<FollowUpDetailVo> retList = new ArrayList<>();
FollowUpDetailVo followUpDetailVo = new FollowUpDetailVo();
// 总计行预留位置
retList.set(0, followUpDetailVo);
// 就诊患者列表查询
List<PatientVisitRecordStatisticVo> patientVisitList = patientVisitRecordMapper.getVisitPatientList(queryDto);
// 随访计划列表查询
List<PatientFollowUpPlanVo> planList = signPatientManageRouteNodeMapper.getFollowUpPlan(queryDto);
if (StringUtils.equals(queryDto.getType(), "dept")) {
// 就诊患者列表按照科室分组
Map<Long, List<PatientVisitRecordStatisticVo>> groupByDept = new HashMap<>();
if (CollectionUtils.isNotEmpty(patientVisitList)) {
groupByDept = patientVisitList.stream().collect(Collectors.groupingBy(PatientVisitRecordStatisticVo::getDepartmentId));
}
Map<Long, List<PatientFollowUpPlanVo>> planGroupByDept = new HashMap<>();
if (CollectionUtils.isNotEmpty(planList)) {
// 随访计划列表按照科室分组
planGroupByDept = planList.stream().collect(Collectors.groupingBy(PatientFollowUpPlanVo::getDepartmentId));
}
// 查询机构科室医生列表
Agency agencyQuery = new Agency();
agencyQuery.setId(queryDto.getHospitalAgencyId());
List<Agency> agencyList = agencyService.selectAgencyByIdList(agencyQuery);
for (Agency agency : agencyList) {
// 根据机构列表查询科室
Department deptQuery = new Department();
deptQuery.setHospitalAgencyId(agency.getId());
deptQuery.setNodeType(NodeTypeEnum.DEPARTMENT.getInfo());
List<Department> deptList = departmentService.selectDepartmentList(deptQuery);
for (Department dept : deptList) {
followUpDetailVo.setRowName(dept.getDepartmentName());
// 就诊人数
List<PatientVisitRecordStatisticVo> deptVisitList = groupByDept.get(dept.getId());
followUpDetailVo.setPatientNum(CollectionUtils.isEmpty(deptVisitList) ? 0 : groupByDept.get(dept.getId()).size());
// 科室统计随访计划人数随访覆盖率随访成功人数随访成功率
List<PatientFollowUpPlanVo> deptPlanList = planGroupByDept.get(dept.getId());
getFollowUpDetailVo(deptPlanList, followUpDetailVo);
// 查询科室医生
SysUser userQuery = new SysUser();
userQuery.setHospitalAgencyId(dept.getHospitalAgencyId());
userQuery.setDepartmentId(dept.getId());
List<SysUser> userList = userService.selectUserList(userQuery);
List<FollowUpDetailVo> childrenList = new ArrayList<>();
Map<Long, List<PatientVisitRecordStatisticVo>> patientGroupByDoctor = deptVisitList.stream().collect(Collectors.groupingBy(PatientVisitRecordStatisticVo::getAttendingPhysicianId));
Map<Long, List<PatientFollowUpPlanVo>> planGroupByDoctor = deptPlanList.stream().collect(Collectors.groupingBy(PatientFollowUpPlanVo::getAttendingPhysicianId));
for (SysUser user : userList) {
FollowUpDetailVo childRow = new FollowUpDetailVo();
childRow.setRowName(user.getNickName());
// 医生就诊人数
childRow.setPatientNum(CollectionUtils.isEmpty(patientGroupByDoctor.get(user.getUserId())) ? 0 : planGroupByDoctor.get(user.getUserId()).size());
// 医生统计随访计划人数随访覆盖率随访成功人数随访成功率
List<PatientFollowUpPlanVo> doctorPlanList = planGroupByDoctor.get(dept.getId());
getFollowUpDetailVo(doctorPlanList, childRow);
childrenList.add(childRow);
}
followUpDetailVo.setChilderenList(childrenList);
retList.add(followUpDetailVo);
}
}
} else if (StringUtils.equals(queryDto.getType(), "date")){
// 日期列表
List<String> months = new ArrayList<>();
LocalDate startDate = queryDto.getStartDate();
while (!startDate.isAfter(queryDto.getEndDate())) {
months.add(startDate.format(DateTimeFormatter.ofPattern("yyyy-MM")));
startDate = startDate.plus(1, ChronoUnit.MONTHS);
}
// 就诊患者列表按照就诊日期分组
Map<String, List<PatientVisitRecordStatisticVo>> groupByVisitDate = new HashMap<>();
if (CollectionUtils.isNotEmpty(patientVisitList)) {
groupByVisitDate = patientVisitList.stream().collect(Collectors.groupingBy(PatientVisitRecordStatisticVo::getDischargeTimeMonthStr));
}
Map<String, List<PatientFollowUpPlanVo>> planGroupByExecuteDate = new HashMap<>();
if (CollectionUtils.isNotEmpty(planList)) {
// 随访计划列表按照计划日期分组
planGroupByExecuteDate = planList.stream().collect(Collectors.groupingBy(PatientFollowUpPlanVo::getExecuteMonthStr));
}
for (String month : months) {
}
}
// 计算总计行
getTotalRow(retList);
return retList;
}
/**
@ -189,4 +306,59 @@ public class StatisticsServiceImpl implements IStatisticsService {
return retObj;
}
/**
* @description 统计随访计划人数随访覆盖率随访成功人数随访成功率
* @Param planList 随访计划
* @Param followUpDetailVo 随访明细表
* @Author haown
* @Date 2024-11-4 11:13
*/
private FollowUpDetailVo getFollowUpDetailVo(List<PatientFollowUpPlanVo> planList, FollowUpDetailVo followUpDetailVo) {
if (followUpDetailVo.getPatientNum() == 0) {
followUpDetailVo.setFollowUpNum(0);
followUpDetailVo.setFollowUpCoverRate(BigDecimal.ZERO);
followUpDetailVo.setFollowUpSuccessNum(0);
followUpDetailVo.setFollowUpSuccessRate(BigDecimal.ZERO);
return followUpDetailVo;
}
// 按照patientId分组
Map<Long, List<PatientFollowUpPlanVo>> groupByPatient = planList.stream().collect(Collectors.groupingBy(PatientFollowUpPlanVo::getPatientId));
// 有随访计划人数
followUpDetailVo.setFollowUpNum(groupByPatient.keySet().size());
// 随访覆盖率
followUpDetailVo.setFollowUpCoverRate(new BigDecimal(followUpDetailVo.getFollowUpNum()).divide(new BigDecimal(followUpDetailVo.getPatientNum()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
// 随访成功人数
Map<Long, List<PatientFollowUpPlanVo>> groupByFinishStatus = planList.stream().filter(item -> item.getTaskFinishStatus() == 1).collect(Collectors.groupingBy(PatientFollowUpPlanVo::getPatientId));
followUpDetailVo.setFollowUpSuccessNum(groupByFinishStatus.keySet().size());
// 随访成功率
followUpDetailVo.setFollowUpSuccessRate(new BigDecimal(followUpDetailVo.getFollowUpSuccessNum()).divide(new BigDecimal(followUpDetailVo.getPatientNum()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
return followUpDetailVo;
}
/**
* @description 计算总计行就诊人数随访计划人数随访覆盖率随访成功人数随访成功率
* @Param * @param null
* @return 列表数据
* @Author haown
* @Date 2024-11-4 11:29
*/
private List<FollowUpDetailVo> getTotalRow(List<FollowUpDetailVo> followUpDetailVoList) {
for (FollowUpDetailVo retObj : followUpDetailVoList) {
retObj.setRowName("总计");
// 就诊人数
retObj.setPatientNum(followUpDetailVoList.stream().map(FollowUpDetailVo::getPatientNum).reduce(Integer::sum).get());
// 随访计划人数
retObj.setFollowUpNum(followUpDetailVoList.stream().map(FollowUpDetailVo::getFollowUpNum).reduce(Integer::sum).get());
// 随访覆盖率
retObj.setFollowUpCoverRate(new BigDecimal(retObj.getFollowUpNum()).divide(new BigDecimal(retObj.getPatientNum()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
// 随访成功人数
retObj.setFollowUpSuccessNum(followUpDetailVoList.stream().map(FollowUpDetailVo::getFollowUpSuccessNum).reduce(Integer::sum).get());
// 随访成功率
retObj.setFollowUpCoverRate(new BigDecimal(retObj.getFollowUpSuccessNum()).divide(new BigDecimal(retObj.getPatientNum()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")));
followUpDetailVoList.set(0, retObj);
}
return followUpDetailVoList;
}
}

View File

@ -2,10 +2,9 @@ package com.xinelu.manage.vo.manualfollowup;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
* 人工随访代办VO
@ -143,7 +142,19 @@ public class ManualFollowUpVO {
@ApiModelProperty(value = "任务节点类型电话外呼PHONE_OUTBOUND问卷量表QUESTIONNAIRE_SCALE宣教文章PROPAGANDA_ARTICLE文字提醒TEXT_REMIND")
private String taskNodeType;
/**
* AI自动 COMMON手动
*/
@ApiModelProperty(value = "AI自动 或 COMMON手动")
private String phoneDialMethod;
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "计划时间")
private LocalDate planTime;
/**
* 生成通话录音唯一标识,可通过该标识获取录音
*/
@ApiModelProperty(value = "生成通话录音唯一标识,可通过该标识,获取录音")
private String ctUUID;
}

View File

@ -0,0 +1,76 @@
package com.xinelu.manage.vo.patientvisitrecord;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description: 就诊记录统计返回视图类
* @author: haown
* @create: 2024-11-01 15:03
**/
@ApiModel("就诊记录统计返回视图类")
@Data
public class PatientVisitRecordStatisticVo {
/**
* 所属医院id
*/
@ApiModelProperty(value = "所属医院id")
private Long hospitalAgencyId;
/**
* 所属医院名称
*/
@ApiModelProperty(value = "所属医院名称")
private String hospitalAgencyName;
/**
* 所属院区id
*/
@ApiModelProperty(value = "所属院区id")
private Long campusAgencyId;
/**
* 所属院区名称
*/
@ApiModelProperty(value = "所属院区名称")
private String campusAgencyName;
/**
* 所属科室id
*/
@ApiModelProperty(value = "所属科室id")
private Long departmentId;
/**
* 所属科室名称
*/
@ApiModelProperty(value = "所属科室名称")
private String departmentName;
/**
* 所属病区id
*/
@ApiModelProperty(value = "所属病区id")
private Long wardId;
/**
* 所属病区名称
*/
@ApiModelProperty(value = "所属病区名称")
private String wardName;
/** 主治医生id */
@ApiModelProperty(value = "主治医生id")
private Long attendingPhysicianId;
/** 主治医生姓名 */
@ApiModelProperty(value = "主治医生姓名")
private String attendingPhysicianName;
/** 出院时间 */
@ApiModelProperty(value = "出院时间月份")
private String dischargeTimeMonthStr;
}

View File

@ -0,0 +1,55 @@
package com.xinelu.manage.vo.signpatientmanageroutenode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description: 随访计划执行列表查询返回视图类
* @author: haown
* @create: 2024-11-01 16:58
**/
@ApiModel("随访计划执行列表查询返回视图类")
@Data
public class PatientFollowUpPlanVo {
private Long id;
/**
* 患者主键
*/
@ApiModelProperty(value = "患者主键")
private Long patientId;
/** 所属科室id */
@ApiModelProperty(value = "所属科室id")
private Long departmentId;
/** 所属科室名称 */
@ApiModelProperty(value = "所属科室名称")
private String departmentName;
/**
* 主治医生id
*/
@ApiModelProperty(value = "主治医生id")
private Long attendingPhysicianId;
/**
* 主治医生姓名
*/
@ApiModelProperty(value = "主治医生姓名")
private String attendingPhysicianName;
/**
* 任务执行状态1完成0未完成
*/
@ApiModelProperty(value = "任务执行状态")
private Integer taskFinishStatus;
/**
* 任务执行月份
*/
@ApiModelProperty(value = "任务执行月份")
private String executeMonthStr;
}

View File

@ -501,4 +501,32 @@
</if>
</where>
</select>
<select id="getVisitPatientList" resultType="com.xinelu.manage.vo.patientvisitrecord.PatientVisitRecordStatisticVo">
select hospital_agency_id, hospital_agency_name, campus_agency_id, campus_agency_name,
department_id, department_name, ward_id, ward_name,
attending_physician_id,attending_physician_name,
date_format(discharge_time, '%Y-%m') as dischargeTimeMonthStr
from patient_visit_record
<where>
del_flag = 0
<if test="hospitalAgencyId != null">
and hospital_agency_id = #{hospitalAgencyId}
</if>
<if test="campusAgencyId != null">
and campus_agency_id = #{campusAgencyId}
</if>
<if test="departmentId != null">
and department_id = #{departmentId}
</if>
<if test="wardId != null">
and ward_id = #{wardId}
</if>
<if test="startDate != null">
and date_format(discharge_time,'%y%m') &gt;= date_format(#{startDate},'%y%m')
</if>
<if test="endDate != null">
and date_format(discharge_time,'%y%m') &lt;= date_format(#{endDate},'%y%m')
</if>
</where>
</select>
</mapper>

View File

@ -20,6 +20,9 @@
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="ctUuid" column="ct_uuid"/>
<result property="phoneDialRecordVideo" column="phone_dial_record_video"/>
</resultMap>
<sql id="selectPhoneDialRecordVo">
@ -37,7 +40,9 @@
create_by,
create_time,
update_by,
update_time
update_time,
ct_uuid,
phone_dial_record_video
from phone_dial_record
</sql>
@ -115,6 +120,10 @@
</if>
<if test="updateTime != null">update_time,
</if>
<if test="ctUuid != null">ct_uuid,
</if>
<if test="phoneDialRecordVideo != null">phone_dial_record_video,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="patientId != null">#{patientId},
@ -145,6 +154,10 @@
</if>
<if test="updateTime != null">#{updateTime},
</if>
<if test="ctUuid != null">#{ctUuid},
</if>
<if test="phoneDialRecordVideo != null">#{phoneDialRecordVideo},
</if>
</trim>
</insert>
@ -244,4 +257,10 @@
</if>
</where>
</select>
<select id="getLastRecord" parameterType="java.lang.Long" resultMap="PhoneDialRecordResult">
<include refid="selectPhoneDialRecordVo"/>
where manage_route_node_id = #{manageRouteNodeId}
order by dial_time desc limit 1
</select>
</mapper>

View File

@ -336,7 +336,8 @@
spmrn.script_info_id,
spmrn.follow_template_id,
spmrn.node_execute_status,
spmrn.route_handle_remark
spmrn.route_handle_remark,
spmrn.phone_dial_method
FROM
sign_patient_manage_route spmr
LEFT JOIN sign_patient_manage_route_node spmrn ON spmr.id = spmrn.manage_route_id
@ -396,6 +397,10 @@
<if test="phoneNodeExecuteResultStatus = null">
AND (spmrn.phone_node_execute_result_status is null or spmrn.phone_node_execute_result_status = ' ')
</if>
<if test="phoneDialMethod != null">
AND spmrn.phone_dial_method = #{phoneDialMethod}
</if>
<!-- 数据范围过滤 -->
${params.dataScope}
</where>

View File

@ -1001,4 +1001,37 @@
AND spmrn.route_check_status = 'AGREE'
AND spmrn.task_node_type in ('PHONE_OUTBOUND','QUESTIONNAIRE_SCALE')
</select>
<select id="getFollowUpPlan" resultType="com.xinelu.manage.vo.signpatientmanageroutenode.PatientFollowUpPlanVo">
SELECT task.manage_route_node_id as id,
task.id as PatientId,
task.hospital_agency_id,
task.hospital_agency_name,
task.department_id,
task.department_name,
task.attending_physician_id,
task.attending_physician_name,
task.task_finish_status,
date_format(task.execute_date_time, '%Y-%m') as executeMonthStr
from patient_task_view task
<where>
<if test="hospitalAgencyId != null">
and task.hospital_agency_id = #{hospitalAgencyId}
</if>
<if test="campusAgencyId != null">
and task.campus_agency_id = #{campusAgencyId}
</if>
<if test="departmentId != null">
and task.department_id = #{departmentId}
</if>
<if test="wardId != null">
and task.ward_id = #{wardId}
</if>
<if test="startDate != null">
and task.date_format(execute_date_time,'%y%m') &gt;= date_format(#{startDate},'%y%m')
</if>
<if test="endDate != null">
and task.date_format(execute_date_time,'%y%m') &lt;= date_format(#{endDate},'%y%m')
</if>
</where>
</select>
</mapper>

View File

@ -58,7 +58,6 @@ public class GenerateChildRouteTask {
childSpecialRoutes.forEach(specialDiseaseRoute -> {
// 查询路径是否生成过任务
manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
manageRouteQuery.setRouteId(specialDiseaseRoute.getId());
manageRouteQuery.setParentRouteId(signPatientManageRoute.getId());
List<SignPatientManageRoute> createManageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
if (CollectionUtils.isEmpty(createManageRouteList)) {