liusheng
8 天以前 c111e3eff1191b29d2d2baf2f485a4bf3a2edc00
代码提交
已添加2个文件
已修改50个文件
1651 ■■■■■ 文件已修改
.idea/compiler.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatBabyGrowthController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SchemeAutofinshruleController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/test/MQTest.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-druid-linshi.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-local.yml 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/RSAPublicKeyExample.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ExternalPatientInfo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchive.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchiveOthreInfo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchiveOut.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchiveReq.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchiveVO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatBabyGrowth.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceStatisticsRequest.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceStatisticsResponse.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtaskVO.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/SchemeAutofinshruleMapper.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/ISchemeAutofinshruleService.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ExternalInfoServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaTemplateServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrTaskTemplateServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/SchemeAutofinshruleServiceImpl.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceTaskServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/SvyLibTemplateServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ExternallInfoMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/SchemeAutofinshruleMapper.xml 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml 602 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/compiler.xml
@@ -7,6 +7,7 @@
        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
        <outputRelativeToContentRoot value="true" />
        <module name="ruoyi-framework" />
        <module name="smartor-wuxi" />
        <module name="ruoyi-system" />
        <module name="smartor" />
        <module name="ruoyi-generator" />
ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
@@ -295,6 +295,7 @@
                    for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
                        //先判断一下,subIds是否为空,如果不为空,只执行subIds里的患者
                        log.info("-----subIds的值为:{}", subIds);
                        if (CollectionUtils.isNotEmpty(subIds)) {
                            boolean contains = subIds.contains(serviceSubtask.getId());
                            //如果contains不为true,说明当前的患者已经发送成功,直接循环下一个人就行
@@ -321,7 +322,7 @@
                                sendMagParam.setPhone(serviceSubtask.getPhone());
                                sendMagParam.setUrl(ip + ":" + req_path + "/sf?p=" + format);
                                sendMagParam.setContent("您好,邀请您填写出院随访调查表,请点击" + sendMagParam.getUrl() + "   å¡«å†™ã€‚感谢您配合!");
                                log.info("888888888888:{}",sendMagParam);
                                log.info("888888888888:{}", sendMagParam);
                            } else if (type == 2) {
                                //问券(问题)
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
@@ -340,7 +341,7 @@
                                sendMagParam.setPhone(serviceSubtask.getPhone());
                                sendMagParam.setUrl(ip + ":" + req_path + "/wt?p=" + format);
                                sendMagParam.setContent("您好,邀请您填写出院调查表,请点击" + sendMagParam.getUrl() + "   å¡«å†™ã€‚感谢您配合!");
                                log.info("您好,邀请您填写出院调查表,请点击,{}",sendMagParam.getUrl());
                                log.info("您好,邀请您填写出院调查表,请点击,{}", sendMagParam.getUrl());
                            } else if (type == 3) {
                                //宣教
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
@@ -358,6 +359,7 @@
                                sendMagParam.setPhone(serviceSubtask.getPhone());
                                sendMagParam.setUrl(ip + ":" + req_path + "/xj?p=" + format);
                                sendMagParam.setContent("您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                log.info("-----------sendMagParam的值为:{}", sendMagParam);
                            }
                            //短信还需要模板
//                            Map<String, String> req = new HashMap<>();
@@ -374,6 +376,7 @@
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmsszzz"); // è¾“出日期格式
                            strb.append("&send_time=" + dateFormat.format(new Date()));
                            String isSuccess = HttpUtil.postFormRequest(xhsmsPath, strb.toString());
                            log.info("-----------sisSuccess的值为:{}", isSuccess);
                            if (StringUtils.isNotEmpty(isSuccess) && isSuccess.contains("200")) {
                                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -59,6 +59,12 @@
    @Value("${uploadSwitch}")
    private Integer uploadSwitch;
    @Value("${req_path}")
    private String reqPath;
    @Value("${localIP}")
    private String localIP;
    /**
     * é€šç”¨ä¸‹è½½è¯·æ±‚
     *
@@ -108,7 +114,10 @@
            String fileName = FileUploadUtils.uploadSort(filePath, file);
            String url = null;
            //新华医院特殊,这个视频的访问得转
            String xhPath = "http://218.108.11.22:8093/profile-api";
            String xhPath = localIP + ":" + reqPath + "/profile-api";
            if (localIP.contains("127.0.0.1") || localIP.contains("localhost")) {
                xhPath = localIP + ":8095" + "/profile";
            }
            if (uploadSwitch == 1) {
                String fn = fileName.replaceAll("/profile", "");
                url = xhPath + fn;
@@ -143,7 +152,10 @@
            convertDocToHtml(filePath + "\\" + file.getOriginalFilename(), filePath + "\\" + file.getOriginalFilename().split("\\.", 2)[0] + ".html");
            String url = null;
            String xhPath = "http://218.108.11.22:8093/profile-api";
            String xhPath = localIP + ":" + reqPath + "/profile-api";
            if (localIP.contains("127.0.0.1") || localIP.contains("localhost")) {
                xhPath = localIP + ":8095" + "/profile";
            }
            if (uploadSwitch == 1) {
                String fn = fileName.replaceAll("\\.[^.]*$", ".html").replaceAll("/profile", "");
                url = xhPath + fn;
@@ -269,7 +281,10 @@
            e.printStackTrace();
        }
        String url = null;
        String xhPath = "http://218.108.11.22:8093/profile-api";
        String xhPath = localIP + ":" + reqPath + "/profile-api";
        if (localIP.contains("127.0.0.1") || localIP.contains("localhost")) {
            xhPath = localIP + ":8095" + "/profile";
        }
        if (uploadSwitch == 1) {
            url = xhPath + "/upload/show/" + fileName.split("\\.", 2)[0] + "/" + fileName;
        } else {
@@ -313,6 +328,5 @@
        System.out.println("word转html成功");
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatBabyGrowthController.java
@@ -52,9 +52,9 @@
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     * æŸ¥è¯¢å©´å„¿æˆé•¿è®°å½•史
     */
    @ApiOperation("查询【请填写功能名称】列表")
    @ApiOperation("查询婴儿成长记录史")
    //@PreAuthorize("@ss.hasPermi('smartor:growth:list')")
    @PostMapping("/dateLine")
    public TableDataInfo dateLine(@RequestBody PatBabyGrowth patBabyGrowth)
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
@@ -93,6 +93,8 @@
    @PostMapping("/selectPatMedInhospListCount")
    @ApiOperation("查询出、入院看病人次和人数")
    public AjaxResult selectPatMedInhospListCount(PatMedReq patMedReq) {
        SysUser user = getLoginUser().getUser();
        patMedReq.setOrgid(user.getOrgid());
        return success(patMedInhospService.selectPatMedInhospListCount(patMedReq));
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SchemeAutofinshruleController.java
@@ -18,7 +18,7 @@
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.smartor.domain.SchemeAutofinshrule;
import com.ruoyi.smartor.service.ISchemeAutofinshruleService;
import com.smartor.service.ISchemeAutofinshruleService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -268,4 +268,16 @@
        return success(serviceSubtaskService.getSfStatistics(serviceSubtaskCountReq));
    }
    /**
     * éšè®¿ç»Ÿè®¡å¯¼å‡º
     */
    @ApiOperation("服务统计查询-按时间维度统计出院/门诊随访数据")
    @PostMapping("/getServiceStatistics")
    public AjaxResult getServiceStatistics(@RequestBody ServiceStatisticsRequest serviceStatisticsRequest) {
        SysUser user = getLoginUser().getUser();
        serviceStatisticsRequest.setOrgid(user.getOrgid());
        List<ServiceStatisticsResponse> serviceStatistics = serviceSubtaskService.getServiceStatistics(serviceStatisticsRequest);
        return success(serviceStatistics);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -2,10 +2,17 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.mapper.SysUserMapper;
import com.smartor.domain.BaseSmsRequest;
import com.smartor.service.IBaseSmsaccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -41,6 +48,17 @@
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IBaseSmsaccountService baseSmsaccountService;
    @Value("${spring.profiles.active}")
    private String active;
    /**
     * ç™»å½•方法
     *
@@ -50,8 +68,14 @@
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
        String token = null;
        if (loginBody.getPhoneCode() != null) {
            String phone = redisCache.getCacheObject(loginBody.getPhoneCode());
            token = loginService.loginByPhone(phone);
        } else {
            // ç”Ÿæˆä»¤ç‰Œ
            token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
        }
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
@@ -102,4 +126,31 @@
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
    /**
     * éªŒè¯ç å‘送
     *
     * @param payload
     * @return
     */
    @PostMapping("/phoneLogin")
    public AjaxResult sendCode(@RequestBody Map<String, String> payload) {
        String phone = payload.get("phone");
        String code = String.format("%06d", new Random().nextInt(999999));
        // å­˜å…¥ Redis,有效期2分钟
        redisCache.setCacheObject(code, phone, 2, TimeUnit.MINUTES);
        //无锡线上环境才发短信
        if (active.equals("wx")) {
            BaseSmsRequest baseSmsRequest = new BaseSmsRequest();
            baseSmsRequest.setPhoneNumber(phone);
            baseSmsRequest.setContent("登陆验证码:" + code + " ï¼Œ2分钟内效,切勿将验证码提供给他人,谨防被骗。");
            baseSmsaccountService.sendMsg(baseSmsRequest);
        }
        // è°ƒç”¨çŸ­ä¿¡æœåŠ¡å‘é€éªŒè¯ç 
        System.out.println("登陆验证码:" + code);
        return AjaxResult.success(true);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/test/MQTest.java
@@ -2,6 +2,7 @@
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.RSAPublicKeyExample;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.smartor.domain.ServiceSubtaskDetail;
@@ -48,9 +49,11 @@
    @Test
    public void bb() {
        String key="1-9-WJscriptCache";
        String[] split = key.split("-");
        System.out.println(split.clone());
        RSAPublicKeyExample rsaPublicKeyExample=new RSAPublicKeyExample();
//        String s1 = rsaPublicKeyExample.encryptedData("123456", "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALQzqW1EIXBKGMu+2oEYSB5gM7Ox/ihyYTeeoE0yPX1qtt4++5yNOeTBVd6EEM4iKzVEzWj6REIWVwaSNPn/SvUCAwEAAQ==");
        String s = rsaPublicKeyExample.decryptedData("J7V6yb5WHW63bQMbMyzxeT07HGesIXJwy9w77zBa6KG4PnWe7uaZh00vX21w%2Bn5FW8%2BjUAAU1HatqRWzFp7fvA%3D%3D", "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAtDOpbUQhcEoYy77agRhIHmAzs7H+KHJhN56gTTI9fWq23j77nI055MFV3oQQziIrNUTNaPpEQhZXBpI0+f9K9QIDAQABAkB3n0fcWfrcoMN/FU3VnrnZOEF6CzFNxkgU9P8y36QECWKZ9JhYQkNpKrMC9oXlN3VSaRigV7B+L/I/a0Rs1W+tAiEA4jx7xcXJ4y4BNwAmVHt6NNiEkzIwWnwC/0qsEu8NsOsCIQDL6MMn1D2uznC6OuOWpxDCkBh1JL1NzZTZeH2G+hj7nwIgKGAC9tjFnvWm4dn0/T7MIIJDpsFeP8fCAS2iZ/6hwuECIAS/eLvWr1EAsZNEh8QcQ8GkBU3E+ztyjAK8UX/xFt/VAiBf79/1tDErX4/DChecM8w3c3DhbBcjuE3fHZn7p6/UKg==");
    System.out.println(s);
    }
    public void aa(MultipartFile file) throws IOException {
ruoyi-admin/src/main/resources/application-druid-linshi.yml
@@ -144,9 +144,9 @@
#req_path: 8095
#localIP: 192.168.2.10
#新华医院外链请求IP和端口号
req_path: 8093
localIP: 218.108.11.22
#外链请求IP和端口号
req_path: 8092
localIP: 192.16.4.220
#获取患者信息URL(华卓提供)
hosp_info_url: http://esb-core-rest.wowjoy.cn/esb/exchange
ruoyi-admin/src/main/resources/application-local.yml
@@ -19,15 +19,15 @@
        #        password: csbsbxt@123
        #        driver-class-name: org.postgresql.Driver
        #      æœ¬åœ°é«˜æ–¯
        url: jdbc:postgresql://192.168.100.138:5432/postgres
        url: jdbc:postgresql://192.168.100.126:5432/postgres
        username: gaussdb
        password: Ls@123456
        driver-class-name: org.postgresql.Driver
        #      é«˜æ–¯æ•°æ®åº“链接
#        url: jdbc:postgresql://172.20.32.115:15400/smartorwx?prepareThreshold=0
#        username: shuifang
#        password: Shuifang@51868
#        driver-class-name: org.postgresql.Driver
      #        url: jdbc:postgresql://172.20.32.115:15400/smartorwx?prepareThreshold=0
      #        username: shuifang
      #        password: Shuifang@51868
      #        driver-class-name: org.postgresql.Driver
      #        å…¬å¸äº‘
      #        url: jdbc:mysql://116.62.18.175:6002/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
@@ -79,15 +79,15 @@
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: false
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # redis é…ç½®
  redis:
    #    # åœ°å€ï¼ˆæ— é”¡äººæ°‘医院)
#    host: 127.0.0.1
#    port: 6020
    #    host: 127.0.0.1
    #    port: 6020
    # åœ°å€ï¼ˆå…¬å¸ï¼‰
    host: 127.0.0.1
@@ -181,8 +181,8 @@
qrpath: D:\qrcode
#无锡内外链请求IP和端口号
req_path: 8092/wxsf
localIP: 192.168.100.128
req_path: 8093
localIP: 127.0.0.1
#req_path: 8092
#localIP: http://61.160.111.174
ruoyi-admin/src/main/resources/application.yml
@@ -9,7 +9,8 @@
  # å®žä¾‹æ¼”示开关
  demoEnabled: true
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/ruoyi/uploadPath
#  profile: D:/ruoyi/uploadPath
  profile: /home/software/uploadPath
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°ç»„计算 char å­—符验证
@@ -74,7 +75,7 @@
    # å›½é™…化资源文件路径
    basename: i18n/messages
  profiles:
    active: wx
    active: local
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java
@@ -2,11 +2,10 @@
/**
 * ç”¨æˆ·ç™»å½•对象
 *
 *
 * @author ruoyi
 */
public class LoginBody
{
public class LoginBody {
    /**
     * ç”¨æˆ·å
     */
@@ -23,47 +22,52 @@
    private String code;
    /**
     * æ‰‹æœºéªŒè¯ç 
     */
    private String phoneCode;
    /**
     * å”¯ä¸€æ ‡è¯†
     */
    private String uuid;
    public String getUsername()
    {
    public String getUsername() {
        return username;
    }
    public void setUsername(String username)
    {
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword()
    {
    public String getPassword() {
        return password;
    }
    public void setPassword(String password)
    {
    public void setPassword(String password) {
        this.password = password;
    }
    public String getCode()
    {
    public String getCode() {
        return code;
    }
    public void setCode(String code)
    {
    public void setCode(String code) {
        this.code = code;
    }
    public String getUuid()
    {
    public String getUuid() {
        return uuid;
    }
    public void setUuid(String uuid)
    {
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }
    public String getPhoneCode() {
        return phoneCode;
    }
    public void setPhoneCode(String phoneCode) {
        this.phoneCode = phoneCode;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/RSAPublicKeyExample.java
@@ -20,71 +20,58 @@
public class RSAPublicKeyExample {
    /**
     * æ•°æ®è§£å¯†
     *
     * @param encryptedData
     * @return
     */
    public String decryptedData(String encryptedData, String pri_key) {
        String privateKeyString = "私钥的Base64编码字符串"; // åŽç«¯ç§é’¥çš„Base64编码字符串
    public static String encryptedData(String plainText, String pubKey) {
        try {
            // å°†ç§é’¥Base64编码字符串转换为PrivateKey对象
            byte[] privateKeyBytes = Base64.getDecoder().decode(pri_key);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            // ä½¿ç”¨ç§é’¥è§£å¯†æ•°æ®
            Cipher decryptCipher = Cipher.getInstance("RSA");
            decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encryptedData));
            // è§£å¯†åŽçš„æ•°æ®
            String decryptedData = new String(decryptedBytes);
            System.out.println("解密后的数据:" + decryptedData);
            return decryptedData;
        } catch (Exception e) {
            log.error("解密报错了:{}", e.getMessage());
        }
        return null;
    }
    /**
     * è¦åŠ å¯†çš„æ˜Žæ–‡æ•°æ®
     *
     * @param plainText
     * @return
     */
    public String encryptedData(String plainText, String pub_key) {
        log.error("需要加密的数据:{}", plainText);
        try {
            byte[] publicKeyBytes = Base64.getDecoder().decode(pub_key);
            byte[] publicKeyBytes = Base64.getDecoder().decode(pubKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            // ä½¿ç”¨å…¬é’¥åŠ å¯†æ•°æ®
            Cipher encryptCipher = Cipher.getInstance("RSA");
            encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = encryptCipher.doFinal(plainText.getBytes());
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            // å°†åŠ å¯†åŽçš„æ•°æ®è½¬æ¢ä¸ºBase64编码的字符串
            // Base64 ç¼–码(必须保留)
            String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
            log.error("Base64加密后的数据:{}", encryptedText);
            encryptedText = URLEncoder.encode(encryptedText, StandardCharsets.UTF_8.toString());
            log.error("URLEncoder编码后的数据:{}", encryptedText);
            String decodedString = URLDecoder.decode(encryptedText, "UTF-8");
            log.error("URLEncoder解码后的数据:{}", decodedString);
            return encryptedText;
            // å¯é€‰ï¼šå¦‚果用于 URL ä¼ è¾“,再进行 URL ç¼–码
            return URLEncoder.encode(encryptedText, StandardCharsets.UTF_8.toString());
        } catch (Exception e) {
            log.error("加密失败了:{}", e.getMessage());
            System.err.println("加密失败: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
        return null;
    }
    /**
     * RSA ç§é’¥è§£å¯†ï¼ˆè§£å¯† Base64 ç¼–码后的密文,支持 URL è§£ç ï¼‰
     */
    public static String decryptedData(String encryptedData, String priKey) {
        try {
            // å¯é€‰ï¼šå…ˆ URL è§£ç ï¼ˆå¦‚果加密前做了 URLEncoder)
            String base64Encrypted = URLDecoder.decode(encryptedData, StandardCharsets.UTF_8.toString());
            // Base64 è§£ç 
            byte[] encryptedBytes = Base64.getDecoder().decode(base64Encrypted);
            byte[] privateKeyBytes = Base64.getDecoder().decode(priKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            System.err.println("解密失败: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
    public static void main(String[] args) {
        String decodedString = null;
        try {
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,7 +108,7 @@
                // è¿‡æ»¤è¯·æ±‚
                .authorizeRequests()
                // å¯¹äºŽç™»å½•login æ³¨å†Œregister éªŒè¯ç captchaImage å…è®¸åŒ¿åè®¿é—®
                .antMatchers("/login", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo", "/socket", "/API_ESB_Service", "/API_ESB_Service/Run", "/magic/web/**", "/smartor/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer","/smartor/import/download","/smartor/serviceSubtask/recordAccept","/smartor/outPath/getInfoByParam").permitAll()
                .antMatchers("/login","/phoneLogin", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo", "/socket", "/API_ESB_Service", "/API_ESB_Service/Run", "/magic/web/**", "/smartor/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer","/smartor/import/download","/smartor/serviceSubtask/recordAccept","/smartor/outPath/getInfoByParam").permitAll()
                // é™æ€èµ„源,可匿名访问
                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                // é™¤ä¸Šé¢å¤–的所有请求全部需要鉴权认证
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,6 +1,9 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@@ -27,14 +30,15 @@
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import java.util.List;
/**
 * ç™»å½•校验方法
 *
 *
 * @author ruoyi
 */
@Component
public class SysLoginService
{
public class SysLoginService {
    @Autowired
    private TokenService tokenService;
@@ -43,7 +47,7 @@
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService userService;
@@ -52,45 +56,35 @@
    /**
     * ç™»å½•验证
     *
     *
     * @param username ç”¨æˆ·å
     * @param password å¯†ç 
     * @param code éªŒè¯ç 
     * @param uuid å”¯ä¸€æ ‡è¯†
     * @param code     éªŒè¯ç 
     * @param uuid     å”¯ä¸€æ ‡è¯†
     * @return ç»“æžœ
     */
    public String login(String username, String password, String code, String uuid)
    {
    public String login(String username, String password, String code, String uuid) {
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        // éªŒè¯ç å¼€å…³
        if (captchaEnabled)
        {
        if (captchaEnabled) {
            validateCaptcha(username, code, uuid);
        }
        // ç”¨æˆ·éªŒè¯
        Authentication authentication = null;
        try
        {
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // è¯¥æ–¹æ³•会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
            } else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally
        {
        } finally {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
@@ -100,26 +94,39 @@
        return tokenService.createToken(loginUser);
    }
    public String loginByPhone(String phone) {
        SysUser sysUser = userService.selectUserByPhone(phone);
        if (ObjectUtils.isNotEmpty(sysUser)) {
            // æž„建登录用户对象
            LoginUser loginUser = new LoginUser();
            loginUser.setUser(sysUser);
            loginUser.setUserId(sysUser.getUserId());
            // åˆ›å»º token
            String token = tokenService.createToken(loginUser);
            // ç”Ÿæˆtoken
            return token;
        }
        return null;
    }
    /**
     * æ ¡éªŒéªŒè¯ç 
     *
     *
     * @param username ç”¨æˆ·å
     * @param code éªŒè¯ç 
     * @param uuid å”¯ä¸€æ ‡è¯†
     * @param code     éªŒè¯ç 
     * @param uuid     å”¯ä¸€æ ‡è¯†
     * @return ç»“æžœ
     */
    public void validateCaptcha(String username, String code, String uuid)
    {
    public void validateCaptcha(String username, String code, String uuid) {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null)
        {
        if (captcha == null) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha))
        {
        if (!code.equalsIgnoreCase(captcha)) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
@@ -130,8 +137,7 @@
     *
     * @param userId ç”¨æˆ·ID
     */
    public void recordLoginInfo(Long userId)
    {
    public void recordLoginInfo(Long userId) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
@@ -20,13 +20,12 @@
 * @author ruoyi
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
public class UserDetailsServiceImpl implements UserDetailsService {
    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysPasswordService passwordService;
@@ -34,21 +33,15 @@
    private SysPermissionService permissionService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = userService.selectUserByUserName(username);
        if (StringUtils.isNull(user))
        {
        if (StringUtils.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", username);
            throw new ServiceException("登录用户:" + username + " ä¸å­˜åœ¨");
        }
        else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
        } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            log.info("登录用户:{} å·²è¢«åˆ é™¤.", username);
            throw new ServiceException("对不起,您的账号:" + username + " å·²è¢«åˆ é™¤");
        }
        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", username);
            throw new ServiceException("对不起,您的账号:" + username + " å·²åœç”¨");
        }
@@ -58,8 +51,7 @@
        return createLoginUser(user);
    }
    public UserDetails createLoginUser(SysUser user)
    {
    public UserDetails createLoginUser(SysUser user) {
        return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -161,17 +161,13 @@
            JsonNode resultListNode = rootNode.path("results").path("resultList");
            // éåކresultList中的每个对象
            for (JsonNode item : resultListNode) {
                SysUserImport person = objectMapper.treeToValue(item, SysUserImport.class);
                person.setStaffPhoto("");
                sysUserImportMapper.insertSysUserImport(person);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void analysisData() {
@@ -208,7 +204,6 @@
        } catch (Exception e) {
            log.error("采集出院数据出问题了:{}", e.getMessage());
        }
    }
//
//    public void dealHisData2() {
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -45,6 +45,8 @@
     */
    public SysUser selectUserByUserName(String userName);
    public SysUser selectUserByPhone(String phone);
    /**
     * é€šè¿‡ç”¨æˆ·ID查询用户
     *
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -42,6 +42,9 @@
     */
    public SysUser selectUserByUserName(String userName);
    public SysUser selectUserByPhone(String phone);
    /**
     * é€šè¿‡ç”¨æˆ·ID查询用户
     *
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -104,6 +104,11 @@
     * @return ç”¨æˆ·å¯¹è±¡ä¿¡æ¯
     */
    @Override
    public SysUser selectUserByPhone(String phone) {
        return userMapper.selectUserByPhone(phone);
    }
    @Override
    public SysUser selectUserByUserName(String userName) {
        SysUser sysUser = userMapper.selectUserByUserName(userName);
        List<SysDept> sysDepts = sysUserDeptMapper.selectDeptListByUserId(sysUser.getUserId());
@@ -142,7 +147,7 @@
            }
            sysUser.setBelongWards(list);
        }
        log.error("潘处的科室是:{}",sysUserDeptKSs);
        log.error("潘处的科室是:{}", sysUserDeptKSs);
        if (!CollectionUtils.isEmpty(sysUserDeptKSs)) {
            List<Map<String, Object>> list = new ArrayList<>();
            for (SysUserDept sud : sysUserDeptKSs) {
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -210,6 +210,11 @@
        where u.user_name = #{userName} and u.del_flag = '0'
    </select>
    <select id="selectUserByPhone" parameterType="String" resultMap="SysUserResult">
        <include refid="selectUserVo"/>
        where u.phonenumber = #{phone} and u.del_flag = '0'
    </select>
    <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
        <include refid="selectUserVo"/>
        where u.user_id = #{userId}
smartor/src/main/java/com/smartor/domain/ExternalPatientInfo.java
@@ -66,6 +66,9 @@
    @ApiModelProperty(value = "家庭电话")
    private String jtdh;
    @ApiModelProperty(value = "预留电话")
    private String yldh;
    @ApiModelProperty(value = "户口地址")
    private String hkdz;
smartor/src/main/java/com/smartor/domain/PatArchive.java
@@ -214,6 +214,13 @@
    private String relativetelcode;
    /**
     * é¢„留号码
     */
    @ApiModelProperty("预留号码")
    @Excel(name = " é¢„留号码 ")
    private String reservedPhone;
    /**
     * æ°‘族
     */
    @ApiModelProperty("民族")
smartor/src/main/java/com/smartor/domain/PatArchiveOthreInfo.java
@@ -221,6 +221,12 @@
    @Excel(name = " æ‰‹æœºå·ç  ")
    private String telcode;
    /**
     * é¢„留号码
     */
    @ApiModelProperty("预留号码")
    @Excel(name = " é¢„留号码 ")
    private String reservedPhone;
    /**
     * äº²å±žå·ç 
smartor/src/main/java/com/smartor/domain/PatArchiveOut.java
@@ -129,6 +129,7 @@
    @ApiModelProperty("手机号码")
    private String telcode;
    /**
     * äº²å±žå·ç 
     */
smartor/src/main/java/com/smartor/domain/PatArchiveReq.java
@@ -74,6 +74,13 @@
    private String telcode;
    /**
     * é¢„留号码
     */
    @ApiModelProperty("预留号码")
    @Excel(name = " é¢„留号码 ")
    private String reservedPhone;
    /**
     * æ‰‹æœºå·ç 
     */
    @ApiModelProperty("手机号码")
@@ -199,9 +206,9 @@
    private List<String> leaveldeptcodes;
    /**
     * ç—…区编号
     * ç—…区编号集合
     */
    @ApiModelProperty(value = "病区编号")
    @ApiModelProperty(value = "病区编号集合")
    private List<String> hospitaldistrictcodes;
    /**
smartor/src/main/java/com/smartor/domain/PatArchiveVO.java
@@ -134,6 +134,12 @@
    @Excel(name = " æ‰‹æœºå·ç  ")
    private String telcode;
    /**
     * é¢„留号码
     */
    @ApiModelProperty("预留号码")
    @Excel(name = " é¢„留号码 ")
    private String reservedPhone;
    /**
     * äº²å±žå·ç 
smartor/src/main/java/com/smartor/domain/PatBabyGrowth.java
@@ -57,7 +57,7 @@
     */
    @ApiModelProperty("胎龄(周)")
    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
    private Long age;
    private String age;
    /**
     * $column.columnComment
smartor/src/main/java/com/smartor/domain/ServiceStatisticsRequest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package com.smartor.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
 * æœåŠ¡ç»Ÿè®¡è¯·æ±‚å‚æ•°
 *
 * @author smartor
 * @date 2025-01-14
 */
@ApiModel(value = "ServiceStatisticsRequest", description = "服务统计请求参数")
@Data
public class ServiceStatisticsRequest {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "开始日期", required = true, example = "2025-08-01")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    @ApiModelProperty(value = "结束日期", required = true, example = "2025-08-05")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
    @ApiModelProperty(value = "统计维度:day-按天, month-按月, year-按年", example = "day")
    private String timeType = "day";
    @ApiModelProperty(value = "机构ID,为空则查询所有")
    private String orgid;
    @ApiModelProperty(value = "科室编码列表,为空则查询所有")
    private List<String> deptcodes;
    @ApiModelProperty(value = "病区编码列表,为空则查询所有")
    private List<String> leavehospitaldistrictcodes;
    @ApiModelProperty(value = "服务类型列表,为空则查询所有 (2-出院随访, 3-门诊随访)")
    private List<String> serviceTypes;
}
smartor/src/main/java/com/smartor/domain/ServiceStatisticsResponse.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.smartor.domain;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * æœåŠ¡ç»Ÿè®¡å“åº”ç»“æžœ
 *
 * @author smartor
 * @date 2025-01-14
 */
@ApiModel(value = "ServiceStatisticsResponse", description = "服务统计响应结果")
@Data
public class ServiceStatisticsResponse {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "时间周期")
    @Excel(name = "时间周期")
    private String timePeriod;
    @ApiModelProperty(value = "出院随访量")
    @Excel(name = "出院随访量")
    private Long dischargeFollowCount = 0L;
    @ApiModelProperty(value = "门诊随访量")
    @Excel(name = "门诊随访量")
    private Long outpatientFollowCount = 0L;
    @ApiModelProperty(value = "出院人次")
    @Excel(name = "出院人次")
    private Long pmiCount = 0L;
    @ApiModelProperty(value = "门诊人次")
    @Excel(name = "门诊人次")
    private Long pmoCount = 0L;
}
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java
@@ -40,6 +40,9 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "离院诊断名称")
    private String leavediagname;
    /**
     * å¤‡æ³¨
     */
smartor/src/main/java/com/smartor/domain/ServiceSubtaskVO.java
@@ -15,7 +15,6 @@
 * å•一任务(随访)对象 ivr_taskcall
 *
 * @author ruoyi
 * @date 2024-02-02
 */
@ApiModel(value = "ServiceSubtaskVO", description = "单一随访任务入参")
@Data
@@ -26,7 +25,39 @@
     *
     */
    @ApiModelProperty(value = "主键id")
    private Long id;
    private Long subId;
    /**
     * éšè®¿æ¬¡æ•°
     */
    @ApiModelProperty(value = "随访次数")
    private Integer visitCount;
    /**
     * æ˜¯å¦åœ¨æ¬¡éšè®¿ï¼š1否    2是
     */
    @ApiModelProperty(value = "是否在次随访:1是    2否")
    private Integer isVisitAgain;
    /**
     * æ‚£è€…ID
     */
    @Excel(name = "  æ‚£è€…ID")
    @ApiModelProperty(value = "患者ID")
    private String patguid;
    /**
     * å¤è¯Šé€šçŸ¥ï¼š0已通知    1未通知
     */
    @ApiModelProperty(value = "复诊通知:0已通知    1未通知")
    private Integer visitNotice;
    /**
     * å‡ºé™¢è¯Šæ–­åç§°
     */
    @Excel(name = "  å‡ºé™¢è¯Šæ–­åç§°")
    @ApiModelProperty(value = "出院诊断名称")
    private String leavediagname;
    /**
     * å‡ºé™¢ç—…人记录ID
@@ -600,17 +631,91 @@
    /**
     * å¼€å§‹å‡ºé™¢æ—¥æœŸ
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "开始出院日期")
    private Date startOutHospTime;
    /**
     * ç»“束出院日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @ApiModelProperty(value = "结束出院日期")
    private Date endOutHospTime;
    /**
     * æŽ’序()
     */
    @ApiModelProperty(value = "排序:0 å‡ºé™¢æ—¶é—´(正序)    1 å‡ºé™¢æ—¶é—´(倒序)   2 å‘送时间(正序)    3 å‘送时间(倒序) ")
    private Integer sort;
    /**
     * ç¬¬ä¸‰æ–¹ä»»åŠ¡ID
     */
    @ApiModelProperty(value = "第三方任务ID")
    private String taskGuid;
    /**
     * åˆ›å»ºå¼€å§‹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createStartTime;
    /**
     * åˆ›å»ºç»“束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createEndTime;
    /**
     * ç§‘室与病区的查询是or还是and:   1:and(默认)     2:or
     */
    @ApiModelProperty(value = "科室与病区的查询是or还是and:   1:and(默认)     2:or  ")
    private String deptOrDistrict = "1";
    /**
     * æ‚£è€…来源
     */
    @ApiModelProperty(value = "患者来源:0本地患者表    1外部患者表")
    private String patfrom;
    /**
     * å¼€å§‹å‘送日期
     */
    @ApiModelProperty(value = "开始发送日期")
    private Date startSendDateTime;
    /**
     * ç»“束发送日期
     */
    @ApiModelProperty(value = "结束发送日期")
    private Date endSendDateTime;
    /**
     * /**
     * æ‚£è€…上次随访的subId
     */
    @ApiModelProperty(value = "患者上次随访的subId")
    private Integer upid;
    @ApiModelProperty(value = "随访时间")
    private Date visitTime;
    /**
     * éšè®¿æ–¹å¼
     */
    @ApiModelProperty(value = "随访方式")
    private String visitType;
    @ApiModelProperty(value = "随访部门编码")
    private String visitDeptCode;
    @ApiModelProperty(value = "随访部门名称")
    private String visitDeptName;
    @ApiModelProperty(value = "随访部门编码集合")
    private List<String> visitDeptCodes;
}
smartor/src/main/java/com/smartor/mapper/SchemeAutofinshruleMapper.java
@@ -1,19 +1,19 @@
package com.ruoyi.smartor.mapper;
package com.smartor.mapper;
import java.util.List;
import com.ruoyi.smartor.domain.SchemeAutofinshrule;
import com.smartor.domain.SchemeAutofinshrule;
/**
 * æ–¹æ¡ˆç»“案规则Mapper接口
 *
 *
 * @author smartor
 * @date 2023-03-04
 */
public interface SchemeAutofinshruleMapper
public interface SchemeAutofinshruleMapper
{
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return æ–¹æ¡ˆç»“案规则
     */
@@ -21,7 +21,7 @@
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则列表
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return æ–¹æ¡ˆç»“案规则集合
     */
@@ -29,7 +29,7 @@
    /**
     * æ–°å¢žæ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
@@ -37,7 +37,7 @@
    /**
     * ä¿®æ”¹æ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
@@ -45,7 +45,7 @@
    /**
     * åˆ é™¤æ–¹æ¡ˆç»“案规则
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return ç»“æžœ
     */
@@ -53,7 +53,7 @@
    /**
     * æ‰¹é‡åˆ é™¤æ–¹æ¡ˆç»“案规则
     *
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ä¸»é”®é›†åˆ
     * @return ç»“æžœ
     */
smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
@@ -1,9 +1,6 @@
package com.smartor.mapper;
import com.smartor.domain.ServiceSubtask;
import com.smartor.domain.ServiceSubtaskCount;
import com.smartor.domain.ServiceSubtaskCountReq;
import com.smartor.domain.ServiceSubtaskVO;
import com.smartor.domain.*;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -75,4 +72,6 @@
    public List<ServiceSubtask> getSfStatistics(ServiceSubtaskCountReq serviceSubtaskCountReq);
    public List<ServiceStatisticsResponse> getServiceStatistics(ServiceStatisticsRequest serviceStatisticsRequest);
}
smartor/src/main/java/com/smartor/service/ISchemeAutofinshruleService.java
@@ -1,19 +1,19 @@
package com.ruoyi.smartor.service;
package com.smartor.service;
import java.util.List;
import com.ruoyi.smartor.domain.SchemeAutofinshrule;
/**
 * æ–¹æ¡ˆç»“案规则Service接口
 *
 *
 * @author smartor
 * @date 2023-03-04
 */
public interface ISchemeAutofinshruleService
public interface ISchemeAutofinshruleService
{
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return æ–¹æ¡ˆç»“案规则
     */
@@ -21,7 +21,7 @@
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则列表
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return æ–¹æ¡ˆç»“案规则集合
     */
@@ -29,7 +29,7 @@
    /**
     * æ–°å¢žæ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
@@ -37,7 +37,7 @@
    /**
     * ä¿®æ”¹æ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
@@ -45,7 +45,7 @@
    /**
     * æ‰¹é‡åˆ é™¤æ–¹æ¡ˆç»“案规则
     *
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ–¹æ¡ˆç»“案规则主键集合
     * @return ç»“æžœ
     */
@@ -53,7 +53,7 @@
    /**
     * åˆ é™¤æ–¹æ¡ˆç»“案规则信息
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return ç»“æžœ
     */
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
@@ -1,9 +1,6 @@
package com.smartor.service;
import com.ruoyi.common.core.domain.AjaxResult;
import com.smartor.domain.*;
import com.smartor.domain.ServiceSubtask;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
import java.util.Map;
@@ -119,9 +116,12 @@
    /**
     * èŽ·å–éšè®¿ç»Ÿè®¡æ¯”ä¾‹
     *
     * @param serviceSubtaskCountReq
     * @return
     */
    public List<ServiceSubtaskStatistic> getSfStatistics(ServiceSubtaskCountReq serviceSubtaskCountReq);
    public List<ServiceStatisticsResponse> getServiceStatistics(ServiceStatisticsRequest request);
}
smartor/src/main/java/com/smartor/service/impl/ExternalInfoServiceImpl.java
@@ -595,7 +595,8 @@
    public Boolean getExternalLeaveHospPatientInfo30Day() {
        try {
            // å›ºå®šå¼€å§‹æ—¶é—´
            String fixedStartTime = "2025-03-25";
//            String fixedStartTime = "2025-03-25";
            String fixedStartTime = "2025-02-01";
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String today = formatter.format(new Date());
@@ -608,7 +609,8 @@
            try {
                startCal.setTime(formatter.parse(fixedStartTime));
                endCal.setTime(formatter.parse(today));
                endCal.setTime(formatter.parse("2025-06-08"));
//                endCal.setTime(formatter.parse(today));
            } catch (ParseException e) {
                log.error("日期解析失败:{}", e.getMessage(), e);
                return false;
smartor/src/main/java/com/smartor/service/impl/IvrLibaTemplateServiceImpl.java
@@ -39,8 +39,6 @@
    @Autowired
    private IvrLibaTemplateScriptMapper ivrLibaTemplateScriptMapper;
    @Autowired
    private TemplateDeptMapper tempDetpRelevanceMapper;
    /**
     * æŸ¥è¯¢æ¨¡æ¿åº“
@@ -172,20 +170,6 @@
                    IvrLibaTemplateScript ivrLibaTemplateScript = scriptHandle(ivrLibaTemplate, ivrLibaTemplateScriptVO, ivrLibaTemplateVO.getIsoperation());
//                    dealOption(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList(), ivrLibaTemplateScript, ivrLibaTemplate.getId(), ivrLibaTemplateVO.getIsoperation());
                }
            }
        }
        //对科室进行处理
        for (TemplateDept tempDetpRelevance : ivrLibaTemplateVO.getTempDetpRelevances()) {
            if (tempDetpRelevance.getId() == null) {
                //新增
                tempDetpRelevance.setTempid(ivrLibaTemplate.getId());
                tempDetpRelevance.setType(2L);
                tempDetpRelevance.setCreateTime(new Date());
                tempDetpRelevanceMapper.insertTemplateDept(tempDetpRelevance);
            } else {
                tempDetpRelevance.setUpdateTime(new Date());
                tempDetpRelevanceMapper.updateTemplateDept(tempDetpRelevance);
            }
        }
smartor/src/main/java/com/smartor/service/impl/IvrTaskTemplateServiceImpl.java
@@ -11,7 +11,6 @@
import com.smartor.mapper.IvrTaskTemplateMapper;
import com.smartor.mapper.IvrTaskTemplateScriptMapper;
import com.smartor.mapper.IvrTaskTemplateTargetoptionMapper;
import com.smartor.mapper.TemplateDeptMapper;
import com.smartor.service.IIvrTaskTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -41,8 +40,6 @@
    @Autowired
    private IvrTaskTemplateTargetoptionMapper ivrTaskTemplateTargetoptionMapper;
    @Autowired
    private TemplateDeptMapper templateDeptMapper;
    /**
     * æŸ¥è¯¢éšè®¿ä»»åŠ¡éšè®¿æ¨¡æ¿åº“
@@ -175,16 +172,7 @@
     */
    @Override
    public int deleteIvrTaskTemplateByIDs(Long[] IDs) {
        if (IDs[0] != null) {
            IvrTaskTemplate ivrTaskTemplate = selectIvrTaskTemplateByID(IDs[0]);
            if (StringUtils.isNotEmpty(ivrTaskTemplate.getLongTemp()) && ivrTaskTemplate.getLongTemp().equals("1")) {
                //如果这个模板是长期任务,则需要删除模板与部门的关联
                TemplateDept templateDept = new TemplateDept();
                templateDept.setType(21L);
                templateDept.setTempid(IDs[0]);
                templateDeptMapper.deleteTemplateDeptByTemplateId(templateDept);
            }
        }
        return ivrTaskTemplateMapper.deleteIvrTaskTemplateByIDs(IDs);
    }
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -127,17 +127,17 @@
    @Override
    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);
        }
//        // èŽ·å–å½“å‰ç™»é™†äººçš„éƒ¨é—¨æƒé™
//        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);
        return patMedRes;
    }
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
@@ -106,15 +106,15 @@
    @Override
    public PatMedRes selectPatMedOuthospCount(PatMedReq patMedReq) {
        // èŽ·å–å½“å‰ç™»é™†äººçš„éƒ¨é—¨æƒé™
        if (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);
        }
//        if (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);
//        }
        return patMedOuthospMapper.selectPatMedOuthospCount(patMedReq);
    }
smartor/src/main/java/com/smartor/service/impl/SchemeAutofinshruleServiceImpl.java
@@ -1,96 +1,90 @@
package com.ruoyi.smartor.service.impl;
package com.smartor.service.impl;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.smartor.domain.SchemeAutofinshrule;
import com.smartor.mapper.SchemeAutofinshruleMapper;
import com.smartor.service.ISchemeAutofinshruleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.smartor.mapper.SchemeAutofinshruleMapper;
import com.ruoyi.smartor.domain.SchemeAutofinshrule;
import com.ruoyi.smartor.service.ISchemeAutofinshruleService;
import java.util.List;
/**
 * æ–¹æ¡ˆç»“案规则Service业务层处理
 *
 *
 * @author smartor
 * @date 2023-03-04
 */
@Service
public class SchemeAutofinshruleServiceImpl implements ISchemeAutofinshruleService
{
public class SchemeAutofinshruleServiceImpl implements ISchemeAutofinshruleService {
    @Autowired
    private SchemeAutofinshruleMapper schemeAutofinshruleMapper;
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return æ–¹æ¡ˆç»“案规则
     */
    @Override
    public SchemeAutofinshrule selectSchemeAutofinshruleById(Long id)
    {
    public SchemeAutofinshrule selectSchemeAutofinshruleById(Long id) {
        return schemeAutofinshruleMapper.selectSchemeAutofinshruleById(id);
    }
    /**
     * æŸ¥è¯¢æ–¹æ¡ˆç»“案规则列表
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return æ–¹æ¡ˆç»“案规则
     */
    @Override
    public List<SchemeAutofinshrule> selectSchemeAutofinshruleList(SchemeAutofinshrule schemeAutofinshrule)
    {
    public List<SchemeAutofinshrule> selectSchemeAutofinshruleList(SchemeAutofinshrule schemeAutofinshrule) {
        return schemeAutofinshruleMapper.selectSchemeAutofinshruleList(schemeAutofinshrule);
    }
    /**
     * æ–°å¢žæ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
    @Override
    public int insertSchemeAutofinshrule(SchemeAutofinshrule schemeAutofinshrule)
    {
    public int insertSchemeAutofinshrule(SchemeAutofinshrule schemeAutofinshrule) {
        schemeAutofinshrule.setCreateTime(DateUtils.getNowDate());
        return schemeAutofinshruleMapper.insertSchemeAutofinshrule(schemeAutofinshrule);
    }
    /**
     * ä¿®æ”¹æ–¹æ¡ˆç»“案规则
     *
     *
     * @param schemeAutofinshrule æ–¹æ¡ˆç»“案规则
     * @return ç»“æžœ
     */
    @Override
    public int updateSchemeAutofinshrule(SchemeAutofinshrule schemeAutofinshrule)
    {
    public int updateSchemeAutofinshrule(SchemeAutofinshrule schemeAutofinshrule) {
        schemeAutofinshrule.setUpdateTime(DateUtils.getNowDate());
        return schemeAutofinshruleMapper.updateSchemeAutofinshrule(schemeAutofinshrule);
    }
    /**
     * æ‰¹é‡åˆ é™¤æ–¹æ¡ˆç»“案规则
     *
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ–¹æ¡ˆç»“案规则主键
     * @return ç»“æžœ
     */
    @Override
    public int deleteSchemeAutofinshruleByIds(Long[] ids)
    {
    public int deleteSchemeAutofinshruleByIds(Long[] ids) {
        return schemeAutofinshruleMapper.deleteSchemeAutofinshruleByIds(ids);
    }
    /**
     * åˆ é™¤æ–¹æ¡ˆç»“案规则信息
     *
     *
     * @param id æ–¹æ¡ˆç»“案规则主键
     * @return ç»“æžœ
     */
    @Override
    public int deleteSchemeAutofinshruleById(Long id)
    {
    public int deleteSchemeAutofinshruleById(Long id) {
        return schemeAutofinshruleMapper.deleteSchemeAutofinshruleById(id);
    }
}
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -1977,6 +1977,39 @@
        return serviceSubtaskStatistics;
    }
    /**
     * æœåŠ¡ç»Ÿè®¡æŸ¥è¯¢ - æŒ‰æ—¶é—´ç»´åº¦ç»Ÿè®¡å‡ºé™¢/门诊随访数据
     *
     * @param request ç»Ÿè®¡è¯·æ±‚参数
     * @return ç»Ÿè®¡ç»“果列表
     */
    @Override
    public List<ServiceStatisticsResponse> getServiceStatistics(ServiceStatisticsRequest request) {
        log.info("getServiceStatistics的入参为:{}", request);
        // å‚数校验
        if (request.getStartDate() == null || request.getEndDate() == null) {
            throw new IllegalArgumentException("开始日期和结束日期不能为空");
        }
        if (request.getStartDate().after(request.getEndDate())) {
            throw new IllegalArgumentException("开始日期不能晚于结束日期");
        }
        // å¦‚æžœtimeType为空,默认按天统计
        if (com.ruoyi.common.utils.StringUtils.isEmpty(request.getTimeType())) {
            request.setTimeType("day");
        }
        List<ServiceStatisticsResponse> result = serviceSubtaskMapper.getServiceStatistics(request);
        log.info("getServiceStatistics返回结果数量:{}", result.size());
        return result;
    }
    private ServiceSubtaskStatistic getStatistic(List<ServiceSubtask> serviceSubtaskList) {
        log.error("-------------serviceSubtaskList的值为:{}", serviceSubtaskList);
        ServiceSubtaskStatistic serviceSubtaskStatistic = new ServiceSubtaskStatistic();
smartor/src/main/java/com/smartor/service/impl/ServiceTaskServiceImpl.java
@@ -211,7 +211,7 @@
            info = wjInfo(serviceTask, patid, isFinish);
        } else {
            //宣教
            info = xjInfo(Long.valueOf(serviceTask.getLibtemplateid()), taskid, patid, isFinish);
            info = xjInfo(Long.valueOf(serviceTask.getTemplateid()), taskid, patid, isFinish);
        }
        SvyTaskTemplate svyTaskTemplate = svyTaskTemplateMapper.selectSvyTaskTemplateBySvyid(serviceTask.getTemplateid());
smartor/src/main/java/com/smartor/service/impl/SvyLibTemplateServiceImpl.java
@@ -33,8 +33,6 @@
    @Autowired
    private SvyLibTemplateTargetoptionMapper svyLibTemplateTargetoptionMapper;
    @Autowired
    private TemplateDeptMapper templateDeptMapper;
    @Autowired
    private SvyLibTemplateTagMapper svyLibTemplateTagMapper;
    @Autowired
    private Icd10AssociationMapper icd10AssociationMapper;
@@ -110,11 +108,6 @@
            //将题目放到问卷列表中
            svyLibTemplateVOS.get(i).setSvyTemplateLibScripts(svyLibTemplateScripts);
            //获取每个问卷对应的科室
            TemplateDept templateDept = new TemplateDept();
            templateDept.setTempid(svyLibTemplateVOS.get(i).getSvyid());
            List<TemplateDept> tempDetpRelevances = templateDeptMapper.selectTemplateDeptList(templateDept);
            svyLibTemplateVOS.get(i).setTempDetpRelevances(CollectionUtils.isNotEmpty(tempDetpRelevances) ? tempDetpRelevances : new ArrayList<>());
            //获取标签
            SvyLibTemplateTag svyLibTemplateTag = new SvyLibTemplateTag();
@@ -208,20 +201,6 @@
                    }
                }
            }
        }
        if (CollectionUtils.isNotEmpty(svyLibTemplate.getTempDetpRelevances())) {
            for (TemplateDept tempDetpRelevance : svyLibTemplate.getTempDetpRelevances()) {
                if (tempDetpRelevance.getId() == null) {
                    //新增
                    tempDetpRelevance.setTempid(svyLibTemplate.getSvyid());
                    tempDetpRelevance.setType(1L);
                    templateDeptMapper.insertTemplateDept(tempDetpRelevance);
                } else {
                    templateDeptMapper.updateTemplateDept(tempDetpRelevance);
                }
            }
        }
        //标签处理
smartor/src/main/resources/mapper/smartor/ExternallInfoMapper.xml
@@ -151,6 +151,7 @@
               DWMC,
               RYRQ,
               SFZH,
               YLDH,
               JDR
        from HIT.HF_RYJDXX
    </sql>
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
@@ -59,6 +59,7 @@
        <result property="medicareType" column="medicare_type"/>
        <result property="carePerson" column="care_person"/>
        <result property="casePersonAge" column="case_person_age"/>
        <result property="reservedPhone" column="reserved_phone"/>
    </resultMap>
@@ -117,6 +118,7 @@
        <result property="leavehospitaldistrictname" column="leavehospitaldistrictname"/>
        <result property="leavehospitaldistrictcode" column="leavehospitaldistrictcode"/>
        <result property="admitdate" column="admitdate"/>
        <result property="reservedPhone" column="reserved_phone"/>
    </resultMap>
    <sql id="selectPatArchiveVo">
@@ -143,6 +145,7 @@
               archivetime,
               archiveby,
               telcode,
               reserved_phone,
               relativetelcode,
               idcardtype,
               orgid,
@@ -198,6 +201,7 @@
            <if test="medicareType != null ">and medicare_type = #{medicareType}</if>
            <if test="carePerson != null ">and care_person = #{carePerson}</if>
            <if test="casePersonAge != null ">and case_person_age = #{casePersonAge}</if>
            <if test="reservedPhone != null ">and reserved_phone = #{reservedPhone}</if>
        </where>
    </select>
@@ -232,11 +236,13 @@
        a.income,
        a.medicare_type,
        a.care_person,
        a.reserved_phone,
        a.case_person_age
        from pat_archive a,pat_archivetag b ,base_tag c
        <where>
            a.del_flag=0 and
            a.id = b.patid and b.tagid = c.tagid
            <if test="reservedPhone != null ">and reserved_phone = #{reservedPhone}</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">and idcardno = #{idcardno}</if>
            <if test="telcode != null  and telcode != ''">and telcode = #{telcode}</if>
@@ -302,6 +308,7 @@
            <if test="medicareType != null ">medicare_type,</if>
            <if test="carePerson != null ">care_person,</if>
            <if test="casePersonAge != null ">case_person_age,</if>
            <if test="reservedPhone != null ">reserved_phone,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="patientno != null">#{patientno},</if>
@@ -349,6 +356,7 @@
            <if test="medicareType != null ">#{medicareType},</if>
            <if test="carePerson != null ">#{carePerson},</if>
            <if test="casePersonAge != null ">#{casePersonAge},</if>
            <if test="reservedPhone != null ">#{reservedPhone},</if>
        </trim>
    </insert>
@@ -356,14 +364,14 @@
        insert into
        pat_archive(name,viptype,sex,idcardno,birthdate,place_of_residence,age,age2,sourcefrom,archivetime,archiveby,telcode,relativetelcode,idcardtype,orgid,openid,dduserid,update_by,update_time
        ,create_by,create_time,isupload,upload_time,pattype,nation,birthplace,native_place,patientno,patid_his,sd_flag,age_unit,age_unit2,notrequired_flag,notrequiredreason,care_facilities,case_path,
        degree_of_education,marital_status,income,medicare_type,care_person,case_person_age)
        degree_of_education,marital_status,income,medicare_type,care_person,case_person_age,reserved_phone)
        values
        <foreach item="item" index="index" collection="list" separator=",">
            (#{item.name},#{item.viptype},#{item.sex},#{item.idcardno},#{item.birthdate},#{item.placeOfResidence},#{item.age},#{item.age2},#{item.sourcefrom},#{item.archivetime},#{item.archiveby}
            ,#{item.telcode},#{item.archiveby},#{item.idcardtype},#{item.orgid},#{item.openid},#{item.dduserid},#{item.updateBy},
            #{item.updateTime},#{item.createBy},#{item.createTime},#{item.isupload},#{item.uploadTime},#{item.pattype},#{item.nation},#{item.birthplace},#{item.nativePlace},#{item.patientno},
            #{item.patidHis},#{item.sdFlag},#{item.ageUnit},#{item.ageUnit2},#{item.notrequiredFlag},#{item.notrequiredreason}
            ,#{item.careFacilities},#{item.casePath},#{item.degreeOfEducation},#{item.maritalStatus},#{item.income},#{item.medicareType},#{item.carePerson},#{item.casePersonAge})
            ,#{item.careFacilities},#{item.casePath},#{item.degreeOfEducation},#{item.maritalStatus},#{item.income},#{item.medicareType},#{item.carePerson},#{item.casePersonAge},#{item.reservedPhone})
        </foreach>
    </insert>
@@ -394,9 +402,9 @@
            <if test="isupload != null">isupload = #{isupload},</if>
            <if test="uploadTime != null">upload_time = #{uploadTime},</if>
            <if test="viptype != null">viptype = #{viptype},</if>
            <if test="viptype != null">patientno = #{patientno},</if>
            <if test="viptype != null">patid_his = #{patidHis},</if>
            <if test="viptype != null">sd_flag = #{sdFlag},</if>
            <if test="patientno != null">patientno = #{patientno},</if>
            <if test="patidHis != null">patid_his = #{patidHis},</if>
            <if test="sdFlag != null">sd_flag = #{sdFlag},</if>
            <if test="ageUnit != null">age_unit = #{ageUnit},</if>
            <if test="ageUnit2 != null">age_unit2 = #{ageUnit2},</if>
            <if test="notrequiredFlag != null ">notrequired_flag = #{notrequiredFlag},</if>
@@ -409,6 +417,7 @@
            <if test="medicareType != null ">medicare_type = #{medicareType},</if>
            <if test="carePerson != null ">care_person = #{carePerson},</if>
            <if test="casePersonAge != null ">case_person_age = #{casePersonAge},</if>
            <if test="reservedPhone != null ">reserved_phone = #{reservedPhone},</if>
        </trim>
        where id = #{id}
    </update>
@@ -466,6 +475,7 @@
        a.upload_time,
        a.viptype,
        a.pattype,
        a.reserved_phone,
        COALESCE((
        SELECT string_agg(d.tagname, ', ')
        FROM pat_archivetag d
@@ -479,6 +489,7 @@
        LEFT JOIN pat_archivetag b ON a.id = b.patid AND b.del_flag = 0
        <where>
            a.del_flag = 0
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
            <if test="tagname != null  and tagname != ''">and b.tagname like concat('%', #{tagname}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">and a.idcardno = #{idcardno}</if>
@@ -539,6 +550,7 @@
        a.create_by,
        a.create_time,
        a.isupload,
        a.reserved_phone,
        a.upload_time,
        a.pattype,
        d.bed_no,
@@ -560,11 +572,11 @@
        pat_med_inhosp d
        JOIN pat_archive a ON a.id = d.patid
        LEFT JOIN ( SELECT patid, GROUP_CONCAT( tagname ) AS tagname FROM pat_archivetag where del_flag=0 GROUP BY patid
        ) t ON t.patid =
        d.patid
        ) t ON t.patid = d.patid
        <where>
            d.del_flag != 1
            AND a.del_flag != 1
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
            <if test="tagname != null  and tagname != ''">and t.tagname like concat('%', #{tagname}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">and a.idcardno = #{idcardno}</if>
@@ -614,14 +626,15 @@
                </foreach>
            </if>
            <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size()>0">
            <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size()>0 and deptcodes == null ">
                AND d.hospitaldistrictcode IN
                <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
                         close=")">
                    #{hospitaldistrictcode}
                </foreach>
            </if>
            <if test="deptcodes != null and deptcodes.size() > 0">
            <if test="deptcodes != null and deptcodes.size() > 0 and hospitaldistrictcodes == null">
                AND d.deptcode IN
                <foreach collection="deptcodes" item="deptcode" open="(" separator=","
                         close=")">
@@ -629,6 +642,20 @@
                </foreach>
            </if>
            <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size()>0 and deptcodes != null ">
                AND (d.hospitaldistrictcode IN
                <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
                         close=")">
                    #{hospitaldistrictcode}
                </foreach>
            </if>
            <if test="hospitaldistrictcodes != null and deptcodes != null and deptcodes.size() > 0">
                OR d.deptcode IN
                <foreach collection="deptcodes" item="deptcode" open="(" separator=","
                         close="))">
                    #{deptcode}
                </foreach>
            </if>
            <if test="patids != null">
                AND a.id NOT IN
@@ -685,8 +712,7 @@
        a.create_time,
        a.isupload,
        a.upload_time,
        d.leavehospitaldistrictcode AS leavehospitaldistrictcode,
        d.leavehospitaldistrictname AS leavehospitaldistrictname,
        a.reserved_phone,
        COALESCE((
        SELECT string_agg(dd.tagname, ', ')
        FROM pat_archivetag dd
@@ -701,6 +727,7 @@
        <where>
            d.del_flag != 1
            AND a.del_flag != 1
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="patid != null  and patid != ''">and a.id = #{patid}</if>
            <if test="tagname != null  and tagname != ''">and t.tagname like concat('%', #{tagname}, '%')</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
@@ -784,6 +811,7 @@
        a.create_time,
        a.isupload,
        a.upload_time,
        a.reserved_phone,
        COALESCE((
        SELECT string_agg(dd.tagname, ', ')
        FROM pat_archivetag dd
@@ -798,6 +826,7 @@
        <where>
            d.del_flag != 1
            AND a.del_flag != 1
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="patid != null  and patid != ''">and a.id = #{patid}</if>
            <if test="tagname != null  and tagname != ''">and t.tagname like concat('%', #{tagname}, '%')</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
@@ -880,6 +909,7 @@
        a.isupload,
        a.upload_time,
        a.pattype,
        a.reserved_phone,
        d.bed_no,
        d.starttime,
        d.endtime,
@@ -899,6 +929,7 @@
        <where>
            d.del_flag != 1
            AND a.del_flag != 1
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="name != null  and name != ''">AND a.name LIKE concat('%', #{name}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">AND a.idcardno = #{idcardno}</if>
            <if test="tagname != null  and tagname != ''">
@@ -925,8 +956,15 @@
            <if test="deptname != null and deptname != ''">AND d.deptname LIKE concat('%', #{deptname}, '%')</if>
            <if test="drname != null and drname != ''">AND d.drname LIKE concat('%',#{drname}, '%')</if>
            <if test="diagname != null and diagname != ''">AND d.diagname LIKE concat('%',#{diagname}, '%')</if>
            <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0">
            <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0 and leaveldeptcodes == null">
                AND d.leavehospitaldistrictcode IN
                <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
                         close=")">
                    #{leavehospitaldistrictcode}
                </foreach>
            </if>
            <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0 and leaveldeptcodes != null and leaveldeptcodes.size() > 0">
                AND (d.leavehospitaldistrictcode IN
                <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
                         close=")">
                    #{leavehospitaldistrictcode}
@@ -934,7 +972,7 @@
            </if>
            <if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0 and leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0">
                OR d.leaveldeptcode IN
                <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close=")">
                <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close="))">
                    #{leaveldeptcode}
                </foreach>
            </if>
@@ -1018,6 +1056,7 @@
        a.create_by,
        a.create_time,
        a.isupload,
        a.reserved_phone,
        a.upload_time,
        rt.tagname,
        ROW_NUMBER() OVER (PARTITION BY a.idcardno ORDER BY a.update_time DESC) AS rn,
@@ -1030,6 +1069,7 @@
            AND a.del_flag != 1
            AND d.admitdate >= CURRENT_DATE - INTERVAL '90 days' <!-- å¼ºçƒˆæŽ¨èåŠ æ—¶é—´é™åˆ¶ -->
            <if test="patid != null and patid != ''">AND a.id = #{patid}</if>
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="tagname != null and tagname != ''">AND rt.tagname LIKE concat('%', #{tagname}, '%')</if>
            <if test="name != null and name != ''">AND a.name LIKE concat('%', #{name}, '%')</if>
            <if test="idcardno != null and idcardno != ''">AND a.idcardno = #{idcardno}</if>
@@ -1129,6 +1169,7 @@
        a.create_time,
        a.isupload,
        a.upload_time,
        a.reserved_phone,
        COALESCE((
        SELECT string_agg(dd.tagname, ', ')
        FROM pat_archivetag dd
@@ -1144,6 +1185,7 @@
        <where>
            d.del_flag != 1
            AND a.del_flag != 1
            <if test="reservedPhone != null ">and a.reserved_phone = #{reservedPhone}</if>
            <if test="patid != null  and patid != ''">and a.id = #{patid}</if>
            <if test="tagname != null  and tagname != ''">and t.tagname like concat('%', #{tagname}, '%')</if>
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml
@@ -743,30 +743,70 @@
    </select>
    <select id="selectPatMedInhospCount" parameterType="com.smartor.domain.PatMedReq"
            resultType="com.smartor.domain.PatMedRes">
        SELECT SUM( rs ) AS rs,
        SUM( rc ) AS rc
        FROM (
        SELECT
        COUNT(1) AS rc,
        COUNT(DISTINCT patid) AS rs
        0 AS rs
        FROM
        pat_med_inhosp
        <where>
            del_flag=0
            <if test="orgid != null">
                AND orgid = #{orgid}
            </if>
            <if test="zy != null">
                and inhospstate=0
                and TO_DATE(starttime,'YYYY-MM-DD') &gt;= TO_DATE(#{startDate},'YYYY-MM-DD')
                and TO_DATE(starttime,'YYYY-MM-DD') &lt;= TO_DATE(#{endDate},'YYYY-MM-DD')
                and starttime &gt;= #{startDate}
                and starttime &gt;= #{endDate}
                <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 inhospstate=1
                and TO_DATE(endtime,'YYYY-MM-DD') &gt;= TO_DATE(#{startDate},'YYYY-MM-DD')
                and TO_DATE(endtime,'YYYY-MM-DD') &lt;= TO_DATE(#{endDate},'YYYY-MM-DD')
                and endtime &gt;= #{startDate}
                and endtime &lt;= #{endDate}
                <if test="deptcodeList != null   and deptcodeList.size() > 0">
                    and leaveldeptcode in
                    <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                        #{deptcode}
                    </foreach>
                </if>
            </if>
            <if test="deptcodeList != null">
        </where>
        union all
        select
        0 AS rc,
        count(1) AS rs
        FROM
        service_subtask
        <where>
            del_flag = 0
            and service_type=2
            <if test="orgid != null">
                AND orgid = #{orgid}
            </if>
            <if test="startDate != null">
                and visit_time &gt;= #{startDate}
            </if>
            <if test="endDate != null">
                and visit_time &lt;= #{endDate}
            </if>
            <if test="deptcodeList != null   and deptcodeList.size() > 0">
                and deptcode in
                <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                    #{deptcode}
                </foreach>
            </if>
        </where>
        ) AS combined_data
    </select>
    <select id="selectEndtimeMax" resultType="java.util.Date">
smartor/src/main/resources/mapper/smartor/PatMedOuthospMapper.xml
@@ -252,22 +252,55 @@
    <select id="selectPatMedOuthospCount" parameterType="com.smartor.domain.PatMedReq"
            resultType="com.smartor.domain.PatMedRes">
        SELECT SUM( rs ) AS rs,
        SUM( rc ) AS rc
        FROM (
        SELECT
        COUNT(id) AS rc,
        COUNT(DISTINCT patid) AS rs
        0 AS rs
        FROM
        pat_med_outhosp
        <where>
            del_flag=0
            and TO_DATE(admitdate,'YYYY-MM-DD') &gt;= TO_DATE(#{startDate},'YYYY-MM-DD')
            and TO_DATE(admitdate,'YYYY-MM-DD') &lt;= TO_DATE(#{endDate},'YYYY-MM-DD')
            <if test="deptcodeList != null">
            <if test="orgid != null">
                and orgid = #{orgid}
            </if>
            and admitdate &gt;= #{startDate}
            and admitdate &lt;= #{endDate}
            <if test="deptcodeList != null and deptcodeList.size()>0">
                and deptcode in
                <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                    #{deptcode}
                </foreach>
            </if>
        </where>
        union all
        select
        0 AS rc,
        count(1) AS rs
        FROM
        service_subtask
        <where>
            del_flag = 0
            and service_type=3
            <if test="orgid != null">
                and orgid = #{orgid}
            </if>
            <if test="startDate != null">
                and visit_time &gt;=#{startDate}
            </if>
            <if test="endDate != null">
                and visit_time &lt;= #{endDate}
            </if>
            <if test="deptcodeList != null and deptcodeList.size()>0">
                and deptcode in
                <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
                    #{deptcode}
                </foreach>
            </if>
        </where>
        ) AS combined_data
    </select>
    <select id="selectAdmitdateMax" resultType="java.util.Date">
smartor/src/main/resources/mapper/smartor/SchemeAutofinshruleMapper.xml
@@ -2,9 +2,9 @@
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.smartor.mapper.SchemeAutofinshruleMapper">
    <resultMap type="SchemeAutofinshrule" id="SchemeAutofinshruleResult">
<mapper namespace="com.smartor.mapper.SchemeAutofinshruleMapper">
    <resultMap type="com.smartor.domain.SchemeAutofinshrule" id="SchemeAutofinshruleResult">
        <result property="id"    column="id"    />
        <result property="schemeid"    column="schemeid"    />
        <result property="ruletype"    column="ruletype"    />
@@ -23,22 +23,22 @@
        select id, schemeid, ruletype, rulevalue, orgid, del_flag, create_by, create_time, update_by, update_time, isupload, upload_time from scheme_autofinshrule
    </sql>
    <select id="selectSchemeAutofinshruleList" parameterType="SchemeAutofinshrule" resultMap="SchemeAutofinshruleResult">
    <select id="selectSchemeAutofinshruleList" parameterType="com.smartor.domain.SchemeAutofinshrule" resultMap="SchemeAutofinshruleResult">
        <include refid="selectSchemeAutofinshruleVo"/>
        <where>
        <where>
            <if test="schemeid != null "> and schemeid = #{schemeid}</if>
            <if test="ruletype != null "> and ruletype = #{ruletype}</if>
            <if test="rulevalue != null  and rulevalue != ''"> and rulevalue = #{rulevalue}</if>
            <if test="orgid != null  and orgid != ''"> and orgid = #{orgid}</if>
        </where>
    </select>
    <select id="selectSchemeAutofinshruleById" parameterType="Long" resultMap="SchemeAutofinshruleResult">
        <include refid="selectSchemeAutofinshruleVo"/>
        where id = #{id}
    </select>
    <insert id="insertSchemeAutofinshrule" parameterType="SchemeAutofinshrule" useGeneratedKeys="true" keyProperty="id">
    <insert id="insertSchemeAutofinshrule" parameterType="com.smartor.domain.SchemeAutofinshrule" useGeneratedKeys="true" keyProperty="id">
        insert into scheme_autofinshrule
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="schemeid != null">schemeid,</if>
@@ -68,7 +68,7 @@
         </trim>
    </insert>
    <update id="updateSchemeAutofinshrule" parameterType="SchemeAutofinshrule">
    <update id="updateSchemeAutofinshrule" parameterType="com.smartor.domain.SchemeAutofinshrule">
        update scheme_autofinshrule
        <trim prefix="SET" suffixOverrides=",">
            <if test="schemeid != null">schemeid = #{schemeid},</if>
@@ -91,9 +91,9 @@
    </delete>
    <delete id="deleteSchemeAutofinshruleByIds" parameterType="String">
        delete from scheme_autofinshrule where id in
        delete from scheme_autofinshrule where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
</mapper>
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -74,6 +74,7 @@
        <result property="sendstate" column="sendstate"/>
        <result property="tagname" column="tagname"/>
        <result property="visitTime" column="visit_time"/>
        <result property="leavediagname" column="leavediagname"/>
    </resultMap>
    <resultMap type="com.smartor.domain.ServiceSubtaskCount" id="ServiceSubtaskResult2">
@@ -123,6 +124,7 @@
               recordid,
               exrecallcount,
               pulltime,
               leavediagname,
               deptcode,
               labelstatus,
               del_flag,
@@ -158,250 +160,160 @@
    <select id="selectServiceSubtaskList" parameterType="com.smartor.domain.ServiceSubtaskVO"
            resultMap="ServiceSubtaskResult">
        select a.id,
        a.hosp_type,
        a.suggest,
        a.sendstate,
        a.endtime,
        a.nurse_id,
        a.nurse_name,
        a.starttime,
        a.submit,
        a.inhospid,
        a.drname,
        a.excep,
        a.drcode,
        a.long_send_time,
        a.openid,
        a.remark,
        a.service_type,
        a.libtemplateid,
        a.libtemplatename,
        a.hospno,
        a.score,
        a.phone,
        a.sex,
        a.age,
        a.patid,
        a.sfzh,
        a.addr,
        a.senderdetail,
        a.type,
        a.taskid,
        a.templateid,
        a.templatename,
        a.senddate,
        a.senduuid,
        a.result,
        a.finishtime,
        a.recordid,
        a.exrecallcount,
        a.pulltime,
        a.deptcode,
        a.labelstatus,
        a.del_flag,
        a.update_by,
        a.update_time,
        a.create_by,
        a.create_time,
        a.isupload,
        a.upload_time,
        a.orgid,
        a.pid,
        a.guid,
        a.text_param,
        a.preachform,
        a.bed_no,
        a.send_type,
        a.task_name,
        a.task_desc,
        a.operator_no,
        a.operator,
        a.wechat,
        a.sendname,
        a.roomno,
        a.admindate,
        a.deptname,
        a.stop_state,
        a.visit_time,
        a.leavehospitaldistrictcode,
        a.leavehospitaldistrictname,
        a.diagname,
        COALESCE((
        SELECT string_agg(d.tagname, ', ')
        FROM pat_archivetag d
        WHERE d.patid = a.patid
        AND d.del_flag = 0
        ), '') AS tagname
        from service_subtask a
        LEFT JOIN pat_archivetag c ON c.patid = a.patid
        <include refid="selectServiceSubtaskVo"/>
        <where>
            a.del_flag=0
            -- and c.del_flag=0
            <if test="sendname != null  and sendname != ''">and a.sendname like concat('%', #{sendname}, '%')</if>
            <if test="tagname != null  and tagname != ''">and c.tagname like concat('%', #{tagname}, '%')</if>
            del_flag=0
            <if test="sendname != null  and sendname != ''">and sendname like concat('%', #{sendname}, '%')</if>
            <if test="phone != null  and phone != ''">and phone = #{phone}</if>
            <if test="leavehospitaldistrictcode != null  and leavehospitaldistrictcode != ''">and
                a.leavehospitaldistrictcode = #{leavehospitaldistrictcode}
                leavehospitaldistrictcode = #{leavehospitaldistrictcode}
            </if>
            <if test="leavehospitaldistrictname != null  and leavehospitaldistrictname != ''">and
                a.leavehospitaldistrictname = #{leavehospitaldistrictname}
                leavehospitaldistrictname = #{leavehospitaldistrictname}
            </if>
            <if test="sex != null  and sex != ''">and a.sex = #{sex}</if>
            <if test="age != null ">and a.age = #{age}</if>
            <if test="submit != null ">and a.submit = #{submit}</if>
            <if test="serviceType != null ">and a.service_type = #{serviceType}</if>
            <if test="patid != null ">and a.patid = #{patid}</if>
            <if test="sfzh != null  and sfzh != ''">and a.sfzh = #{sfzh}</if>
            <if test="addr != null  and addr != ''">and a.addr = #{addr}</if>
            <if test="senderdetail != null  and senderdetail != ''">and a.senderdetail = #{senderdetail}</if>
            <if test="type != null  and type != ''">and a.type = #{type}</if>
            <if test="taskid != null ">and a.taskid = #{taskid}</if>
            <if test="templateid != null  and templateid != ''">and a.templateid = #{templateid}</if>
            <if test="templatename != null  and templatename != ''">and a.templatename like concat('%', #{templatename},
            <if test="leavediagname != null  and leavediagname != ''">and leavediagname like concat('%',
                #{leavediagname}, '%')
            </if>
            <if test="sex != null  and sex != ''">and sex = #{sex}</if>
            <if test="age != null ">and age = #{age}</if>
            <if test="patguid != null ">and patguid = #{patguid}</if>
            <if test="subId != null ">and id = #{subId}</if>
            <if test="inhospid != null ">and inhospid = #{inhospid}</if>
            <if test="submit != null ">and submit = #{submit}</if>
            <if test="upid != null ">and upid = #{upid}</if>
            <if test="patfrom != null ">and patfrom = #{patfrom}</if>
            <if test="serviceType != null ">and service_type = #{serviceType}</if>
            <if test="patid != null ">and patid = #{patid}</if>
            <if test="sfzh != null  and sfzh != ''">and sfzh = #{sfzh}</if>
            <if test="addr != null  and addr != ''">and addr = #{addr}</if>
            <if test="senderdetail != null  and senderdetail != ''">and senderdetail = #{senderdetail}</if>
            <if test="type != null  and type != ''">and type = #{type}</if>
            <if test="taskid != null ">and taskid = #{taskid}</if>
            <if test="templateid != null  and templateid != ''">and templateid = #{templateid}</if>
            <if test="templatename != null  and templatename != ''">and templatename like concat('%', #{templatename},
                '%')
            </if>
            <if test="startOutHospTime != null">
                AND TO_DATE( a.endtime,'YYYY-MM-DD') &gt;= TO_DATE(#{startOutHospTime},'YYYY-MM-DD')
                AND to_char(endtime, 'YYMMDD') &gt;= to_char(#{startOutHospTime}::timestamp, 'YYMMDD')
            </if>
            <if test="endOutHospTime != null">
                AND TO_DATE( a.endtime,'YYYY-MM-DD') &lt;= TO_DATE(#{endOutHospTime},'YYYY-MM-DD')
                AND to_char(endtime, 'YYMMDD') &lt;= to_char(#{endOutHospTime}::timestamp, 'YYMMDD')
            </if>
            <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
                AND a.leavehospitaldistrictcode IN
                <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
                         close=")">
                    #{leavehospitaldistrictcode}
                </foreach>
            <if test="startSendDateTime != null">
                AND to_char(long_send_time, 'YYMMDD') >= to_char(#{startSendDateTime}::timestamp, 'YYMMDD')
            </if>
            <if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0">
                AND a.deptcode IN
                <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
                         close=")">
                    #{leaveldeptcode}
                </foreach>
            <if test="endSendDateTime != null">
                AND to_char(long_send_time, 'YYMMDD') &lt;= to_char(#{endSendDateTime}::timestamp, 'YYMMDD')
            </if>
            <if test="longSendTime != null">
                AND to_char(long_send_time, 'YYMMDD') &lt;= to_char(#{longSendTime}::timestamp, 'YYMMDD')
            </if>
            <if test="deptOrDistrict==1">
                <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
                    AND leavehospitaldistrictcode IN
                    <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
                             separator=","
                             close=")">
                        #{leavehospitaldistrictcode}
                    </foreach>
                </if>
                <if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0">
                    AND deptcode IN
                    <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
                             close=")">
                        #{leaveldeptcode}
                    </foreach>
                </if>
            </if>
            <if test="deptOrDistrict==2">
                <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
                    AND (leavehospitaldistrictcode IN
                    <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
                             separator=","
                             close=")">
                        #{leavehospitaldistrictcode}
                    </foreach>
                </if>
                <if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0">
                    OR deptcode IN
                    <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
                             close="))">
                        #{leaveldeptcode}
                    </foreach>
                </if>
            </if>
            <if test="senddate != null ">and a.senddate = #{senddate}</if>
            <if test="senduuid != null  and senduuid != ''">and a.senduuid = #{senduuid}</if>
            <if test="result != null  and result != ''">and a.result = #{result}</if>
            <if test="finishtime != null ">and a.finishtime = #{finishtime}</if>
            <if test="recordid != null ">and a.recordid = #{recordid}</if>
            <if test="exrecallcount != null ">and a.exrecallcount = #{exrecallcount}</if>
            <if test="pulltime != null ">and a.pulltime = #{pulltime}</if>
            <if test="deptcode != null  and deptcode != ''">and a.deptcode = #{deptcode}</if>
            <if test="deptname != null  and deptname != ''">and a.deptname = #{deptname}</if>
            <if test="labelstatus != null ">and a.labelstatus = #{labelstatus}</if>
            <if test="isupload != null ">and a.isupload = #{isupload}</if>
            <if test="uploadTime != null ">and a.upload_time = #{uploadTime}</if>
            <if test="orgid != null  and orgid != ''">and a.orgid = #{orgid}</if>
            <if test="pid != null ">and a.pid = #{pid}</if>
            <if test="inhospid != null ">and a.inhospid = #{inhospid}</if>
            <if test="preachform != null ">and a.preachform = #{preachform}</if>
            <if test="guid != null  and guid != ''">and a.guid = #{guid}</if>
            <if test="textParam != null  and textParam != ''">and a.text_param = #{textParam}</if>
            <if test="bedNo != null">and a.bed_no = #{bedNo}</if>
            <if test="sendType != null  and sendType != ''">and a.send_type = #{sendType}</if>
            <if test="operator != null  and operator != ''">and a.operator = #{operator}</if>
            <if test="operatorNo != null  and operatorNo != ''">and a.operator_no = #{operatorNo}</if>
            <if test="wechat != null  and wechat != ''">and a.wechat = #{wechat}</if>
            <if test="hospType != null  and hospType != ''">and a.hosp_type = #{hospType}</if>
            <if test="libtemplateid != null ">and a.libtemplateid = #{libtemplateid}</if>
            <if test="libtemplatename != null ">and a.libtemplatename = #{libtemplatename}</if>
            <if test="openid != null ">and a.openid = #{openid}</if>
            <if test="longSendTime != null ">and a.long_send_time = #{longSendTime}</if>
            <if test="sendstate != null ">and a.sendstate = #{sendstate}</if>
            <if test="drname != null  and drname != ''">and a.drname like concat('%', #{drname}, '%')</if>
            <if test="drcode != null ">and a.drcode = #{drcode}</if>
            <if test="starttime != null ">and a.starttime = #{starttime}</if>
            <if test="endtime != null ">and a.endtime = #{endtime}</if>
            <if test="excep != null ">and a.excep = #{excep}</if>
            <if test="nurseId != null ">and a.nurse_id = #{nurseId}</if>
            <if test="nurseName != null ">and a.nurse_name = #{nurseName}</if>
            <if test="score != null">and a.score = #{score}</if>
            <if test="remark != null">and a.remark = #{remark}</if>
            <if test="suggest != null">and a.suggest = #{suggest}</if>
            <if test="createBy != null">and a.create_by = #{createBy}</if>
            <if test="visitTime != null">and a.visit_time = #{visitTime}</if>
            <if test="senddate != null ">and senddate = #{senddate}</if>
            <if test="senduuid != null  and senduuid != ''">and senduuid = #{senduuid}</if>
            <if test="result != null  and result != ''">and result = #{result}</if>
            <if test="finishtime != null ">and finishtime = #{finishtime}</if>
            <if test="recordid != null ">and recordid = #{recordid}</if>
            <if test="exrecallcount != null ">and exrecallcount = #{exrecallcount}</if>
            <if test="pulltime != null ">and pulltime = #{pulltime}</if>
            <if test="deptcode != null  and deptcode != ''">and deptcode = #{deptcode}</if>
            <if test="deptname != null  and deptname != ''">and deptname = #{deptname}</if>
            <if test="labelstatus != null ">and labelstatus = #{labelstatus}</if>
            <if test="isupload != null ">and isupload = #{isupload}</if>
            <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
            <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
            <if test="pid != null ">and pid = #{pid}</if>
            <if test="preachform != null ">and preachform = #{preachform}</if>
            <if test="guid != null  and guid != ''">and guid = #{guid}</if>
            <if test="textParam != null  and textParam != ''">and text_param = #{textParam}</if>
            <if test="bedNo != null">and bed_no = #{bedNo}</if>
            <if test="sendType != null  and sendType != ''">and send_type = #{sendType}</if>
            <if test="operator != null  and operator != ''">and operator = #{operator}</if>
            <if test="operatorNo != null  and operatorNo != ''">and operator_no = #{operatorNo}</if>
            <if test="wechat != null  and wechat != ''">and wechat = #{wechat}</if>
            <if test="hospType != null  and hospType != ''">and hosp_type = #{hospType}</if>
            <if test="libtemplateid != null ">and libtemplateid = #{libtemplateid}</if>
            <if test="libtemplatename != null ">and libtemplatename = #{libtemplatename}</if>
            <if test="openid != null ">and openid = #{openid}</if>
            <if test="longSendTime != null ">and long_send_time = #{longSendTime}</if>
            <if test="sendstate != null ">and sendstate = #{sendstate}</if>
            <if test="drname != null  and drname != ''">and drname like concat('%', #{drname}, '%')</if>
            <if test="taskName != null  and taskName != ''">and task_name like concat('%', #{taskName}, '%')</if>
            <if test="drcode != null and drcode != ''">and (drcode = #{drcode}</if>
            <if test="nurseId != null  and nurseId != ''">or nurse_id = #{nurseId})</if>
            <if test="starttime != null ">and starttime = #{starttime}</if>
            <if test="endtime != null ">and endtime = #{endtime}</if>
            <if test="excep != null ">and excep = #{excep}</if>
            <if test="nurseName != null ">and nurse_name = #{nurseName}</if>
            <if test="score != null">and score = #{score}</if>
            <!--            <if test="visitCount != null">and visit_count = #{visitCount}</if>-->
            <if test="visitCount != null and visitCount == 1">
                AND visit_count = 1
            </if>
            <if test="visitCount != null and visitCount > 1">
                AND visit_count > 1
            </if>
            <if test="remark != null">and remark = #{remark}</if>
            <if test="suggest != null">and suggest = #{suggest}</if>
            <if test="createBy != null">and create_by = #{createBy}</if>
            <if test="taskGuid != null">and task_guid = #{taskGuid}</if>
            <if test="isVisitAgain != null">and is_visit_again = #{isVisitAgain}</if>
            <if test="visitTime != null">and visit_time = #{visitTime}</if>
            <!--<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
            <if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>-->
            <if test="visitCount != null and visitCount > 1 and visitDeptCodes != null and visitDeptCodes.size() > 0">
                AND visit_dept_code IN
                <foreach collection="visitDeptCodes" item="visitDeptCodes" open="("
                         separator=","
                         close=")">
                    #{visitDeptCodes}
                </foreach>
            </if>
        </where>
        GROUP BY a.id,
        a.hosp_type,
        a.suggest,
        a.sendstate,
        a.endtime,
        a.nurse_id,
        a.nurse_name,
        a.starttime,
        a.submit,
        a.inhospid,
        a.drname,
        a.excep,
        a.drcode,
        a.long_send_time,
        a.openid,
        a.remark,
        a.service_type,
        a.libtemplateid,
        a.libtemplatename,
        a.hospno,
        a.score,
        a.phone,
        a.sex,
        a.age,
        a.patid,
        a.sfzh,
        a.addr,
        a.senderdetail,
        a.type,
        a.taskid,
        a.templateid,
        a.templatename,
        a.senddate,
        a.visit_time,
        a.senduuid,
        a.result,
        a.finishtime,
        a.recordid,
        a.exrecallcount,
        a.pulltime,
        a.deptcode,
        a.labelstatus,
        a.del_flag,
        a.update_by,
        a.update_time,
        a.create_by,
        a.create_time,
        a.isupload,
        a.upload_time,
        a.orgid,
        a.pid,
        a.guid,
        a.text_param,
        a.preachform,
        a.bed_no,
        a.send_type,
        a.task_name,
        a.task_desc,
        a.operator_no,
        a.operator,
        a.wechat,
        a.sendname,
        a.roomno,
        a.admindate,
        a.deptname,
        a.stop_state,
        a.leavehospitaldistrictcode,
        a.leavehospitaldistrictname,
        a.diagname
        order by a.visit_time desc
        <if test="serviceType != null  and serviceType != ''and serviceType != '2'and serviceType != '3'">
            ,a.long_send_time desc
        </if>
        <if test="serviceType != null  and serviceType != ''and serviceType == '2'">,a.endtime desc</if>
        <if test="serviceType != null  and serviceType != ''and serviceType == '3'">,a.admindate desc</if>
        <if test="sort != null  and sort==0">order by endtime asc</if>
        <if test="sort != null  and sort==1">order by endtime desc</if>
        <if test="sort != null  and sort==2">order by long_send_time asc</if>
        <if test="sort != null  and sort==3">order by long_send_time desc</if>
        <if test="sort != null  and sort==5">order by admindate asc</if>
        <if test="sort != null  and sort==6">order by admindate desc</if>
        <!-- order by update_time desc,id desc -->
    </select>
    <select id="selectServiceSubtaskById" parameterType="Long" resultMap="ServiceSubtaskResult">
        <include refid="selectServiceSubtaskVo"/>
@@ -491,6 +403,7 @@
            <if test="sendstate != null ">sendstate,</if>
            <if test="inhospid != null ">inhospid,</if>
            <if test="visitTime != null ">visit_time,</if>
            <if test="leavediagname != null ">leavediagname,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="sendname != null">#{sendname},</if>
@@ -563,6 +476,7 @@
            <if test="sendstate != null ">#{sendstate},</if>
            <if test="inhospid != null ">#{inhospid},</if>
            <if test="visitTime != null ">#{visitTime},</if>
            <if test="leavediagname != null ">#{leavediagname},</if>
        </trim>
    </insert>
@@ -639,6 +553,7 @@
            <if test="suggest != null ">suggest=#{suggest},</if>
            <if test="inhospid != null ">inhospid=#{inhospid},</if>
            <if test="visitTime != null ">visit_time=#{visitTime},</if>
            <if test="leavediagname != null ">leavediagname=#{leavediagname},</if>
        </trim>
        where id = #{id}
    </update>
@@ -721,6 +636,7 @@
        <where>
            <if test="patid != null ">patid=#{patid}</if>
            <if test="taskid != null ">and taskid=#{taskid}</if>
            <if test="leavediagname != null ">and leavediagname=#{leavediagname}</if>
        </where>
    </update>
@@ -797,6 +713,7 @@
            <if test="suggest != null ">suggest=#{suggest},</if>
            <if test="inhospid != null ">inhospid=#{inhospid},</if>
            <if test="visitTime != null ">visit_time=#{visitTime},</if>
            <if test="leavediagname != null ">leavediagname=#{leavediagname},</if>
        </trim>
        where patid = #{patid} and taskid = #{taskid}
    </update>
@@ -908,6 +825,7 @@
               nurse_name,
               remark,
               visit_time,
               leavediagname,
               diagname
        FROM service_subtask,
             JSON_TABLE(send_time_slot, '$[*]' COLUMNS (
@@ -922,7 +840,7 @@
    <!--    èŽ·å–éšè®¿é—¨è¯Šæ¯æœˆçš„æ•°é‡-->
    <select id="getSfFzInfoEveryMonth" parameterType="com.smartor.domain.ServiceSubtaskCountReq"
            resultMap="ServiceSubtaskResult2">
        SELECT TO_DATE(st.finishtime, '%Y-%m') AS month,
        SELECT to_char(st.finishtime, 'YYYY-MM') AS month,
              st.service_type as service_type,
              st.id as subTaskId,
    COUNT(*) AS count
@@ -934,14 +852,236 @@
        WHERE
            dd.user_id =#{userId}
          AND st.finishtime IS NOT NULL
          and TO_DATE(st.finishtime
            , '%Y-%m') &gt;= #{startTime}
          and TO_DATE(st.finishtime
            , '%Y-%m') &lt;= #{endTime}
          and to_char(st.finishtime
            , 'YYYY-MM') &gt;= #{startTime}
          and to_char(st.finishtime
            , 'YYYY-MM') &lt;= #{endTime}
        GROUP BY
            month, st.service_type, st.id
        ORDER BY
            month, st.service_type, st.id;
    </select>
    <!-- æœåŠ¡ç»Ÿè®¡æŸ¥è¯¢ - æŒ‰æ—¶é—´ç»´åº¦ç»Ÿè®¡å‡ºé™¢/门诊随访数据 -->
    <select id="getServiceStatistics" parameterType="com.smartor.domain.ServiceStatisticsRequest"
            resultType="com.smartor.domain.ServiceStatisticsResponse">
        SELECT
        timePeriod,
        SUM(dischargeFollowCount) AS dischargeFollowCount,
        SUM(outpatientFollowCount) AS outpatientFollowCount,
        SUM(pmiCount) AS pmiCount,
        SUM(pmoCount) AS pmoCount
        FROM (
        -- éšè®¿æ•°æ®
        SELECT
        <choose>
            <when test="timeType == 'day'">
                to_char(visit_time, 'YYYY-MM-DD') AS timePeriod,
            </when>
            <when test="timeType == 'month'">
                to_char(visit_time, 'YYYY-MM') AS timePeriod,
            </when>
            <when test="timeType == 'year'">
                to_char(visit_time, 'YYYY') AS timePeriod,
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(visit_time), '-W', LPAD(WEEK(visit_time, 1), 2, '0')) AS timePeriod,
            </when>
            <otherwise>
                to_char(visit_time, 'YYYY-MM-DD') AS timePeriod,
            </otherwise>
        </choose>
        COUNT(CASE WHEN service_type = '2' THEN 1 END) AS dischargeFollowCount,
        COUNT(CASE WHEN service_type = '3' THEN 1 END) AS outpatientFollowCount,
        0 AS pmiCount,
        0 AS pmoCount
        FROM service_subtask
        WHERE
        del_flag = '0'
        <if test="startDate != null and endDate != null">
            AND  visit_time  &gt;=  #{startDate}
            AND  visit_time  &lt;=  #{endDate}
        </if>
        <if test="orgid != null">
            AND orgid = #{orgid}
        </if>
        <if test="deptcodes != null and deptcodes.size() > 0">
            AND deptcode IN
            <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
            AND leavehospitaldistrictcode IN
            <foreach collection="leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")">
                #{districtcode}
            </foreach>
        </if>
        <if test="serviceTypes != null and serviceTypes.size() > 0">
            AND service_type IN
            <foreach collection="serviceTypes" item="serviceType" open="(" separator="," close=")">
                #{serviceType}
            </foreach>
        </if>
        GROUP BY
        <choose>
            <when test="timeType == 'day'">
                to_char(visit_time, 'YYYY-MM-DD')
            </when>
            <when test="timeType == 'month'">
                to_char(visit_time, 'YYYY-MM')
            </when>
            <when test="timeType == 'year'">
                to_char(visit_time, 'YYYY')
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(visit_time), '-W', LPAD(WEEK(visit_time, 1), 2, '0'))
            </when>
            <otherwise>
                to_char(visit_time, 'YYYY-MM-DD')
            </otherwise>
        </choose>
        UNION ALL
        -- å‡ºé™¢äººæ¬¡æ•°æ®
        SELECT
        <choose>
            <when test="timeType == 'day'">
                to_char(endtime, 'YYYY-MM-DD') AS timePeriod,
            </when>
            <when test="timeType == 'month'">
                to_char(endtime, 'YYYY-MM') AS timePeriod,
            </when>
            <when test="timeType == 'year'">
                to_char(endtime, 'YYYY') AS timePeriod,
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(endtime), '-W', LPAD(WEEK(endtime, 1), 2, '0')) AS timePeriod,
            </when>
            <otherwise>
                to_char(endtime, 'YYYY-MM-DD') AS timePeriod,
            </otherwise>
        </choose>
        0 AS dischargeFollowCount,
        0 AS outpatientFollowCount,
        COUNT( patid) AS pmiCount,
        0 AS pmoCount
        FROM pat_med_inhosp
        WHERE del_flag = '0'
        <if test="startDate != null and endDate != null">
            AND endtime  &gt;=  #{startDate}
            AND  endtime  &lt;=  #{endDate}
        </if>
        AND inhospstate=1
        <if test="orgid != null">
            AND orgid = #{orgid}
        </if>
        <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
            AND leavehospitaldistrictcode IN
            <foreach collection="leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")">
                #{districtcode}
            </foreach>
        </if>
        <if test="deptcodes != null and deptcodes.size() > 0">
            AND leaveldeptcode IN
            <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        GROUP BY
        <choose>
            <when test="timeType == 'day'">
                to_char(endtime, 'YYYY-MM-DD')
            </when>
            <when test="timeType == 'month'">
                to_char(endtime, 'YYYY-MM')
            </when>
            <when test="timeType == 'year'">
                to_char(endtime, 'YYYY')
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(endtime), '-W', LPAD(WEEK(endtime, 1), 2, '0'))
            </when>
            <otherwise>
                to_char(endtime, 'YYYY-MM-DD')
            </otherwise>
        </choose>
        UNION ALL
        -- é—¨è¯Šäººæ¬¡æ•°æ®
        SELECT
        <choose>
            <when test="timeType == 'day'">
                to_char(admitdate, 'YYYY-MM-DD') AS timePeriod,
            </when>
            <when test="timeType == 'month'">
                to_char(admitdate, 'YYYY-MM') AS timePeriod,
            </when>
            <when test="timeType == 'year'">
                to_char(admitdate, 'YYYY') AS timePeriod,
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(admitdate), '-W', LPAD(WEEK(admitdate, 1), 2, '0')) AS timePeriod,
            </when>
            <otherwise>
                to_char(admitdate, 'YYYY-MM-DD') AS timePeriod,
            </otherwise>
        </choose>
        0 AS dischargeFollowCount,
        0 AS outpatientFollowCount,
        0 AS pmiCount,
        COUNT( patid) AS pmoCount
        FROM pat_med_outhosp
        WHERE del_flag = '0'
        <if test="startDate != null and endDate != null">
            AND admitdate &gt;= #{startDate}
            AND admitdate &lt;= #{endDate}
        </if>
        <if test="orgid != null">
            AND orgid = #{orgid}
        </if>
        <if test="deptcodes != null and deptcodes.size() > 0">
            AND deptcode IN
            <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
                #{deptcode}
            </foreach>
        </if>
        GROUP BY
        <choose>
            <when test="timeType == 'day'">
                to_char(admitdate, 'YYYY-MM-DD')
            </when>
            <when test="timeType == 'month'">
                to_char(admitdate, 'YYYY-MM')
            </when>
            <when test="timeType == 'year'">
                to_char(admitdate, 'YYYY')
            </when>
            <when test="timeType == 'week'">
                CONCAT(YEAR(admitdate), '-W', LPAD(WEEK(admitdate, 1), 2, '0'))
            </when>
            <otherwise>
                to_char(admitdate, 'YYYY-MM-DD')
            </otherwise>
        </choose>
        ) AS combined_data
        GROUP BY timePeriod
        ORDER BY timePeriod DESC
    </select>
</mapper>