| | |
| | | return "再次随访任务创建失败,找不到对应任务 taskid = " + serviceSubtask.getTaskid() + ", 再请次重试"; |
| | | } |
| | | // nexttaskflag=0 表示任务链终止,不允许再生成 |
| | | if ("0".equals(serviceTask.getNexttaskflag())) { |
| | | log.info("无需再次随访,任务已标记无后续随访, taskid = {}", serviceSubtask.getTaskid()); |
| | | return "无需再次随访,该任务无后续随访安排"; |
| | | } |
| | | // if ("0".equals(serviceTask.getNexttaskflag())) { |
| | | // log.info("无需再次随访,任务已标记无后续随访, taskid = {}", serviceSubtask.getTaskid()); |
| | | // return "无需再次随访,该任务无后续随访安排"; |
| | | // } |
| | | // 幂等校验:同一原任务只允许生成一条二次随访 |
| | | ServiceSubtaskEntity againQuery = new ServiceSubtaskEntity(); |
| | | againQuery.setUpid(serviceSubtask.getId().intValue()); |
| | |
| | | return "再次随访任务创建失败,患者出院记录不完整或下一任务配置异常, 再请次重试"; |
| | | } |
| | | Date now = new Date(); |
| | | applyAgainVisitTime(serviceSubtaskAgain, serviceSubtask, nextServiceTask, config, now); |
| | | // 医生处理意见取自本次请求,按下一任务重建子任务时需显式带入,否则不会落库 |
| | | if (request != null) { |
| | | serviceSubtaskAgain.setDoctorOpinion(request.getDoctorOpinion()); |
| | | serviceSubtaskAgain.setRemark(request.getRemark()); |
| | | serviceSubtaskAgain.setDrcode(request.getDrcode()); |
| | | serviceSubtaskAgain.setDrname(request.getDrname()); |
| | | serviceSubtaskAgain.setNurseId(request.getNurseId()); |
| | | serviceSubtaskAgain.setNurseName(request.getNurseName()); |
| | | serviceSubtaskAgain.setManagementDoctor(request.getManagementDoctor()); |
| | | serviceSubtaskAgain.setManagementDoctorCode(request.getManagementDoctorCode()); |
| | | } |
| | | serviceSubtaskAgain.setId(null); |
| | | serviceSubtaskAgain.setUpid(serviceSubtask.getId().intValue()); |
| | | serviceSubtaskAgain.setVisitCount(ObjectUtils.isNotEmpty(serviceSubtask.getVisitCount()) |
| | |
| | | serviceSubtaskAgain.setIsVisitAgain(1); |
| | | serviceSubtaskAgain.setCreateTime(now); |
| | | serviceSubtaskAgain.setUpdateTime(now); |
| | | |
| | | // 二次随访时间:上次随访完成时间(未完成则当前时间)+ 下一任务发送天数;过去时间兜底为当前时间 |
| | | applyAgainVisitTime(serviceSubtaskAgain, serviceSubtask, nextServiceTask, config, now); |
| | | // 新任务的随访方式记录本次选择的再次随访方式;resource 本身不落库 |
| | | serviceSubtaskAgain.setVisitType(resource); |
| | | serviceSubtaskAgain.setVisitDeptCode(visitDeptCode); |
| | |
| | | if (dueTime.before(now)) { |
| | | dueTime = now; |
| | | } |
| | | if(ObjectUtils.isNotEmpty(origin.getVisitTime())){ |
| | | dueTime = ObjectUtils.isNotEmpty(origin.getVisitTime()) ? origin.getVisitTime() : now; |
| | | } |
| | | |
| | | target.setLongSendTime(dueTime); |
| | | Date visitTime = dueTime; |
| | | if ("3".equals(nextTask.getType())) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 再次随访附加统计:待随访、已发送、人工电话超时及回院复诊复查(suggest=6)。 |
| | | * 再次随访附加统计:待随访、已发送、人工电话超时及回院复诊复查(suggest=7)。 |
| | | */ |
| | | private void applyAgainFollowUpExtraStatistics(ServiceSubtaskStatistic statistic, ServiceSubtask serviceSubtask) { |
| | | if (serviceSubtask.getVisitCount() == null || serviceSubtask.getVisitCount() <= 1) { |
| | |
| | | return; |
| | | } |
| | | Long sendstate = serviceSubtask.getSendstate(); |
| | | // 回院复诊复查:再次随访中按处理意见 suggest=6 统计 |
| | | if (StringUtils.equals("6", StringUtils.trim(serviceSubtask.getSuggest()))) { |
| | | statistic.setSuggest6CountAgain(statistic.getSuggest6CountAgain() + 1L); |
| | | // 回院复诊复查:再次随访中按处理意见 suggest=7 统计 |
| | | if (StringUtils.equals("7", StringUtils.trim(serviceSubtask.getSuggest()))) { |
| | | statistic.setSuggest7CountAgain(statistic.getSuggest7CountAgain() + 1L); |
| | | } |
| | | if (sendstate.equals(3L)) { |
| | | statistic.setSentAgain(statistic.getSentAgain() + 1L); |
| | |
| | | * pendingFollowUpSentAgainInfo - visitCount > 1 && sendstate in (3,7) |
| | | * sentInfo - visitCount = 1 && sendstate = 3 |
| | | * sentAgainInfo - visitCount > 1 && sendstate = 3 |
| | | * suggest6CountAgainInfo - visitCount > 1 && suggest = 6 |
| | | * suggest7CountAgainInfo - visitCount > 1 && suggest = 7 |
| | | * filterCountList - taskSituation = 6 && sendstate = 4 |
| | | * |
| | | */ |
| | |
| | | serviceSubtaskCountReq.setVisitCount(2); |
| | | serviceSubtaskCountReq.setExcep("1"); |
| | | break; |
| | | case "suggest6CountAgainInfo": |
| | | // 再次随访回院复诊复查:visitCount > 1 且 suggest = 6 |
| | | case "suggest7CountAgainInfo": |
| | | // 再次随访回院复诊复查:visitCount > 1 且 suggest = 7 |
| | | serviceSubtaskCountReq.setVisitCount(2); |
| | | serviceSubtaskCountReq.setSuggest("6"); |
| | | serviceSubtaskCountReq.setSuggest("7"); |
| | | break; |
| | | case "taskSituation1Info": |
| | | serviceSubtaskCountReq.setTaskSituation(1); |
| | |
| | | total.setSentAgain(0L); |
| | | total.setFollowUpSuccessAgain(0L); |
| | | total.setFollowUpFailAgain(0L); |
| | | total.setSuggest6CountAgain(0L); |
| | | total.setSuggest7CountAgain(0L); |
| | | total.setManualAgain(0L); |
| | | total.setSmsAgain(0L); |
| | | total.setWeChatAgain(0L); |
| | |
| | | total.setSentAgain(total.getSentAgain() + (stat.getSentAgain() != null ? stat.getSentAgain() : 0L)); |
| | | total.setFollowUpSuccessAgain(total.getFollowUpSuccessAgain() + (stat.getFollowUpSuccessAgain() != null ? stat.getFollowUpSuccessAgain() : 0L)); |
| | | total.setFollowUpFailAgain(total.getFollowUpFailAgain() + (stat.getFollowUpFailAgain() != null ? stat.getFollowUpFailAgain() : 0L)); |
| | | total.setSuggest6CountAgain(total.getSuggest6CountAgain() + (stat.getSuggest6CountAgain() != null ? stat.getSuggest6CountAgain() : 0L)); |
| | | total.setSuggest7CountAgain(total.getSuggest7CountAgain() + (stat.getSuggest7CountAgain() != null ? stat.getSuggest7CountAgain() : 0L)); |
| | | total.setManualAgain(total.getManualAgain() + (stat.getManualAgain() != null ? stat.getManualAgain() : 0L)); |
| | | total.setSmsAgain(total.getSmsAgain() + (stat.getSmsAgain() != null ? stat.getSmsAgain() : 0L)); |
| | | total.setWeChatAgain(total.getWeChatAgain() + (stat.getWeChatAgain() != null ? stat.getWeChatAgain() : 0L)); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 微信公众号已领取未填写:按题目默认选项补齐当前子任务,并将当前子任务完成。 |
| | | * <p> |
| | | * 所有查询、明细写入、状态更新都只使用当前 subid,避免影响其他任务/子任务。 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean completeWechatClaimedByDefault(ServiceSubtask serviceSubtask) { |
| | | if (serviceSubtask == null || serviceSubtask.getId() == null) { |
| | | return false; |
| | | } |
| | | |
| | | // 重新读取当前子任务,所有判断只针对这一个 subid |
| | | ServiceSubtask current = serviceSubtaskMapper.selectServiceSubtaskById(serviceSubtask.getId()); |
| | | if (current == null) { |
| | | return false; |
| | | } |
| | | // 只处理:丽水中医院、问卷、当前方式公众号、已领取、未提交 |
| | | // 其他医院 orgid 不匹配时直接返回 false,继续走原补偿逻辑。 |
| | | if (!IServiceSubtaskService.WECHAT_DEFAULT_COMPLETE_ORGID.equals(current.getOrgid()) |
| | | || !"2".equals(current.getType()) |
| | | || !"5".equals(current.getCurrentPreachform()) |
| | | || !Long.valueOf(1L).equals(current.getSendstate()) |
| | | || Long.valueOf(1L).equals(current.getSubmit())) { |
| | | return false; |
| | | } |
| | | |
| | | // 查询当前子任务自己的公众号发送方式,必须是已发送(2)或已领取(3) |
| | | ServiceSubtaskPreachform query = new ServiceSubtaskPreachform(); |
| | | query.setSubid(current.getId()); |
| | | query.setTaskid(current.getTaskid()); |
| | | query.setPreachform("5"); |
| | | List<ServiceSubtaskPreachform> preachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(query); |
| | | if (CollectionUtils.isEmpty(preachforms)) { |
| | | return false; |
| | | } |
| | | ServiceSubtaskPreachform currentPreachform = preachforms.stream() |
| | | .filter(item -> "2".equals(item.getSendstate()) || "3".equals(item.getSendstate())) |
| | | .findFirst().orElse(null); |
| | | if (currentPreachform == null) { |
| | | return false; |
| | | } |
| | | |
| | | // 只给当前 subid 补齐默认选项;至少有一题默认选项才继续 |
| | | int filled = fillWechatDefaultDetailForCurrentSubtask(current); |
| | | if (filled <= 0) { |
| | | log.info("【微信公众号默认完成】subid:{} 没有可填充的默认选项,跳过", current.getId()); |
| | | return false; |
| | | } |
| | | |
| | | // 当前公众号发送方式:已发送/已领取 -> 完成(9) |
| | | ServiceSubtaskPreachform updatePreachform = new ServiceSubtaskPreachform(); |
| | | updatePreachform.setId(currentPreachform.getId()); |
| | | updatePreachform.setSubid(current.getId()); |
| | | updatePreachform.setPreachform("5"); |
| | | updatePreachform.setOrgid(current.getOrgid()); |
| | | updatePreachform.setRemark("已领取未填写,按默认选项完成"); |
| | | int preachformUpdated = serviceSubtaskPreachformMapper.updateWechatPreachformComplete(updatePreachform); |
| | | if (preachformUpdated == 0) { |
| | | throw new BaseException("微信公众号默认完成失败:发送方式状态已变化,subid=" + current.getId()); |
| | | } |
| | | |
| | | // 当前子任务:已领取(1) -> 完成(6),只更新这一个 subid |
| | | ServiceSubtask complete = new ServiceSubtask(); |
| | | complete.setId(current.getId()); |
| | | complete.setOrgid(current.getOrgid()); |
| | | complete.setFinishtime(new Date()); |
| | | complete.setResult("success"); |
| | | complete.setRemark("已领取未填写,按默认选项完成"); |
| | | int subtaskUpdated = serviceSubtaskMapper.updateWechatDefaultComplete(complete); |
| | | if (subtaskUpdated == 0) { |
| | | throw new BaseException("微信公众号默认完成失败:子任务状态已变化,subid=" + current.getId()); |
| | | } |
| | | |
| | | log.info("【微信公众号默认完成】subid:{},已按默认选项完成,填充题目数:{}", current.getId(), filled); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 仅给当前子任务补齐问卷单选/多选题中 default_value=2 的选项。 |
| | | * 已有非空答案的题目跳过,不覆盖患者已填写内容。 |
| | | * |
| | | * @return 实际填充(或此前已由系统默认填充)的题目数 |
| | | */ |
| | | private int fillWechatDefaultDetailForCurrentSubtask(ServiceSubtask serviceSubtask) { |
| | | Long templateId = serviceSubtask.getTemplateid(); |
| | | ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid()); |
| | | if (templateId == null && serviceTask != null) { |
| | | templateId = serviceTask.getTemplateid(); |
| | | } |
| | | if (templateId == null) { |
| | | return 0; |
| | | } |
| | | |
| | | SvyTaskTemplateScript scriptQuery = new SvyTaskTemplateScript(); |
| | | scriptQuery.setTemplateID(templateId); |
| | | List<SvyTaskTemplateScript> scripts = svyTaskTemplateScriptService.selectSvyTaskTemplateScriptList(scriptQuery); |
| | | if (CollectionUtils.isEmpty(scripts)) { |
| | | return 0; |
| | | } |
| | | |
| | | int filled = 0; |
| | | for (SvyTaskTemplateScript script : scripts) { |
| | | SvyTaskTemplateScriptVO scriptVO = DtoConversionUtils.sourceToTarget(script, SvyTaskTemplateScriptVO.class); |
| | | SvyTaskTemplateScriptVO scriptWithOptions = svyTaskTemplateScriptService.selectInfoByCondition(scriptVO); |
| | | if (scriptWithOptions == null |
| | | || scriptWithOptions.getId() == null |
| | | || CollectionUtils.isEmpty(scriptWithOptions.getSvyTaskTemplateTargetoptions()) |
| | | || (!"1".equals(scriptWithOptions.getScriptType()) && !"2".equals(scriptWithOptions.getScriptType()))) { |
| | | continue; |
| | | } |
| | | |
| | | List<SvyTaskTemplateTargetoption> options = scriptWithOptions.getSvyTaskTemplateTargetoptions(); |
| | | List<SvyTaskTemplateTargetoption> defaultOptions = options.stream() |
| | | .filter(option -> option.getDefaultValue() != null && option.getDefaultValue() == 2L) |
| | | .filter(option -> StringUtils.isNotBlank(option.getOptioncontent())) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(defaultOptions)) { |
| | | continue; |
| | | } |
| | | |
| | | // 已有非空答案则不覆盖,避免影响患者已填写内容 |
| | | ServiceSubtaskDetail detailQuery = new ServiceSubtaskDetail(); |
| | | detailQuery.setSubId(serviceSubtask.getId()); |
| | | detailQuery.setScriptid(scriptWithOptions.getId()); |
| | | List<ServiceSubtaskDetail> existingDetails = serviceSubtaskDetailMapper.selectServiceSubtaskDetailList(detailQuery); |
| | | ServiceSubtaskDetail existing = CollectionUtils.isNotEmpty(existingDetails) ? existingDetails.get(0) : null; |
| | | if (existing != null |
| | | && (StringUtils.isNotBlank(existing.getAsrtext()) || StringUtils.isNotBlank(existing.getMatchedtext()))) { |
| | | // 之前已由系统默认填充过的,计入已填充,保证重试幂等 |
| | | if ("DEFAULT".equals(existing.getOperate())) { |
| | | filled++; |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | String targetValue = options.stream() |
| | | .map(SvyTaskTemplateTargetoption::getOptioncontent) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.joining("&")); |
| | | String defaultValue = defaultOptions.stream() |
| | | .map(SvyTaskTemplateTargetoption::getOptioncontent) |
| | | .collect(Collectors.joining("&")); |
| | | |
| | | ServiceSubtaskDetail detail = new ServiceSubtaskDetail(); |
| | | detail.setSubId(serviceSubtask.getId()); |
| | | detail.setTaskid(serviceSubtask.getTaskid()); |
| | | detail.setPatid(serviceSubtask.getPatid()); |
| | | detail.setScriptid(scriptWithOptions.getId()); |
| | | detail.setTemplatequestionnum(scriptWithOptions.getId()); |
| | | detail.setQuestiontext(scriptWithOptions.getScriptContent()); |
| | | detail.setCategoryid(scriptWithOptions.getCategoryid()); |
| | | detail.setTargetid(scriptWithOptions.getTargetid() != null ? scriptWithOptions.getTargetid().intValue() : null); |
| | | detail.setValueType(scriptWithOptions.getScriptType()); |
| | | detail.setTargetvalue(targetValue); |
| | | detail.setAsrtext(defaultValue); |
| | | detail.setMatchedtext(defaultValue); |
| | | detail.setOperate("DEFAULT"); |
| | | detail.setTemplateType(2); |
| | | detail.setLibTemplateid(serviceSubtask.getLibtemplateid() != null ? serviceSubtask.getLibtemplateid().intValue() : null); |
| | | detail.setTemplateid(templateId.toString()); |
| | | detail.setGuid(scriptWithOptions.getGuid()); |
| | | detail.setOrgid(StringUtils.isNotEmpty(scriptWithOptions.getOrgid()) ? scriptWithOptions.getOrgid() |
| | | : (serviceTask != null ? serviceTask.getOrgid() : null)); |
| | | detail.setCreateTime(new Date()); |
| | | detail.setUpdateTime(new Date()); |
| | | |
| | | if (existing != null) { |
| | | detail.setId(existing.getId()); |
| | | serviceSubtaskDetailMapper.updateServiceSubtaskDetail(detail); |
| | | } else { |
| | | serviceSubtaskDetailMapper.insertServiceSubtaskDetail(detail); |
| | | } |
| | | filled++; |
| | | } |
| | | return filled; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> getHeLibraryCount(@RequestBody HeLibraryCountVO heLibraryCountVO) { |
| | | if (ObjectUtils.isEmpty(heLibraryCountVO)) { |