导出修改

This commit is contained in:
zhangheng 2026-02-09 16:38:38 +08:00
parent c5f5d45167
commit a02360918a
8 changed files with 377 additions and 18 deletions

View File

@ -0,0 +1,32 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* 问卷题目选项类型
*/
@Getter
public enum QuestionSubjectTypeEnum {
/**
* 单选题
*/
MULTIPLE_CHOICE("MULTIPLE_CHOICE"),
/**
* 多选题
*/
MULTIPLE_CHOICE_QUESTIONS("MULTIPLE_CHOICE_QUESTIONS"),
/**
* 填空题
*/
FILL_IN_THE_BLANKS("FILL_IN_THE_BLANKS"),
;
final private String info;
QuestionSubjectTypeEnum(String info) {
this.info = info;
}
}

View File

@ -159,7 +159,7 @@ public class SignPatientManageRouteNodeController extends BaseController {
}
@ApiOperation("外呼记录导出")
@PostMapping("/export")
//@PostMapping("/export")
public void export(HttpServletResponse response, UploadRobotPublishRecordDto uploadRobotPublishRecordDto) {
List<UploadRobotPublishRecordVo> list = signNodeService.uploadRobotPublishRecord(uploadRobotPublishRecordDto);
if (CollectionUtils.isNotEmpty(list)){
@ -168,4 +168,12 @@ public class SignPatientManageRouteNodeController extends BaseController {
ExcelUtil<UploadRobotPublishRecordVo> util = new ExcelUtil<UploadRobotPublishRecordVo>(UploadRobotPublishRecordVo.class);
util.exportExcel(response, list, "外呼记录");
}
@ApiOperation("外呼记录导出")
@PostMapping("/export")
public void questionnaireExport(HttpServletResponse response, UploadRobotPublishRecordDto uploadRobotPublishRecordDto) {
List<FollowUpFeedbackVo> list = signNodeService.selectAIQuestionnaireList(uploadRobotPublishRecordDto);
ExcelUtil<FollowUpFeedbackVo> util = new ExcelUtil<>(FollowUpFeedbackVo.class);
util.exportExcel(response, list, "外呼记录");
}
}

View File

@ -256,4 +256,20 @@ public interface SignPatientManageRouteNodeMapper {
* @return SignPatientManageRouteNode
*/
SignPatientManageRouteNode selectSignPatientManageRouteNode(SignPatientManageRouteNode signPatientManageRouteNode);
/**
* 问卷外呼记录查询
*
* @param uploadRobotPublishRecordDto 时间信息
* @return UploadRobotPublishRecordVo
*/
List<FollowUpFeedbackVo> selectAIQuestionnaireList(UploadRobotPublishRecordDto uploadRobotPublishRecordDto);
/**
* 问卷选项记录查询
*
* @param manageRouteNodeIds
* @return QuestionSubmitExportVo
*/
List<QuestionSubmitExportVo> selectQuestionSubmit(List<Long> manageRouteNodeIds);
}

View File

@ -233,4 +233,12 @@ public interface ISignPatientManageRouteNodeService {
* @return UploadRobotPublishRecordVo
*/
List<UploadRobotPublishRecordVo> uploadRobotPublishRecord(UploadRobotPublishRecordDto uploadRobotPublishRecordDto);
/**
* 外呼记录
*
* @param uploadRobotPublishRecordDto 时间信息
* @return UploadRobotPublishRecordVo
*/
List<FollowUpFeedbackVo> selectAIQuestionnaireList(UploadRobotPublishRecordDto uploadRobotPublishRecordDto);
}

View File

@ -14,13 +14,7 @@ import com.xinelu.common.constant.TemplateTypeConstants;
import com.xinelu.common.constant.TriggerConditionOperatorConstants;
import com.xinelu.common.constant.TriggerLogicConstants;
import com.xinelu.common.constant.VisitMethodConstants;
import com.xinelu.common.enums.MessageStatusEnum;
import com.xinelu.common.enums.NodeExecuteResultStatusEnum;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.PhoneDialMethodEnum;
import com.xinelu.common.enums.QuestionTypeEnum;
import com.xinelu.common.enums.RouteCheckStatusEnum;
import com.xinelu.common.enums.RouteNodeNameEnum;
import com.xinelu.common.enums.*;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
@ -80,16 +74,7 @@ import com.xinelu.manage.vo.patientinfo.PatientNextTaskVo;
import com.xinelu.manage.vo.patientquestionsubmitresult.PatientQuestionSubmitResultVO;
import com.xinelu.manage.vo.propagandainfo.PropagandaMaterialsVo;
import com.xinelu.manage.vo.questionInfo.QuestionVO;
import com.xinelu.manage.vo.signpatientmanageroutenode.AIDialRecordVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.AppletRouteNodeListVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeInfoVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeListVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientTaskVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageRouteNodeInfoVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageRouteNodeVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientTaskVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.UploadRobotPublishRecordVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.*;
import com.xinelu.manage.vo.specialdiseasenode.PatientSpecialDiseaseNodeVo;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeVO;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO;
@ -104,6 +89,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -1481,6 +1467,69 @@ public class SignPatientManageRouteNodeServiceImpl implements ISignPatientManage
return uploadRobotPublishRecordVos;
}
/**
* 外呼记录
*
* @param uploadRobotPublishRecordDto 时间信息
* @return FollowUpFeedbackVo
*/
@Override
public List<FollowUpFeedbackVo> selectAIQuestionnaireList(UploadRobotPublishRecordDto uploadRobotPublishRecordDto) {
//查询管理任务节点数据
List<FollowUpFeedbackVo> followUpFeedbackVos = signPatientManageRouteNodeMapper.selectAIQuestionnaireList(uploadRobotPublishRecordDto);
if (CollectionUtils.isEmpty(followUpFeedbackVos)) {
return new ArrayList<>();
}
Map<Long, FollowUpFeedbackVo> userMap = followUpFeedbackVos.stream().collect(Collectors.toMap(FollowUpFeedbackVo::getManageRouteNodeId, Function.identity()));
List<Long> manageRouteNodeIds = followUpFeedbackVos.stream().filter(Objects::nonNull).map(UploadRobotPublishRecordVo::getManageRouteNodeId).collect(Collectors.toList());
//问卷题目选项查询
List<QuestionSubmitExportVo> questionSubmitExportVos = signPatientManageRouteNodeMapper.selectQuestionSubmit(manageRouteNodeIds);
if (CollectionUtils.isEmpty(questionSubmitExportVos)) {
return followUpFeedbackVos;
}
//遍历塞值
for (QuestionSubmitExportVo questionSubmitExportVo : questionSubmitExportVos) {
//没数据跳出
FollowUpFeedbackVo followUpFeedbackVo = userMap.get(questionSubmitExportVo.getManageRouteNodeId());
if (Objects.isNull(followUpFeedbackVo)) {
continue;
}
//题目是单选
if (questionSubmitExportVo.getQuestionType().equals(QuestionSubjectTypeEnum.MULTIPLE_CHOICE.getInfo())) {
//序号1 已选择数据
if (questionSubmitExportVo.getQuestionNumber() == 1 && Objects.nonNull(questionSubmitExportVo.getOptionChooseSign()) && questionSubmitExportVo.getOptionChooseSign() == 0) {
followUpFeedbackVo.setWorkingPersonnelService(questionSubmitExportVo.getOptionName());
if (StringUtils.isNotBlank(questionSubmitExportVo.getOptionSubmitAnswer())) {
followUpFeedbackVo.setWorkingPersonnelServiceSuggestion(questionSubmitExportVo.getOptionSubmitAnswer());
}
//序号2 已选择数据
} else if (questionSubmitExportVo.getQuestionNumber() == 2 && Objects.nonNull(questionSubmitExportVo.getOptionChooseSign()) && questionSubmitExportVo.getOptionChooseSign() == 0) {
followUpFeedbackVo.setConsultConvenientDegree(questionSubmitExportVo.getOptionName());
if (StringUtils.isNotBlank(questionSubmitExportVo.getOptionSubmitAnswer())) {
followUpFeedbackVo.setConsultConvenientDegreeSuggestion(questionSubmitExportVo.getOptionSubmitAnswer());
}
//序号3 已选择数据
} else if (questionSubmitExportVo.getQuestionNumber() == 3 && Objects.nonNull(questionSubmitExportVo.getOptionChooseSign()) && questionSubmitExportVo.getOptionChooseSign() == 0) {
followUpFeedbackVo.setDoctorServiceAttitude(questionSubmitExportVo.getOptionName());
if (StringUtils.isNotBlank(questionSubmitExportVo.getOptionSubmitAnswer())) {
followUpFeedbackVo.setDoctorServiceAttitudeSuggestion(questionSubmitExportVo.getOptionSubmitAnswer());
}
//序号4 已选择数据
} else if (questionSubmitExportVo.getQuestionNumber() == 4 && Objects.nonNull(questionSubmitExportVo.getOptionChooseSign()) && questionSubmitExportVo.getOptionChooseSign() == 0) {
followUpFeedbackVo.setHospitalEnvironment(questionSubmitExportVo.getOptionName());
if (StringUtils.isNotBlank(questionSubmitExportVo.getOptionSubmitAnswer())) {
followUpFeedbackVo.setHospitalEnvironmentSuggestion(questionSubmitExportVo.getOptionSubmitAnswer());
}
}
}
//题目是多选
if (questionSubmitExportVo.getQuestionType().equals(QuestionSubjectTypeEnum.FILL_IN_THE_BLANKS.getInfo())) {
followUpFeedbackVo.setWorkSuggestions(questionSubmitExportVo.getFillBlanksAnswer());
}
}
return followUpFeedbackVos;
}
/**
* 根据管理路径生成任务
* @param signPatientManageRoute 签约管理路径

View File

@ -0,0 +1,69 @@
package com.xinelu.manage.vo.signpatientmanageroutenode;
import com.xinelu.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Description 外呼导出随访反馈实体类
* @Author zh
* @Date 2026-02-06
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class FollowUpFeedbackVo extends UploadRobotPublishRecordVo{
/**
* 工作人员的服务态度反馈
*/
@Excel(name = "工作人员的服务态度反馈")
private String workingPersonnelService;
/**
* 工作人员的服务态度反馈意见
*/
@Excel(name = "工作人员的服务态度反馈意见")
private String workingPersonnelServiceSuggestion;
/**
* 门诊就诊流程便捷程度反馈
*/
@Excel(name = "门诊就诊流程便捷程度反馈")
private String consultConvenientDegree;
/**
* 门诊就诊流程便捷程度反馈意见
*/
@Excel(name = "门诊就诊流程便捷程度反馈意见")
private String consultConvenientDegreeSuggestion;
/**
* 医生的服务态度反馈
*/
@Excel(name = "医生的服务态度反馈")
private String doctorServiceAttitude;
/**
* 医生的服务态度反馈意见
*/
@Excel(name = "医生的服务态度反馈意见")
private String doctorServiceAttitudeSuggestion;
/**
* 医院就医环境反馈
*/
@Excel(name = "医院就医环境反馈")
private String hospitalEnvironment;
/**
* 医院就医环境反馈意见
*/
@Excel(name = "医院就医环境反馈意见")
private String hospitalEnvironmentSuggestion;
/**
* 工作建议
*/
@Excel(name = "工作建议")
private String workSuggestions;
}

View File

@ -0,0 +1,55 @@
package com.xinelu.manage.vo.signpatientmanageroutenode;
import lombok.Data;
/**
* 外呼问卷导出vo
*/
@Data
public class QuestionSubmitExportVo {
/**
* 管理任务路径节点id
*/
private Long manageRouteNodeId;
/**
* 问卷id
*/
private Long questionInfoId;
/**
* 问卷标号
*/
private Long questionNumber;
/**
* 题目类型单选题MULTIPLE_CHOICE多选题MULTIPLE_CHOICE_QUESTIONS填空题FILL_IN_THE_BLANKS
*/
private String questionType;
/**
* 回答填空题
*/
private String fillBlanksAnswer;
/**
* 问卷名称
*/
private String questionName;
/**
* 题目名称
*/
private String optionName;
/**
* 题目选项选择标识0已选择1未选择
*/
private Long optionChooseSign;
/**
* 选项题目提交答案
*/
private String optionSubmitAnswer;
}

View File

@ -1431,4 +1431,126 @@
where create_by = #{createBy}
order by create_time desc limit 1
</select>
<select id="selectAIQuestionnaireList"
resultType="com.xinelu.manage.vo.signpatientmanageroutenode.FollowUpFeedbackVo">
SELECT
spmrn.id manageRouteNodeId,
spmrn.manage_route_name,
spmrn.task_node_type,
spmrn.dial_status,
spmrn.question_info_id,
spmrn.questionnaire_name,
spmrn.node_execute_status,
spmrn.node_plan_time,
spmrn.task_excute_type,
spmrn.sn,
spmrn.phone_node_execute_result_status,
CASE
WHEN spmrn.node_execute_status = 'EXECUTED' THEN '已随访'
WHEN spmrn.node_execute_status = 'UNEXECUTED' THEN '未随访'
END AS followUpStatus,
CASE
WHEN spmrn.phone_dial_method = 'AI' THEN 'AI'
WHEN spmrn.phone_dial_method = 'COMMON' THEN spmrn.route_handle_person
END AS phoneDialMethod,
spmrn.create_by AS samplingPersonnel,
spmrn.create_time AS SampleTime,
CASE
WHEN pqsr.contented_flag = 'DISCONTENTED' THEN '不满意'
WHEN pqsr.contented_flag = 'CONTENTED' THEN '满意'
END AS contentedFlag,
pqsr.task_execute_record_id,
pqsr.remarkable_flag,
pqsr.id,
pqsr.total_score,
pi.patient_phone,
pi.patient_name,
pi.id AS patientId,
pi.department_name,
pi.department_id,
pi.hospital_agency_id,
pi.hospital_agency_name,
pi.visit_date,
pi.age,
pi.patient_visit_record_id,
pi.main_diagnosis,
CASE
WHEN spmrn.task_node_type = 'PHONE_OUTBOUND' THEN spmrn.script_info_id
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN qi.script_info_id
END AS scriptTemplateId,
CASE
WHEN spmrn.task_node_type = 'PHONE_OUTBOUND' THEN spmrn.phone_template_name
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN qi.script_name
END AS scriptTemplateName
FROM sign_patient_manage_route_node spmrn
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
LEFT JOIN patient_question_submit_result pqsr ON pqsr.manage_route_node_id = spmrn.id
LEFT JOIN patient_info pi ON spmr.patient_id = pi.id
LEFT JOIN question_info qi on spmrn.question_info_id = qi.id
WHERE
spmrn.del_flag = 0
<if test="departmentId != null">
and pi.department_id = #{departmentId}
</if>
<if test="hospitalAgencyId != null">
and pi.hospital_agency_id = #{hospitalAgencyId}
</if>
<if test="patientId != null">
and pi.id = #{patientId}
</if>
<if test="patientName != null and patientName != ''">
and pi.patient_name like concat('%', #{patientName}, '%')
</if>
<if test="patientPhone != null">
and pi.patient_phone = #{patientPhone}
</if>
<if test="taskNodeType != null and taskNodeType != ''">
and spmrn.task_node_type = #{taskNodeType}
</if>
<if test="questionInfoId != null">
AND spmrn.question_info_id = #{questionInfoId}
</if>
<if test="startTime != null"><!-- 开始时间检索 -->
AND date_format(spmrn.node_plan_time,'%y%m%d') &gt;= date_format(#{startTime},'%y%m%d')
</if>
<if test="endTime != null"><!-- 结束时间检索 -->
AND date_format(spmrn.node_plan_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')
</if>
<if test="nodeExecuteStatus != null and nodeExecuteStatus != ''">
and spmrn.node_execute_status = #{nodeExecuteStatus}
</if>
<if test="taskExcuteType != null and taskExcuteType != ''">
and spmrn.task_excute_type = #{taskExcuteType}
</if>
<if test="phoneNodeExecuteResultStatus != null and phoneNodeExecuteResultStatus != ''">
and spmrn.phone_node_execute_result_status = #{phoneNodeExecuteResultStatus}
</if>
<if test="sn != null and sn != ''">
and spmrn.sn = #{sn}
</if>
<if test="contentedFlag != null and contentedFlag != ''">
and pqsr.contented_flag = #{contentedFlag}
</if>
${params.dataScope}
GROUP BY spmrn.id
ORDER BY spmrn.create_time DESC
</select>
<select id="selectQuestionSubmit"
resultType="com.xinelu.manage.vo.signpatientmanageroutenode.QuestionSubmitExportVo">
select pqsm.manage_route_node_id,
pqsm.question_info_id,
pqsj.question_number,
pqsj.fill_blanks_answer,
pqsj.question_type,
pqsj.question_name,
pqor.option_name,
pqor.option_choose_sign,
pqor.option_submit_answer
from patient_question_submit_result pqsm
LEFT JOIN patient_question_subject_result pqsj on pqsm.id = pqsj.question_submit_result_id
LEFT JOIN patient_question_option_result pqor on pqsj.id = pqor.question_subject_result_id
ORDER BY pqsm.create_time DESC
</select>
</mapper>