陈昶聿
3 天以前 3f8535e2eeab1463324438f28d2ef72d8f1049c9
Merge branch 'master' into master-手术随访
已重命名1个文件
已修改16个文件
已添加1个文件
727 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-ls.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-sltd.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-xh.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtaskExport.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskCotinueCountVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml 219 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -1,11 +1,8 @@
package com.ruoyi.web.controller.smartor;
import com.github.pagehelper.ISelect;
import com.github.pagehelper.Page;
import com.ruoyi.common.annotation.AddOrgId;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -17,44 +14,35 @@
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.PreachFormEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserDeptService;
import com.smartor.domain.*;
import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
import com.smartor.domain.VO.ServiceSubtaskVO;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.mapper.PatMedInhospMapper;
import com.smartor.mapper.PatMedOuthospMapper;
import com.smartor.service.IServiceSubtaskRecordService;
import com.smartor.service.IServiceSubtaskService;
import com.smartor.service.IServiceTaskService;
import com.smartor.service.impl.ServiceSubtaskServiceImpl;
import com.sun.org.apache.bcel.internal.generic.NEW;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -69,6 +57,11 @@
@RestController
@RequestMapping("/smartor/serviceSubtask")
public class ServiceSubtaskController extends BaseController {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setAutoGrowCollectionLimit(1024); // æˆ– 2048、4096 ç­‰
    }
    @Autowired
    private IServiceSubtaskService serviceSubtaskService;
@@ -126,15 +119,18 @@
        // ç›´æŽ¥ä»Žå·²æœ‰èšåˆç»“果推算total,避免去掉分页后再全量查一遍大表
        long total = 0L;
        try {
            long wzx = map.get("wzx") != null ? ((Number) map.get("wzx")).longValue() : 0L;
            long ysf = map.get("ysf") != null ? ((Number) map.get("ysf")).longValue() : 0L;
            long dsf = map.get("dsf") != null ? ((Number) map.get("dsf")).longValue() : 0L;
            long yc = map.get("yc") != null ? ((Number) map.get("yc")).longValue() : 0L;
            long jg = map.get("jg") != null ? ((Number) map.get("jg")).longValue() : 0L;
            long fssb = map.get("fssb") != null ? ((Number) map.get("fssb")).longValue() : 0L;
            long yfs = map.get("yfs") != null ? ((Number) map.get("yfs")).longValue() : 0L;
            long blq = map.get("blq") != null ? ((Number) map.get("blq")).longValue() : 0L;
            total = wzx + ysf + dsf + yc + jg + fssb + yfs + blq;
//                 * wzx: æœªæ‰§è¡Œæ•°é‡
//                    * ysf: å·²éšè®¿æ•°é‡
//                    * fssb: å‘送失败数量
//                    * yfs: å·²å‘送数量
//                    * dsf: å¾…随访数量
//            long wzx = map.get("wzx") != null ? ((Number) map.get("wzx")).longValue() : 0L;
//            long ysf = map.get("ysf") != null ? ((Number) map.get("ysf")).longValue() : 0L;
//            long dsf = map.get("dsf") != null ? ((Number) map.get("dsf")).longValue() : 0L;
//            long fssb = map.get("fssb") != null ? ((Number) map.get("fssb")).longValue() : 0L;
            total = map.get("total") != null ? ((Number) map.get("total")).longValue() : 0L;
        } catch (Exception e) {
            // å…œåº•:全量count
            serviceSubtaskEntity.setPageNum(null);
@@ -221,24 +217,31 @@
    //@PreAuthorize("@ss.hasPermi('system:taskcall:export')")
    @Log(title = "单一任务(随访宣教)", businessType = BusinessType.EXPORT)
    @PostMapping("/patItemExport")
    public void patItemExport(HttpServletResponse response, @RequestBody ServiceSubtaskEntity serviceSubtaskVO) {
    public void patItemExport(HttpServletResponse response, ServiceSubtaskEntity serviceSubtaskVO) {
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        serviceSubtaskVO.setOrgid(user.getOrgid());
        List<ServiceSubtaskRes> serviceSubtaskList = null;
        if (serviceSubtaskVO != null) {
            if (serviceSubtaskVO.getPageNum() != null && serviceSubtaskVO.getPageSize() != null)
                PageUtils.startPageByPost(serviceSubtaskVO.getPageNum(), serviceSubtaskVO.getPageSize());
            serviceSubtaskList = serviceSubtaskService.patItem(serviceSubtaskVO);
        }
        List<ServiceSubtaskExprot> serviceSubtaskExprots = null;
        List<ServiceSubtaskExport> serviceSubtaskExports = null;
        if (!CollectionUtils.isEmpty(serviceSubtaskList)) {
            serviceSubtaskExprots = DtoConversionUtils.sourceToTarget(serviceSubtaskList, ServiceSubtaskExprot.class);
            for (ServiceSubtaskExprot serviceSubtaskExprot : serviceSubtaskExprots) {
                String pf = PreachFormEnum.getDescByCode(serviceSubtaskExprot.getPreachform());
                serviceSubtaskExprot.setPreachform(pf);
            serviceSubtaskExports = DtoConversionUtils.sourceToTarget(serviceSubtaskList, ServiceSubtaskExport.class);
            for (ServiceSubtaskExport serviceSubtaskExport : serviceSubtaskExports) {
                String pf = PreachFormEnum.getDescByCode(serviceSubtaskExport.getPreachform());
                serviceSubtaskExport.setPreachform(pf);
                //计算出院天数
                if (!Objects.isNull(serviceSubtaskExport.getEndtime())) {
                    Integer endDay = DateUtils.differentDaysByMillisecond(serviceSubtaskExport.getEndtime(), new Date());
                    serviceSubtaskExport.setEndDay(endDay);
                }
            }
        }
        ExcelUtil<ServiceSubtaskExprot> util = new ExcelUtil<ServiceSubtaskExprot>(ServiceSubtaskExprot.class);
        util.exportExcel(response, serviceSubtaskExprots, "患者随访信息表单");
        ExcelUtil<ServiceSubtaskExport> util = new ExcelUtil<ServiceSubtaskExport>(ServiceSubtaskExport.class);
        util.exportExcel(response, serviceSubtaskExports, "患者随访信息表单");
    }
@@ -556,9 +559,7 @@
    @PostMapping("/getSfStatisticsExport")
    public void export(HttpServletResponse response, ServiceSubtaskCountReq serviceSubtaskCountReq) {
        List<ServiceSubtaskStatistic> sfStatistics = serviceSubtaskService.getSfStatisticsExport(serviceSubtaskCountReq);
        ExcelUtil<ServiceSubtaskStatistic> util = new ExcelUtil<ServiceSubtaskStatistic>(ServiceSubtaskStatistic.class);
        String sheetName = "";
        String fileName = "";
        if (active.equals("ls") || active.equals("druid")) {
@@ -596,6 +597,30 @@
        }
        return success(serviceSubtaskService.getSfStatisticsJoydetails(serviceSubtaskCountReq));
    }
    /**
     * å»¶ç»­æŠ¤ç†ç»Ÿè®¡
     */
    @ApiOperation("延续护理统计")
    @AddOrgId(field = "orgid", paramIndex = 0, campusField = "campusid")
    @PostMapping("/getContinueNerseCount")
    public AjaxResult getContinueNerseCount(@RequestBody ServiceSubtaskCotinueCountVO serviceSubtaskCotinueCountVO) {
        SysUser user = getLoginUser().getUser();
        serviceSubtaskCotinueCountVO.setOrgid(user.getOrgid());
        serviceSubtaskCotinueCountVO.setCampusid(user.getCampusid());
        boolean hasDistrict = !CollectionUtils.isEmpty(serviceSubtaskCotinueCountVO.getLeavehospitaldistrictcodes());
        boolean hasDept = !CollectionUtils.isEmpty(serviceSubtaskCotinueCountVO.getDeptcodes());
        if (hasDistrict && hasDept) {
            return error("病区Code集合与科室Code集合互斥,不能同时传入");
        }
        return success(serviceSubtaskService.getContinueNurseCount(serviceSubtaskCotinueCountVO));
    }
    /**
     * èŽ·å–éšè®¿åˆ†ç±»ç»Ÿè®¡æ˜Žç»†
@@ -712,4 +737,6 @@
        }
        return map;
    }
}
ruoyi-admin/src/main/resources/application-ls.yml
@@ -11,7 +11,7 @@
        #        username: smartor
        #        password: Smartor.2023
        #        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://9.209.1.5:2883/smartor-lisui?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://9.209.1.5:2883/smartor-lisui?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=60000&socketTimeout=120000
        username: root@sfxx#other_cluster02
        password: Y5oapyS8
        driverClassName: com.mysql.cj.jdbc.Driver
ruoyi-admin/src/main/resources/application-sltd.yml
@@ -7,7 +7,7 @@
      # ä¸»åº“数据源
      master:
        #        çœç«‹åŒå¾·
        url: jdbc:mysql://192.88.117.237:3306/smartor_sltd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://192.88.117.237:3306/smartor_sltd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=60000&socketTimeout=120000
        username: root
        password: Smartor.2023
        driverClassName: com.mysql.cj.jdbc.Driver
ruoyi-admin/src/main/resources/application-xh.yml
@@ -7,7 +7,7 @@
      # ä¸»åº“数据源
      master:
        #   æ–°åŽ
        url: jdbc:mysql://192.168.191.181:3308/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://192.168.191.181:3308/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=60000&socketTimeout=120000
        username: smartor
        password: Smartor.2023
        driverClassName: com.mysql.cj.jdbc.Driver
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -319,7 +319,6 @@
                    serviceSLTDInhospReqVO.setEncounterTimeStart(nowTime);
                    serviceSLTDInhospReqVO.setEncounterTimeEnd(nowTime);
                    List<String> list = new ArrayList<>();
//                    list.add("FH0108.02");
                    list.add("FH0109.22");
                    list.add("FH0109.23");
                    list.add("FH0109.53");
@@ -577,20 +576,20 @@
                //2判断一下,当前的sort是不是等于需要执行的总个数,如果等于的话,说明是最后一个,直接将servuce_subtask的状态改成5,执行失败就行了
                Long cs = currentSort.get();
                if (cs.equals(serviceSubtaskPreachforms.size())) {
                    if(serviceSubtask.getPreachform().equals("1")){
                    if (serviceSubtask.getPreachform().equals("1")) {
                        serviceSubtask.setSendstate(7L);
                        serviceSubtask.setRemark("处理补偿任务,当前处理最后补偿 äººå·¥è¶…æ—¶");
                    }else {
                    } else {
                        serviceSubtask.setSendstate(5L);
                        serviceSubtask.setRemark("处理补偿任务,当前处理最后补偿,全部执行失败");
                    }
                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                    //修改发送方式的状态为失败
                    if(serviceSubtaskPreachform.getPreachform().equals("1")){
                    if (serviceSubtaskPreachform.getPreachform().equals("1")) {
                        serviceSubtaskPreachform.setSendstate("7");
                        serviceSubtaskPreachform.setId(id.get());
                    }else {
                    } else {
                        serviceSubtaskPreachform.setSendstate("5");
                        serviceSubtaskPreachform.setId(id.get());
                    }
@@ -1018,8 +1017,9 @@
                    //说明全发送失败了
                    serviceSubtask.setSendstate(5L);
                    log.error("getSendPreachform方法 æ£€æŸ¥æ˜¯å¦æ‰€æœ‰sendstate不等于9, å…¨å¤±è´¥äº†");
                    serviceSubtask.setRemark("所有发送方式均未获取结果,任务失败");
                    //人工发送超时
                    if(ObjectUtils.isNotEmpty(serviceSubtask.getCurrentPreachform()) && serviceSubtask.getCurrentPreachform().equals("1")){
                    if (ObjectUtils.isNotEmpty(serviceSubtask.getCurrentPreachform()) && serviceSubtask.getCurrentPreachform().equals("1")) {
                        serviceSubtask.setSendstate(7L);
                        serviceSubtask.setRemark("人工发送超时");
                    }
@@ -1105,7 +1105,7 @@
            subtaskPreachform.setSendstate("5");
            subtaskPreachform.setId(id.get());
            //人工发送超时
            if(ObjectUtils.isNotEmpty(serviceSubtask.getCurrentPreachform()) && serviceSubtask.getCurrentPreachform().equals("1")){
            if (ObjectUtils.isNotEmpty(serviceSubtask.getCurrentPreachform()) && serviceSubtask.getCurrentPreachform().equals("1")) {
                subtaskPreachform.setSendstate("7");
                subtaskPreachform.setRemark("人工发送超时");
            }
@@ -1233,7 +1233,7 @@
                if (failSendstate.equals("2")) serviceSubtaskPreachform1.setSendstate("9");
            }
            serviceSubtaskPreachform1.setRemark(remark);
            if(ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")){
            if (ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")) {
                serviceSubtaskPreachform1.setSendstate("7");
                serviceSubtaskPreachform1.setRemark("人工发送超时");
            }
@@ -1241,16 +1241,18 @@
            //如果当前的preachform已经是最后一个了,那直接将serviceSubtask的sendstate状态改成5就行了(全失败了)
            if (serviceSubtaskPreachform1.getSort() == sspCount.size()) {
                if(ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")){
                if (ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")) {
                    serviceSubtask.setCurrentPreachform(preachform);
                    serviceSubtask.setSendstate(7L);
                    serviceSubtask.setRemark("人工发送超时");
                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                    return true;
                }else {
                } else {
                    if (failSendstate.equals("4") || failSendstate.equals("5")) {
                        serviceSubtask.setCurrentPreachform(preachform);
                        serviceSubtask.setSendstate(5L);
                        log.error("setSuccessPreachForm方法,当前的preachform已经是最后一个了,全部执行失败");
                        serviceSubtask.setRemark("所有发送方式均未获取结果,任务失败");
                        //serviceSubtask.setRemark("setSuccessPreachForm方法,当前的preachform已经是最后一个了,全部执行失败");
                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                        return true;
@@ -1265,10 +1267,10 @@
        //将下一次的随访时间与当前执行方式记录一下
        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime()));
        serviceSubtask.setCurrentPreachform(preachform);
        if(ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")){
        if (ObjectUtils.isNotEmpty(preachform) && preachform.equals("1")) {
            serviceSubtask.setSendstate(7L);
            serviceSubtask.setRemark("人工发送超时");
        }else {
        } else {
            serviceSubtask.setSendstate(3L);
        }
        if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -330,7 +330,7 @@
                    questionnaireCategorys.add(map);
                }
            }
            satisfactionCategories.put("questionnaireCategorys", CollectionUtils.isEmpty(questionnaireCategorys) ? null : questionnaireCategorys);
            satisfactionCategories.put("questionnaireCategorys", questionnaireCategorys);
            //设置当前用户的声音问题分类和问卷问题分类
            sysUser.setSatisfactionCategories(satisfactionCategories);
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java
@@ -653,7 +653,7 @@
    @ApiModelProperty(value = "异常预警:0绿色;1红色;2黄色; 3已处理")
    private Integer isabnormal;
    @ApiModelProperty(value = "继续标识")
    @ApiModelProperty(value = "继续标识:1否 2是")
    private Integer continueFlag;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
smartor/src/main/java/com/smartor/domain/ServiceSubtaskExport.java
ÎļþÃû´Ó smartor/src/main/java/com/smartor/domain/ServiceSubtaskExprot.java ÐÞ¸Ä
@@ -8,8 +8,6 @@
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * å•一任务(随访)对象 ivr_taskcall
@@ -17,9 +15,9 @@
 * @author ruoyi
 * @date 2024-02-02
 */
@ApiModel(value = "ServiceSubtaskExprot", description = "单一随访任务入参")
@ApiModel(value = "ServiceSubtaskExport", description = "单一随访任务入参")
@Data
public class ServiceSubtaskExprot extends BaseEntity {
public class ServiceSubtaskExport extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /**
@@ -32,21 +30,21 @@
    /**
     * å‘送人
     */
    @Excel(name = " å‘送人 ")
    @Excel(name = " å§“名 ")
    @ApiModelProperty(value = "发送人")
    private String sendname;
    /**
     * åˆ›å»ºè€…
     * å‘送状态
     */
    @Excel(name = "随访人")
    private String updateBy;
    @Excel(name = " ä»»åŠ¡çŠ¶æ€ ")
    @ApiModelProperty(value = "发送状态 1 è¢«é¢†å–(在任务中是新建,在服务中是被领取)  2 å¾…发送  3 å·²å‘送  4 ä¸æ‰§è¡Œ  5 å‘送失败 6 å·²å®Œæˆ 7 è¶…æ—¶(人工)")
    private Long sendstate;
    /**
     * å®Œæˆæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = " å®Œæˆæ—¶é—´ ", width = 30, dateFormat = "yyyy-MM-dd")
    @ApiModelProperty(value = "完成时间")
    private Date finishtime;
@@ -54,9 +52,16 @@
     * å‡ºé™¢æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = " å‡ºé™¢æ—¶é—´ ", width = 30, dateFormat = "yyyy-MM-dd")
    @Excel(name = " å‡ºé™¢æ—¥æœŸ ", width = 30, dateFormat = "yyyy-MM-dd")
    @ApiModelProperty(value = "出院时间")
    private Date endtime;
    /**
     * åº”随访日期
     */
    @Excel(name = "应随访日期",dateFormat = "yyyy-MM-dd")
    @ApiModelProperty(value = "应随访日期")
    private Date visitTime;
    /**
@@ -66,6 +71,15 @@
    @ApiModelProperty(value = "医生姓名")
    private String drname;
    /**
     * éšè®¿äººå‘˜
     */
    @Excel(name = "随访人员")
    private String updateBy;
    @Excel(name = "出院天数", suffix = "天")
    @ApiModelProperty(value = "出院天数")
    private Integer endDay;
    /**
     * èº«ä»½è¯å·
@@ -117,8 +131,8 @@
    /**
     * å®£æ•™å½¢å¼ :文本、图片、语音、视频、混合
     */
    @Excel(name = "任务执行方式")
    @ApiModelProperty(value = "任务形式(1,人工 2,纸质  3,电话  4,短信  5.微信公众号 6.微信小程序 7.支付宝小程序  8.智能机器人  9.钉钉   10.导入)")
    @Excel(name = "任务执行方式")
    private String preachform;
smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskCotinueCountVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.smartor.domain.VO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * å»¶ç»­æŠ¤ç†ç»Ÿè®¡è¯·æ±‚
 *
 * @author ls
 * @date 2026-04-11
 */
@ApiModel(value = "ServiceSubtaskCotinueCountVO", description = "延续护理统计请求")
@Data
public class ServiceSubtaskCotinueCountVO {
    @ApiModelProperty(value = "病区Code集合")
    private List<String> leavehospitaldistrictcodes;
    @ApiModelProperty(value = "科室Code集合")
    private List<String> deptcodes;
    @ApiModelProperty("机构编码")
    private String orgid;
    @ApiModelProperty("院区编码")
    private String campusid;
}
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
@@ -2,6 +2,7 @@
import com.smartor.domain.*;
import com.smartor.domain.VO.PatSatisfactionReqVO;
import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.domain.entity.ServiceSubtaskSatisfactionEntity;
import org.apache.ibatis.annotations.MapKey;
@@ -194,4 +195,20 @@
    List<Long> querySendCount(ServiceSubtaskSatisfactionEntity serviceSubtaskSatisfactionEntity);
    /**
     * æŒ‰ç—…区分组统计延续护理数量
     *
     * @param vo æŸ¥è¯¢æ¡ä»¶
     * @return æ¯ä¸ªç—…区的统计结果
     */
    List<Map<String, Object>> getContinueNurseCount(ServiceSubtaskCotinueCountVO vo);
    /**
     * æŒ‰ç§‘室分组统计延续护理数量
     *
     * @param vo æŸ¥è¯¢æ¡ä»¶
     * @return æ¯ä¸ªç§‘室的统计结果
     */
    List<Map<String, Object>> getContinueNurseCountByDept(ServiceSubtaskCotinueCountVO vo);
}
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
@@ -3,6 +3,7 @@
import com.ruoyi.common.core.domain.AjaxResult;
import com.smartor.domain.*;
import com.smartor.domain.ServiceSubtask;
import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import org.springframework.web.bind.annotation.RequestBody;
@@ -149,4 +150,13 @@
    public List<ServiceSubtaskDiagname> convertToDiagnameList(List<ServiceSubtask> subtaskList) ;
    public Map<String, Object> getCurrentUserServiceSubtaskCount(ServiceSubtaskEntity entity);
    /**
     * æŒ‰ç—…区或科室统计延续护理数量
     * éƒ½ä¸ä¼ æ—¶åŒæ—¶æŒ‰ç—…区和科室各统计一遍
     *
     * @param vo æŸ¥è¯¢æ¡ä»¶ï¼ˆleavehospitaldistrictcodes ä¸Ž deptcodes äº’斥)
     * @return noContinueCount、ContinueCount åŠ detail åˆ—表
     */
    Map<String, Object> getContinueNurseCount(ServiceSubtaskCotinueCountVO vo);
    }
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -146,16 +146,6 @@
    public PatMedRes selectPatMedInhospListCount(PatMedReq patMedReq) {
        PatMedRes patMedRes = null;
        // èŽ·å–å½“å‰ç™»é™†äººçš„éƒ¨é—¨æƒé™
        if (org.springframework.util.CollectionUtils.isEmpty(patMedReq.getDeptcodeList())) {
//            Long userId = SecurityUtils.getUserId();
//            List<SysDept> sysDepts = sysUserDeptMapper.selectDeptListByUserId(userId);
//            List<String> deptCode = new ArrayList<>();
//            for (SysDept sysDept : sysDepts) {
//                deptCode.add(sysDept.getDeptId().toString());
//            }
//            patMedReq.setDeptcodeList(deptCode);
//            patMedRes = patMedInhospMapper.selectPatMedInhospCount(patMedReq);
        }
        patMedRes = patMedInhospMapper.selectPatMedInhospCount(patMedReq);
        return patMedRes;
    }
@@ -441,6 +431,7 @@
    /**
     * å¤šç»´åº¦éšè®¿
     *
     * @param config
     * @return
     */
@@ -479,14 +470,12 @@
     * æŒ‰ç»´åº¦æ‰¾åˆ°æ‰€æœ‰åŒ¹é…é•¿æœŸä»»åŠ¡ï¼Œæ‰¹é‡ç”Ÿæˆ subtask
     * type: 1=科室, 2=病区, 3=疾病
     */
    private void processTasksByDimension(PatMedInhosp patMedInhosp1,
            PatArchive patArchive,
            String config, int type) {
    private void processTasksByDimension(PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, int type) {
        List<Long> matchedTaskIds = findMatchingTaskIds(patMedInhosp1, type);
        if (CollectionUtils.isEmpty(matchedTaskIds)) {
                String reason = getDimensionReason(type);
                markFlagAsNoConfig(patMedInhosp1, type, reason);
            String reason = getDimensionReason(type);
            markFlagAsNoConfig(patMedInhosp1, type, reason);
            return;
        }
@@ -496,11 +485,11 @@
        }
    }
    private String getDimensionReason(int type){
    private String getDimensionReason(int type) {
        switch (type) {
            case 1: { // ç§‘室
                return "未找到科室匹配的长期任务";
                 }
            }
            case 2: { // ç—…区
                return "未找到病区匹配的长期任务";
            }
@@ -511,9 +500,7 @@
        return "多维长期任务-匹配类型为空";
    }
    private void markFlagAsNoConfig(PatMedInhosp patMedInhosp,
                                    int type,
                                    String reason){
    private void markFlagAsNoConfig(PatMedInhosp patMedInhosp, int type, String reason) {
        switch (type) {
            case 1: { // ç§‘室
                patMedInhosp.setDeptcheckFlag("2");
@@ -537,14 +524,14 @@
    }
    private void markAllFlagsAsError(PatMedInhosp patMedInhosp,
                                    String reason){
    private void markAllFlagsAsError(PatMedInhosp patMedInhosp, String reason) {
        patMedInhosp.setDeptcheckFlag("2");
        patMedInhosp.setWardcheckFlag("2");
        patMedInhosp.setDiagcheckFlag("2");
        patMedInhosp.setRemark(reason);
        patMedInhospMapper.updatePatMedInhosp(patMedInhosp);
    }
    /**
     * æ ¹æ®ç»´åº¦ç±»åž‹æŸ¥è¯¢åŒ¹é…çš„长期任务 ID åˆ—表
     */
@@ -556,8 +543,7 @@
                query.setDeptCode(patMedInhosp1.getLeaveldeptcode());
                query.setDeptType("1");
                query.setOrgid(patMedInhosp1.getOrgid());
                return serviceTaskdeptMapper.selectServiceTaskdeptList(query)
                        .stream().map(ServiceTaskdept::getTaskId).collect(Collectors.toList());
                return serviceTaskdeptMapper.selectServiceTaskdeptList(query).stream().map(ServiceTaskdept::getTaskId).collect(Collectors.toList());
            }
            case 2: { // ç—…区
                ServiceTaskdept query = new ServiceTaskdept();
@@ -565,8 +551,7 @@
                query.setDeptCode(patMedInhosp1.getLeavehospitaldistrictcode());
                query.setDeptType("2");
                query.setOrgid(patMedInhosp1.getOrgid());
                return serviceTaskdeptMapper.selectServiceTaskdeptList(query)
                        .stream().map(ServiceTaskdept::getTaskId).collect(Collectors.toList());
                return serviceTaskdeptMapper.selectServiceTaskdeptList(query).stream().map(ServiceTaskdept::getTaskId).collect(Collectors.toList());
            }
            case 3: { // ç–¾ç—…
                if (StringUtils.isEmpty(patMedInhosp1.getLeaveicd10code())) return Collections.emptyList();
@@ -574,8 +559,7 @@
                query.setLongtask(1L);
                query.setIcd10code(patMedInhosp1.getLeaveicd10code());
                query.setOrgid(patMedInhosp1.getOrgid());
                return serviceTaskdiagMapper.selectServiceTaskdiagList(query)
                        .stream().map(ServiceTaskdiag::getTaskId).collect(Collectors.toList());
                return serviceTaskdiagMapper.selectServiceTaskdiagList(query).stream().map(ServiceTaskdiag::getTaskId).collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
@@ -741,13 +725,12 @@
    }
    /**
     *
     * @param taskid ä»»åŠ¡id
     * @param check æ˜¯å¦éœ€è¦æ ¡éªŒ
     * @param taskid        ä»»åŠ¡id
     * @param check         æ˜¯å¦éœ€è¦æ ¡éªŒ
     * @param patMedInhosp1 ç—…人出入院信息
     * @param patArchive ç—…人信息
     * @param type éšè®¿ç±»åž‹(1-科室,2-病区,3-疾病)
     * @param config é…ç½®ä¿¡æ¯ visit.early.day
     * @param patArchive    ç—…人信息
     * @param type          éšè®¿ç±»åž‹(1-科室,2-病区,3-疾病)
     * @param config        é…ç½®ä¿¡æ¯ visit.early.day
     */
    //将患者放到subtask中
    private void writeInSubTask(Long taskid, Boolean check, PatMedInhosp patMedInhosp1, PatArchive patArchive, Integer type, String config) {
@@ -1304,8 +1287,7 @@
                        }
                        //景宁 å‡ºé™¢é¦–次(7天)随访一定要做
                        boolean firstVisit = false;
                        if (serviceSubtask1.getOrgid().equals("47255004333112711A1001")
                                && serviceSubtask1.getVisitCount() != null && serviceSubtask1.getVisitCount() == 1) {
                        if (serviceSubtask1.getOrgid().equals("47255004333112711A1001") && serviceSubtask1.getVisitCount() != null && serviceSubtask1.getVisitCount() == 1) {
                            firstVisit = true;
                        }
                        if (!firstVisit) {
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
@@ -181,7 +181,7 @@
        if (org.apache.commons.lang3.StringUtils.isNotBlank(patMedOuthosp.getSerialnum())) {
            int exists = patMedOuthospMapper.countBySerialnum(targetTable, patMedOuthosp.getSerialnum());
            if (exists > 0) {
                log.debug("[insert] serialnum={} å·²å­˜åœ¨äºŽè¡¨ {},跳过插入", patMedOuthosp.getSerialnum(), targetTable);
                log.info("[insert] serialnum={} å·²å­˜åœ¨äºŽè¡¨ {},跳过插入", patMedOuthosp.getSerialnum(), targetTable);
                return 0;
            }
        }
smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
@@ -457,11 +457,21 @@
    }
    private void processResultList(List<ServiceSLTDInhospResDTO> resultList, List<String> types, String cry, String campusId) {
        for (String type : types)
        // é—¨è¯Š(FH0108.01)和急诊(FH0108.03)在业务上是同一类数据,共用同一个 resultList。
        // è‹¥ types åŒæ—¶åŒ…含两者,outHospitalDate ä¼šè¢«è°ƒç”¨ä¸¤æ¬¡å¯¼è‡´é‡å¤å…¥åº“。
        // å› æ­¤åªè¦ types ä¸­å«æœ‰ä»»æ„ä¸€ä¸ªé—¨æ€¥è¯Šç±»åž‹ï¼Œå°±åªå¤„理一次。
        boolean outpProcessed = false;
        for (String type : types) {
            switch (type) {
                case "FH0108.01":
                    log.info("【parseResponseData】解析门诊数据");
                    outHospitalDate(resultList);
                case "FH0108.03":
                    if (!outpProcessed) {
                        log.info("【parseResponseData】解析门急诊数据,types={}", types);
                        outHospitalDate(resultList);
                        outpProcessed = true;
                    } else {
                        log.info("【parseResponseData】门急诊数据已处理,跳过 type={}", type);
                    }
                    break;
                case "FH0109.26":
                    log.info("【parseResponseData】解析住院数据");
@@ -483,14 +493,11 @@
                    log.info("【parseResponseData】解析预住院(其他)数据");
                    inHospitalDate(resultList, cry);
                    break;
//                case "FH0108.03":
//                    log.info("【parseResponseData】解析急诊数据");
//                    outHospitalDate(resultList);
//                    break;
                default:
                    log.warn("【parseResponseData】未知的数据类型:{}", type);
                    break;
            }
        }
    }
    private Boolean outHospitalDate(List<ServiceSLTDInhospResDTO> resultList) {
@@ -607,37 +614,38 @@
            }
        } else if (cry.equals("1")) {
//           å‡ºé™¢æ•°æ®å¤„理
            if (CollectionUtils.isEmpty(existingInhosps)) {
                //如果为空,要先判断,预入院是否有值,有值的话则更新
            // å‡ºé™¢æ•°æ®å¤„理
            if (CollectionUtils.isNotEmpty(existingInhosps)) {
                // å·²å­˜åœ¨å‡ºé™¢è®°å½•,直接更新(保持最新数据)
                patMedInhosp.setInhospid(existingInhosps.get(0).getInhospid());
                patMedInhospService.updatePatMedInhosp(patMedInhosp);
                log.info("出院记录已存在,执行更新:serialnum={}, orgid={}", patMedInhosp.getSerialnum(), patMedInhosp.getOrgid());
            } else {
                // ä¸å­˜åœ¨å‡ºé™¢è®°å½•,先查预入院(state=3),再查入院(state=0)
                queryInhosp.setInhospstate("3");
                log.info("-----patMedInhospList进来了不?入参为:{}", queryInhosp);
                log.info("-----查询预入院记录,入参为:{}", queryInhosp);
                List<PatMedInhosp> patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp);
                log.info("----patMedInhospList进来了不?返参为:{}", CollectionUtils.isEmpty(patMedInhospList) ? null : patMedInhospList.get(0).getSerialnum());
                log.info("----预入院查询结果:{}", CollectionUtils.isEmpty(patMedInhospList) ? "空" : patMedInhospList.get(0).getSerialnum());
                if (CollectionUtils.isNotEmpty(patMedInhospList)) {
                    //如果预入院不为空,则进行修改
                    // å­˜åœ¨é¢„入院记录,更新为出院状态
                    patMedInhosp.setInhospid(patMedInhospList.get(0).getInhospid());
                    patMedInhospService.updatePatMedInhosp(patMedInhosp);
                    log.info("由预入院更新为出院:serialnum={}", patMedInhosp.getSerialnum());
                } else {
                    //如果入院不为空,则进行修改
                    // å†æŸ¥å…¥é™¢è®°å½•(state=0)
                    queryInhosp.setInhospstate("0");
                    patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp);
                    log.debug("入院查询结果:{}", CollectionUtils.isEmpty(patMedInhospList) ? "空" : patMedInhospList.size());
                    if (CollectionUtils.isNotEmpty(patMedInhospList)) {
                        // å­˜åœ¨å…¥é™¢è®°å½•,更新为出院状态
                        patMedInhosp.setInhospid(patMedInhospList.get(0).getInhospid());
                        patMedInhospService.updatePatMedInhosp(patMedInhosp);
                    }
                }
                //如果都为空,则进行新增
                if (CollectionUtils.isEmpty(patMedInhospList)) {
                    //如果入院不为空,则进行修改
                    queryInhosp.setInhospstate("0");
                    log.debug("出院queryInhosp入参为:{}", queryInhosp);
                    List<PatMedInhosp> patMedInhosps = patMedInhospService.selectPatMedInhosp(queryInhosp);
                    log.debug("出院patMedInhospList返参为:{}", CollectionUtils.isEmpty(patMedInhosps) ? null : patMedInhosps.size());
                    if (CollectionUtils.isNotEmpty(patMedInhosps)) {
                        patMedInhospService.updatePatMedInhosp(patMedInhosp);
                        log.info("由入院更新为出院:serialnum={}", patMedInhosp.getSerialnum());
                    } else {
                        // é¢„入院和入院均不存在,直接新增出院记录
                        try {
                            patMedInhospService.insertPatMedInhosp(patMedInhosp);
                            log.info("新增出院记录:serialnum={}", patMedInhosp.getSerialnum());
                        } catch (org.springframework.dao.DuplicateKeyException e) {
                            log.warn("出院记录已存在,跳过:serialnum={}, orgid={}, state={}", patMedInhosp.getSerialnum(), patMedInhosp.getOrgid(), patMedInhosp.getInhospstate());
                        }
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
@@ -431,6 +431,7 @@
            List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.selectServiceSubtaskList(ssVO);
            ServiceSubtask serviceSubtask = new ServiceSubtask();
            serviceSubtask.setId(subid);
            serviceSubtask.setTaskid(tid);
            serviceSubtask.setPatid(pid);
            serviceSubtask.setSubmit(1L);
@@ -847,7 +848,9 @@
        serviceSubtaskDetailVO.setCreateTime(new Date());
        serviceSubtaskDetailVO.setUpdateTime(new Date());
        serviceSubtaskDetailVO.setTemplateType(2);
        serviceSubtaskDetailVO.setLibTemplateid(CollectionUtils.isNotEmpty(selectServiceSubtaskList) ? selectServiceSubtaskList.get(0).getLibtemplateid().intValue() : null);
        serviceSubtaskDetailVO.setLibTemplateid(CollectionUtils.isNotEmpty(selectServiceSubtaskList) ?
                (ObjectUtils.isNotEmpty(selectServiceSubtaskList.get(0).getLibtemplateid()) ?
                        selectServiceSubtaskList.get(0).getLibtemplateid().intValue() : null): null);
        if (ObjectUtils.isNotEmpty(serviceTask)) {
            serviceSubtaskDetailVO.setGuid(serviceTask.getGuid());
            serviceSubtaskDetailVO.setOrgid(serviceTask.getOrgid());
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -13,6 +13,7 @@
import com.smartor.common.FtpService;
import com.smartor.config.PhoneUtils;
import com.smartor.domain.*;
import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.mapper.*;
import com.smartor.service.*;
@@ -411,18 +412,18 @@
        // å¤„理空异常
        if (MapUtils.isEmpty(result)) {
            result = new HashMap<>();
            // ç¡®ä¿æ‰€æœ‰ key éƒ½æœ‰å€¼ï¼Œé¿å…ç©ºæŒ‡é’ˆå¼‚常
            // MyBatis çš„ SUM åœ¨æ²¡æœ‰åŒ¹é…è¡Œæ—¶ä¼šè¿”回 null
            result.putIfAbsent("wzx", 0);
            result.putIfAbsent("ysf", 0);
            result.putIfAbsent("yc", 0);
            result.putIfAbsent("jg", 0);
            result.putIfAbsent("fssb", 0);
            result.putIfAbsent("yfs", 0);
            result.putIfAbsent("blq", 0);
            result.putIfAbsent("dsf", 0);
            result.putIfAbsent("total", 0);
        }
        // ç¡®ä¿æ‰€æœ‰ key éƒ½æœ‰å€¼ï¼Œé¿å…ç©ºæŒ‡é’ˆå¼‚常
        // MyBatis çš„ SUM åœ¨æ²¡æœ‰åŒ¹é…è¡Œæ—¶ä¼šè¿”回 null
        result.putIfAbsent("wzx", 0);
        result.putIfAbsent("ysf", 0);
        result.putIfAbsent("yc", 0);
        result.putIfAbsent("jg", 0);
        result.putIfAbsent("fssb", 0);
        result.putIfAbsent("yfs", 0);
        result.putIfAbsent("blq", 0);
        result.putIfAbsent("dsf", 0);
        return result;
    }
@@ -1982,7 +1983,7 @@
//        if (existSize > 0) return pullTaskVOList;
        int count = 0;
        long size = listOps.size("cache-0");
        log.error("---------打电话之前缓存中的数据量:{}", size);
        log.info("---------打电话之前缓存中的数据量:{}", size);
        if (size > 0) {
            //phoneCount()  é€šè¿‡ç»™å‡ºçš„æ¯ä¸ªå°æ—¶éœ€è¦æ‰“出的电话量,算出到晚上8点一点能打出多少个电话,获取到总量
            //如果需要立即执行的数据量大于一天要执行的上限,则只取上限的数量,其它的则放回redis中
@@ -2031,7 +2032,7 @@
            }
        }
//        if (existList.size() != 0) redisCache.setCacheListRight("cache-exist", existList);
        log.error("-----------实际拉取的电话数据量:{}", CollectionUtils.isNotEmpty(pullTaskVOList) ? pullTaskVOList.size() : null);
        log.info("-----------实际拉取的电话数据量:{}", CollectionUtils.isNotEmpty(pullTaskVOList) ? pullTaskVOList.size() : null);
        return pullTaskVOList;
    }
@@ -3847,7 +3848,7 @@
            if (serviceSubtaskPreachform1.getSort() == spSize.size() && failSendstate.equals("4")) {
                serviceSubtask.setCurrentPreachform(preachform);
                serviceSubtask.setSendstate(5L);
//                serviceSubtask.setRemark("setFailPreachForm方法 å½“前的preachform已经是最后一个了,全失败了");
                serviceSubtask.setRemark("所有发送方式均未获取结果,任务失败");
                serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                return true;
            }
@@ -4017,4 +4018,65 @@
    public Map<String, Object> getCurrentUserServiceSubtaskCount(ServiceSubtaskEntity entity) {
        return serviceSubtaskMapper.getCurrentUserServiceSubtaskCount(entity);
    }
    @Override
    public Map<String, Object> getContinueNurseCount(ServiceSubtaskCotinueCountVO vo) {
        boolean hasDistrict = !CollectionUtils.isEmpty(vo.getLeavehospitaldistrictcodes());
        boolean hasDept = !CollectionUtils.isEmpty(vo.getDeptcodes());
        List<Map<String, Object>> districtRows;
        List<Map<String, Object>> deptRows;
        if (hasDistrict) {
            // åªä¼ äº†ç—…区:仅按病区维度统计
            districtRows = serviceSubtaskMapper.getContinueNurseCount(vo);
            deptRows = Collections.emptyList();
        } else if (hasDept) {
            // åªä¼ äº†ç§‘室:仅按科室维度统计
            districtRows = Collections.emptyList();
            deptRows = serviceSubtaskMapper.getContinueNurseCountByDept(vo);
        } else {
            // éƒ½æœªä¼ ï¼šç—…区和科室各统计一遍
            districtRows = serviceSubtaskMapper.getContinueNurseCount(vo);
            deptRows = serviceSubtaskMapper.getContinueNurseCountByDept(vo);
        }
        long totalNoContinue = 0L;
        long totalContinue = 0L;
        List<Map<String, Object>> detail = new ArrayList<>();
        for (Map<String, Object> row : districtRows) {
            String groupName = row.get("groupName") == null
                    ? (row.get("groupCode") == null ? "" : row.get("groupCode").toString())
                    : row.get("groupName").toString();
            long noCnt = row.get("noContinueCnt") == null ? 0L : Long.parseLong(row.get("noContinueCnt").toString());
            long yesCnt = row.get("continueCnt") == null ? 0L : Long.parseLong(row.get("continueCnt").toString());
            totalNoContinue += noCnt;
            totalContinue += yesCnt;
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("未延续_" + groupName, noCnt);
            item.put("已延续_"+groupName, yesCnt);
            detail.add(item);
        }
        for (Map<String, Object> row : deptRows) {
            String groupName = row.get("groupName") == null
                    ? (row.get("groupCode") == null ? "" : row.get("groupCode").toString())
                    : row.get("groupName").toString();
            long noCnt = row.get("noContinueCnt") == null ? 0L : Long.parseLong(row.get("noContinueCnt").toString());
            long yesCnt = row.get("continueCnt") == null ? 0L : Long.parseLong(row.get("continueCnt").toString());
            totalNoContinue += noCnt;
            totalContinue += yesCnt;
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("未延续_" + groupName, noCnt);
            item.put("已延续_" + groupName, yesCnt);
            detail.add(item);
        }
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("未延续总数量", totalNoContinue);
        result.put("已延续总数量", totalContinue);
        result.put("详情", detail);
        return result;
    }
}
smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml
@@ -854,167 +854,74 @@
    <select id="selectPatMedInhospCount" parameterType="com.smartor.domain.PatMedReq"
            resultType="com.smartor.domain.PatMedRes">
        SELECT SUM( rs ) AS rs,
        SUM( rc ) AS rc,
        SUM( scsf ) AS scsf,
        SUM( zcsf ) AS zcsf,
        SUM( zbsf ) AS zbsf
        SELECT SUM(rc) AS rc,
               SUM(rs) AS rs,
               SUM(scsf) AS scsf,
               SUM(zcsf) AS zcsf,
               SUM(zbsf) AS zbsf
        FROM (
        <!-- å‡ºé™¢äººæ¬¡-->
        SELECT
        COUNT(1) AS rc,
        0 AS rs,
        0 AS scsf,
        0 AS zcsf,
        0 AS zbsf
        FROM
        pat_med_inhosp
        JOIN
        pat_archive ON pat_archive.id = pat_med_inhosp.patid
        where 1=1
        and pat_med_inhosp.del_flag=0
        <if test="orgid != null and orgid != ''">
            and pat_med_inhosp.orgid = #{orgid}
        </if>
        AND pat_archive.idcardno IS NOT NULL
        <if test="zy != null">
            and pat_med_inhosp.inhospstate=0
            and date_format(pat_med_inhosp.starttime,'%y%m%d') &gt;= date_format(#{startDate},'%y%m%d')
            and date_format(pat_med_inhosp.starttime,'%y%m%d') &lt;= date_format(#{endDate},'%y%m%d')
            <if test="deptcodeList != null   and deptcodeList.size() > 0">
                and pat_med_inhosp.deptcode in
            <!-- å‡ºé™¢äººæ¬¡ï¼šåŽ»æŽ‰ date_format åŒ…装,使日期字段索引生效 -->
            SELECT
                COUNT(1) AS rc,
                0 AS rs,
                0 AS scsf,
                0 AS zcsf,
                0 AS zbsf
            FROM pat_med_inhosp
            JOIN pat_archive ON pat_archive.id = pat_med_inhosp.patid
            WHERE pat_med_inhosp.del_flag = 0
            <if test="orgid != null and orgid != ''">
                AND pat_med_inhosp.orgid = #{orgid}
            </if>
            AND pat_archive.idcardno IS NOT NULL
            <if test="zy != null">
                AND pat_med_inhosp.inhospstate = 0
                AND pat_med_inhosp.starttime &gt;= #{startDate}
                AND pat_med_inhosp.starttime &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
                <if test="deptcodeList != null and deptcodeList.size() > 0">
                    AND pat_med_inhosp.deptcode IN
                    <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                        #{deptcode}
                    </foreach>
                </if>
            </if>
            <if test="cy != null">
                AND pat_med_inhosp.inhospstate = 1
                AND pat_med_inhosp.endtime &gt;= #{startDate}
                AND pat_med_inhosp.endtime &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
                <if test="deptcodeList != null and deptcodeList.size() > 0">
                    AND pat_med_inhosp.leaveldeptcode IN
                    <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                        #{deptcode}
                    </foreach>
                </if>
            </if>
            UNION ALL
            <!-- éšè®¿æœåŠ¡/首次/再次/专病随访:合并为单次扫描,用条件聚合代替4个 UNION ALL -->
            SELECT
                0 AS rc,
                COUNT(1) AS rs,
                SUM(CASE WHEN service_type = 2 AND visit_count = 1 THEN 1 ELSE 0 END) AS scsf,
                SUM(CASE WHEN service_type = 2 AND visit_count > 1  THEN 1 ELSE 0 END) AS zcsf,
                SUM(CASE WHEN service_type = 13                      THEN 1 ELSE 0 END) AS zbsf
            FROM service_subtask
            WHERE del_flag = 0
            AND service_type IN (2, 13)
            <if test="orgid != null and orgid != ''">
                AND orgid = #{orgid}
            </if>
            <if test="startDate != null">
                AND visit_time &gt;= #{startDate}
            </if>
            <if test="endDate != null">
                AND visit_time &lt; DATE_ADD(#{endDate}, INTERVAL 1 DAY)
            </if>
            <if test="deptcodeList != null and deptcodeList.size() > 0">
                AND deptcode IN
                <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                    #{deptcode}
                </foreach>
            </if>
        </if>
        <if test="cy != null">
            and pat_med_inhosp.inhospstate=1
            and date_format(pat_med_inhosp.endtime,'%y%m%d') &gt;= date_format(#{startDate},'%y%m%d')
            and date_format(pat_med_inhosp.endtime,'%y%m%d') &lt;= date_format(#{endDate},'%y%m%d')
            <if test="deptcodeList != null   and deptcodeList.size() > 0">
                and pat_med_inhosp.leaveldeptcode in
                <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                    #{deptcode}
                </foreach>
            </if>
        </if>
        <!-- éšè®¿æœåŠ¡äººæ•° -->
        union all
        select
        0 AS rc,
        count(1) AS rs,
        0 AS scsf,
        0 AS zcsf,
        0 AS zbsf
        FROM
        service_subtask
        where 1=1
        and del_flag = 0
        and service_type=2
        <if test="orgid != null and orgid != ''">
            and orgid = #{orgid}
        </if>
        <if test="startDate != null">
            AND date_format( visit_time, '%y%m%d' ) &gt;= date_format( #{startDate}, '%y%m%d' )
        </if>
        <if test="endDate != null">
            AND date_format( visit_time, '%y%m%d' ) &lt;= date_format(#{endDate},'%y%m%d')
        </if>
        <if test="deptcodeList != null   and deptcodeList.size() > 0">
            and deptcode in
            <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        <!-- é¦–次随访人数 -->
        union all
        select
        0 AS rc,
        0 AS rs,
        count(1) AS scsf,
        0 AS zcsf,
        0 AS zbsf
        FROM
        service_subtask
        where 1=1
        and del_flag = 0
        and service_type=2
        and visit_count is not null
        and visit_count = 1
        <if test="orgid != null and orgid != ''">
            and orgid = #{orgid}
        </if>
        <if test="startDate != null">
            AND date_format( visit_time, '%y%m%d' ) &gt;= date_format( #{startDate}, '%y%m%d' )
        </if>
        <if test="endDate != null">
            AND date_format( visit_time, '%y%m%d' ) &lt;= date_format(#{endDate},'%y%m%d')
        </if>
        <if test="deptcodeList != null   and deptcodeList.size() > 0">
            and deptcode in
            <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        <!-- å†æ¬¡éšè®¿äººæ•° -->
        union all
        select
        0 AS rc,
        0 AS rs,
        0 AS scsf,
        count(1) AS zcsf,
        0 AS zbsf
        FROM
        service_subtask
        where 1=1
        and del_flag = 0
        and service_type=2
        and visit_count is not null
        and visit_count > 1
        <if test="orgid != null and orgid != ''">
            and orgid = #{orgid}
        </if>
        <if test="startDate != null">
            AND date_format( visit_time, '%y%m%d' ) &gt;= date_format( #{startDate}, '%y%m%d' )
        </if>
        <if test="endDate != null">
            AND date_format( visit_time, '%y%m%d' ) &lt;= date_format(#{endDate},'%y%m%d')
        </if>
        <if test="deptcodeList != null   and deptcodeList.size() > 0">
            and deptcode in
            <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        <!-- ä¸“病随访人数 -->
        union all
        select
        0 AS rc,
        0 AS rs,
        0 AS scsf,
        0 AS zcsf,
        count(1) AS zbsf
        FROM
        service_subtask
        where 1=1
        and del_flag = 0
        and service_type=13
        <if test="orgid != null and orgid != ''">
            and orgid = #{orgid}
        </if>
        <if test="startDate != null">
            AND date_format( visit_time, '%y%m%d' ) &gt;= date_format( #{startDate}, '%y%m%d' )
        </if>
        <if test="endDate != null">
            AND date_format( visit_time, '%y%m%d' ) &lt;= date_format(#{endDate},'%y%m%d')
        </if>
        <if test="deptcodeList != null   and deptcodeList.size() > 0">
            and deptcode in
            <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        ) AS combined_data
    </select>
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -265,7 +265,7 @@
    <select id="selectServiceSubtaskList" parameterType="com.smartor.domain.entity.ServiceSubtaskEntity"
            resultMap="ServiceSubtaskResult">
        <include refid="selectServiceSubtaskVo"/>
        where  del_flag = 0
        where del_flag = 0
        <if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
        <if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
        <if test="continueCount != null ">and continue_count = #{continueCount}</if>
@@ -1243,6 +1243,9 @@
            <if test="continueContent != null ">continue_content = #{continueContent},</if>
        </trim>
        where patid = #{patid} and taskid = #{taskid}
        <if test="id != null ">
            and id = #{id}
        </if>
    </update>
    <update id="updateServiceSubtaskByTaskGuid" parameterType="com.smartor.domain.ServiceSubtask">
@@ -2132,7 +2135,8 @@
        SUM(CASE WHEN sendstate = 2 THEN 1 ELSE 0 END) AS dsf,
        SUM(CASE WHEN sendstate = 1 THEN 1 ELSE 0 END) AS blq,
        SUM(CASE WHEN excep IS NOT NULL AND excep = '1' THEN 1 ELSE 0 END) AS yc,
        SUM(CASE WHEN excep IS NOT NULL AND excep = '2' THEN 1 ELSE 0 END) AS jg
        SUM(CASE WHEN excep IS NOT NULL AND excep = '2' THEN 1 ELSE 0 END) AS jg,
        COUNT(1) as total
        FROM service_subtask
        where 1=1
        and del_flag = 0
@@ -2418,4 +2422,62 @@
        </if>
    </select>
    <!--
        æŒ‰ç—…区或科室分组统计 continue_flag æ•°é‡
        ä¼ äº† leavehospitaldistrictcodes â†’ æŒ‰ç—…区维度
        ä¼ äº† deptcodes              â†’ æŒ‰ç§‘室维度
        éƒ½ä¸ä¼                      â†’ æŒ‰ç—…区维度统计全量
    -->
    <!-- æŒ‰ç—…区分组统计延续护理数量 -->
    <select id="getContinueNurseCount"
            parameterType="com.smartor.domain.VO.ServiceSubtaskCotinueCountVO"
            resultType="java.util.Map">
        SELECT
        leavehospitaldistrictcode AS groupCode,
        leavehospitaldistrictname AS groupName,
        SUM(CASE WHEN continue_flag = 1 THEN 1 ELSE 0 END) AS noContinueCnt,
        SUM(CASE WHEN continue_flag = 2 THEN 1 ELSE 0 END) AS continueCnt
        FROM service_subtask
        WHERE del_flag = 0
        AND continue_flag IN (1, 2)
        AND leavehospitaldistrictcode IS NOT NULL AND leavehospitaldistrictcode != ''
        <if test="orgid != null and orgid != ''">
            AND orgid = #{orgid}
        </if>
        <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
            AND leavehospitaldistrictcode IN
            <foreach collection="leavehospitaldistrictcodes" item="code" open="(" separator="," close=")">
                #{code}
            </foreach>
        </if>
        GROUP BY leavehospitaldistrictcode, leavehospitaldistrictname
        ORDER BY groupCode
    </select>
    <!-- æŒ‰ç§‘室分组统计延续护理数量 -->
    <select id="getContinueNurseCountByDept"
            parameterType="com.smartor.domain.VO.ServiceSubtaskCotinueCountVO"
            resultType="java.util.Map">
        SELECT
        deptcode AS groupCode,
        deptname AS groupName,
        SUM(CASE WHEN continue_flag = 1 THEN 1 ELSE 0 END) AS noContinueCnt,
        SUM(CASE WHEN continue_flag = 2 THEN 1 ELSE 0 END) AS continueCnt
        FROM service_subtask
        WHERE del_flag = 0
        AND continue_flag IN (1, 2)
        AND deptcode IS NOT NULL AND deptcode != ''
        <if test="orgid != null and orgid != ''">
            AND orgid = #{orgid}
        </if>
        <if test="deptcodes != null and deptcodes.size() > 0">
            AND deptcode IN
            <foreach collection="deptcodes" item="code" open="(" separator="," close=")">
                #{code}
            </foreach>
        </if>
        GROUP BY deptcode, deptname
        ORDER BY groupCode
    </select>
</mapper>