陈昶聿
20 小时以前 a2dd5b42824eff9626d1f48e1561be85f17f6107
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -3618,6 +3618,10 @@
                if (serviceSubtask.getSendstate() != null && serviceSubtask.getSendstate() != 4) {
                    serviceSubtaskStatistic.setFollowUpNeeded(serviceSubtaskStatistic.getFollowUpNeeded() + 1L);
                }
                //及时随访人次:已完成且未超时
                if (isTimelyFollowUp(serviceSubtask)) {
                    serviceSubtaskStatistic.setTimelyFollowUp(serviceSubtaskStatistic.getTimelyFollowUp() + 1L);
                }
                //人工已拨通总量
                if (ObjectUtils.isNotEmpty(serviceSubtask.getIsManuallyCalled())
@@ -3886,6 +3890,19 @@
    }
    /**
     * 是否属于「及时随访」:随访已完成且完成时状态为正常完成(未超时)。
     * <p>
     * finish_state:1-正常完成 2-延期完成 3-超时完成,只有 1 计入及时随访。
     *
     * @param serviceSubtask 随访子任务
     * @return true-计入及时随访人次
     */
    private boolean isTimelyFollowUp(ServiceSubtask serviceSubtask) {
        return serviceSubtask.getSendstate() != null && serviceSubtask.getSendstate().equals(6L)
                && serviceSubtask.getFinishState() != null && serviceSubtask.getFinishState().equals(1L);
    }
    /**
     * 首次随访统计
     *
     * @param serviceSubtaskList
@@ -3916,6 +3933,10 @@
            //应随访人次
            if (serviceSubtask.getSendstate() != null && serviceSubtask.getSendstate() != 4) {
                serviceSubtaskStatistic.setFollowUpNeeded(serviceSubtaskStatistic.getFollowUpNeeded() + 1L);
            }
            //及时随访人次:已完成且未超时
            if (isTimelyFollowUp(serviceSubtask)) {
                serviceSubtaskStatistic.setTimelyFollowUp(serviceSubtaskStatistic.getTimelyFollowUp() + 1L);
            }
            //首次出院随访
@@ -4085,6 +4106,10 @@
            //应随访人次
            if (serviceSubtask.getSendstate() != null && serviceSubtask.getSendstate() != 4) {
                serviceSubtaskStatistic.setFollowUpNeeded(serviceSubtaskStatistic.getFollowUpNeeded() + 1L);
            }
            //及时随访人次:已完成且未超时
            if (isTimelyFollowUp(serviceSubtask)) {
                serviceSubtaskStatistic.setTimelyFollowUp(serviceSubtaskStatistic.getTimelyFollowUp() + 1L);
            }
            //再次出院随访
@@ -4342,7 +4367,8 @@
        serviceSubtaskStatistic.setDrname(serviceSubtaskList.get(0).getDrname());
        serviceSubtaskStatistic.setJoyCount(0);
        serviceSubtaskStatistic.setJoyAllCount(0);
        //出院人次
        serviceSubtaskStatistic.setDischargeCount(serviceSubtaskList.size());
        //获取随访统计
        if (subCounts == null) {
            subCounts = new ArrayList<>();
@@ -4616,6 +4642,7 @@
     * pendingFollowUpInfo - visitCount = 1 && sendstate = 2
     * followUpSuccessInfo - visitCount = 1 && sendstate = 6
     * followUpFailInfo - visitCount = 1 && (sendstate = 5 || sendstate = 7)
     * timelyFollowUpInfo - sendstate = 6 && finish_state = 1(沿用请求的 visitCount 口径)
     * manualInfo - visitCount = 1 && currentPreachForm = "1"
     * voiceInfo - visitCount = 1 && currentPreachForm = "3"
     * smsInfo - visitCount = 1 && currentPreachForm = "4"
@@ -4674,14 +4701,22 @@
    }
    private void applyHyperLinkInfoType(ServiceSubtaskCountReq serviceSubtaskCountReq, String hyperLinkInfoType) {
        //及时随访明细需要沿用请求的首次/再次口径
        Integer originVisitCount = serviceSubtaskCountReq.getVisitCount();
        serviceSubtaskCountReq.setVisitCount(null);
        serviceSubtaskCountReq.setSendstates(null);
        serviceSubtaskCountReq.setCurrentPreachform(null);
        serviceSubtaskCountReq.setExcep(null);
        serviceSubtaskCountReq.setTaskSituation(null);
        serviceSubtaskCountReq.setFinishState(null);
        switch (hyperLinkInfoType) {
            case "dischargeCountInfo":
                break;
            case "timelyFollowUpInfo":
                serviceSubtaskCountReq.setVisitCount(originVisitCount);
                serviceSubtaskCountReq.setSendstates(new ArrayList<>(Collections.singletonList(6L)));
                serviceSubtaskCountReq.setFinishState(1L);
                break;
            case "followUpNeededAllInfo":
                serviceSubtaskCountReq.setSendstates(new ArrayList<>(Arrays.asList(1L, 2L, 3L, 5L, 6L, 7L)));
@@ -4839,7 +4874,7 @@
     * @return
     */
    @Override
    @Cacheable(value = "getSfStatisticsScript", key = "T(org.springframework.util.DigestUtils).md5DigestAsHex(#serviceSubtaskCountReq.toString().getBytes())", unless = "#result == null or #result.isEmpty()")
//    @Cacheable(value = "getSfStatisticsScript", key = "T(org.springframework.util.DigestUtils).md5DigestAsHex(#serviceSubtaskCountReq.toString().getBytes())", unless = "#result == null or #result.isEmpty()")
    public List<ServiceSubtaskStatistic> getSfStatisticsScript(ServiceSubtaskCountReq serviceSubtaskCountReq) {
        log.info("getSfStatisticsScript的入参为:{}", serviceSubtaskCountReq);
        List<ServiceSubtaskStatistic> serviceSubtaskStatistics = new ArrayList<>();
@@ -4847,13 +4882,13 @@
        // 根据条件进行分组
        Map<String, List<ServiceSubtask>> collect = new HashMap<>();
        String groupKey = "drcode";
        if (serviceSubtaskCountReq.getLeavehospitaldistrictcodes() != null && !serviceSubtaskCountReq.getLeavehospitaldistrictcodes().isEmpty()) {
        if (serviceSubtaskCountReq.getStatisticaltype() != null && serviceSubtaskCountReq.getStatisticaltype() == 1) {
            if (serviceSubtaskCountReq.getDrcode() != null && !serviceSubtaskCountReq.getDrcode().isEmpty()) {
                groupKey = "drcode";
            } else {
                groupKey = "leavehospitaldistrictcode";
            }
        } else if (serviceSubtaskCountReq.getDeptcodes() != null && !serviceSubtaskCountReq.getDeptcodes().isEmpty()) {
        } else if (serviceSubtaskCountReq.getStatisticaltype() != null && serviceSubtaskCountReq.getStatisticaltype() == 2) {
            if (serviceSubtaskCountReq.getDrcode() != null && !serviceSubtaskCountReq.getDrcode().isEmpty()) {
                groupKey = "drcode";
            } else {
@@ -4969,8 +5004,7 @@
    }
    @Override
    public Map<String, ServiceSubtaskScriptCount> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq) {
        Map<String, ServiceSubtaskScriptCount> result = new HashMap<>();
    public Map<String, Object> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq) {
        List<ServiceSubtaskScriptCount> allCounts = new ArrayList<>();
        List<ServiceSubtaskScriptCount> allItemCounts = new ArrayList<>();
        String type = serviceSubtaskCountReq.getType();
@@ -4994,7 +5028,23 @@
            allItemCounts = serviceSubtaskMapper.getSfStatisticsScriptItemDetails(serviceSubtaskCountReq);
        }
        for (ServiceSubtaskScriptCount count : allCounts) {
        //返回结构是 Map,且不传 type 时会执行两条 SQL,PageHelper 没法对整体分页,
        //所以在题目合并完成之后按题目(scriptid)在这里分页,保证 total 和每页数据都是题目维度的。
        allCounts.sort(Comparator
                .comparing(ServiceSubtaskScriptCount::getSubtaskType, Comparator.nullsLast(String::compareTo))
                .thenComparing(ServiceSubtaskScriptCount::getScriptid, Comparator.nullsLast(Long::compareTo)));
        int pageNum = ObjectUtils.isNotEmpty(serviceSubtaskCountReq.getPageNum()) && serviceSubtaskCountReq.getPageNum() > 0
                ? serviceSubtaskCountReq.getPageNum() : 1;
        int pageSize = ObjectUtils.isNotEmpty(serviceSubtaskCountReq.getPageSize()) && serviceSubtaskCountReq.getPageSize() > 0
                ? serviceSubtaskCountReq.getPageSize() : 10;
        int total = allCounts.size();
        int fromIndex = (int) Math.min((long) (pageNum - 1) * pageSize, total);
        int toIndex = Math.min(fromIndex + pageSize, total);
        List<ServiceSubtaskScriptCount> pageCounts = allCounts.subList(fromIndex, toIndex);
        Map<String, ServiceSubtaskScriptCount> pageData = new LinkedHashMap<>();
        for (ServiceSubtaskScriptCount count : pageCounts) {
            Map<String, ServiceSubtaskScriptCount> itemCountMap = new HashMap<>();
            //问卷加上空白选项
            if (ObjectUtils.isNotEmpty(count.getTemplateid()) && ObjectUtils.isNotEmpty(count.getSubtaskType()) && count.getSubtaskType().equals("2")) {
@@ -5025,31 +5075,42 @@
                }
            }
            allItemCounts.forEach(itemCount -> {
                if (ObjectUtils.isNotEmpty(count.getScriptid()) && ObjectUtils.isNotEmpty(itemCount.getScriptid())) {
                    if (count.getScriptid().equals(itemCount.getScriptid())) {
                        //放入统计信息
                        itemCount.setScriptContent(count.getScriptContent());
                        itemCount.setScriptType(count.getScriptType());
                        itemCount.setSubtaskType(count.getSubtaskType());
                        itemCount.setCompletedQuantity(count.getCompletedQuantity());
                        itemCount.setAllQuantity(count.getAllQuantity());
                        itemCount.setCompletedPercentage(count.getCompletedPercentage());
                        itemCount.setTemplateid(count.getTemplateid());
                        //计算选择比例
                        int chosenQuantity = ObjectUtils.isNotEmpty(itemCount.getChosenQuantity()) ? itemCount.getChosenQuantity() : 0;
                        int completedQuantity = itemCount.getCompletedQuantity();
                        if (ObjectUtils.isNotEmpty(completedQuantity) && completedQuantity != 0) {
                            BigDecimal chosenPercentage = (new BigDecimal(chosenQuantity)).divide(new BigDecimal(completedQuantity), 2, RoundingMode.HALF_UP);
                            itemCount.setChosenPercentage(chosenPercentage.toString());
                        }
                        itemCountMap.put(itemCount.getOptionText(), itemCount);
                //明细行已按“题目内容+任务类型”聚合并带出 script_content,不能用 scriptid 匹配:
                //同一道题会被复制到多个任务模板,每个模板的 scriptid 都不同
                boolean sameQuestion = ObjectUtils.isNotEmpty(count.getScriptContent())
                        && ObjectUtils.isNotEmpty(itemCount.getScriptContent())
                        && count.getScriptContent().equals(itemCount.getScriptContent())
                        && Objects.equals(count.getSubtaskType(), itemCount.getSubtaskType());
                if (sameQuestion) {
                    //放入统计信息
                    itemCount.setScriptContent(count.getScriptContent());
                    itemCount.setScriptType(count.getScriptType());
                    itemCount.setSubtaskType(count.getSubtaskType());
                    itemCount.setCompletedQuantity(count.getCompletedQuantity());
                    itemCount.setAllQuantity(count.getAllQuantity());
                    itemCount.setCompletedPercentage(count.getCompletedPercentage());
                    itemCount.setTemplateid(count.getTemplateid());
                    //计算选择比例
                    int chosenQuantity = ObjectUtils.isNotEmpty(itemCount.getChosenQuantity()) ? itemCount.getChosenQuantity() : 0;
                    int completedQuantity = itemCount.getCompletedQuantity();
                    if (ObjectUtils.isNotEmpty(completedQuantity) && completedQuantity != 0) {
                        BigDecimal chosenPercentage = (new BigDecimal(chosenQuantity)).divide(new BigDecimal(completedQuantity), 2, RoundingMode.HALF_UP);
                        itemCount.setChosenPercentage(chosenPercentage.toString());
                    }
                    itemCountMap.put(itemCount.getOptionText(), itemCount);
                }
            });
            List<ServiceSubtaskScriptCount> itemCounts = new ArrayList<>(itemCountMap.values());
            count.setDetails(itemCounts);
            result.put(count.getScriptid().toString(), count);
            pageData.put(count.getScriptid().toString(), count);
        }
        Map<String, Object> result = new HashMap<>();
        // total 是题目总数(已按题目合并),rows/data 是当前页数据
        result.put("total", total);
        result.put("pageNum", pageNum);
        result.put("pageSize", pageSize);
        result.put("rows", new ArrayList<>(pageCounts));
        result.put("data", pageData);
        return result;
    }
@@ -5151,6 +5212,7 @@
        total.setPendingFollowUp(0L);
        total.setFollowUpSuccess(0L);
        total.setFollowUpFail(0L);
        total.setTimelyFollowUp(0L);
        total.setManual(0L);
        total.setSms(0L);
        total.setWeChat(0L);
@@ -5182,6 +5244,7 @@
            total.setPendingFollowUp(total.getPendingFollowUp() + (stat.getPendingFollowUp() != null ? stat.getPendingFollowUp() : 0L));
            total.setFollowUpSuccess(total.getFollowUpSuccess() + (stat.getFollowUpSuccess() != null ? stat.getFollowUpSuccess() : 0L));
            total.setFollowUpFail(total.getFollowUpFail() + (stat.getFollowUpFail() != null ? stat.getFollowUpFail() : 0L));
            total.setTimelyFollowUp(total.getTimelyFollowUp() + (stat.getTimelyFollowUp() != null ? stat.getTimelyFollowUp() : 0L));
            total.setManual(total.getManual() + (stat.getManual() != null ? stat.getManual() : 0L));
            total.setSms(total.getSms() + (stat.getSms() != null ? stat.getSms() : 0L));
            total.setWeChat(total.getWeChat() + (stat.getWeChat() != null ? stat.getWeChat() : 0L));