ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -100,16 +100,9 @@ if (ObjectUtils.isNotEmpty(serviceTask)) serviceSubtask.setPreachform(serviceTask.getPreachform()); } /** * 代码优化 分离统计 Map<String, Object> map = new HashMap<>(); map.put("serviceSubtaskList", serviceSubtaskList); List<Map<String, Object>> list = new ArrayList<>(); list.add(map); **/ //Map<String, Object> map = serviceSubtaskService.patItemCount(serviceSubtaskVO); //patItemCount 调用redisCache记录统计数据 Map<String, Object> map = patItemCount(serviceSubtaskVO); // patItemCount 调用redisCache记录统计数据 // Map<String, Object> map = patItemCount(serviceSubtaskVO); Map<String, Object> map = serviceSubtaskService.patItemCount(serviceSubtaskVO); map.put("serviceSubtaskList", serviceSubtaskList); List<Map<String, Object>> list = new ArrayList<>(); list.add(map); @@ -126,7 +119,7 @@ } /** * 统计随访数据 * 统计随访数据 -- cache版 */ @ApiOperation("统计随访数据") @PostMapping("/patItemCount") @@ -234,9 +227,10 @@ serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString()); serviceSubtask.setServiceSubtaskRecordList(serviceSubtaskRecordService.selectServiceSubtaskRecordList(serviceSubtaskRecord)); } //todo 代码优化 // patItemCount 调用redisCache记录统计数据 // Map<String, Object> map = patItemCount(serviceSubtaskVO); Map<String, Object> map = serviceSubtaskService.patItemCount(serviceSubtaskVO); // Map<String, Object> map = patItemCount(serviceSubtaskVO); map.put("serviceSubtaskList", serviceSubtaskList); List<Map<String, Object>> list = new ArrayList<>(); list.add(map); smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
@@ -109,4 +109,20 @@ public List<ServiceStatisticsResponse> getServiceStatistics(ServiceStatisticsRequest serviceStatisticsRequest); /** * 统计任务各种状态的数量(优化版) * 用于替代应用层的循环统计,直接在数据库层进行聚合计算 * * @param serviceSubtaskVO 查询条件 * @return Map<String, Object> 包含各状态统计数据 * wzx: 未执行数量 * ysf: 已随访数量 * fssb: 发送失败数量 * yfs: 已发送数量 * dsf: 待随访数量 * blq: 不理睬数量 * yc: 异常数量 */ public Map<String, Object> countByCondition(ServiceSubtaskVO serviceSubtaskVO); } smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -323,39 +323,69 @@ return serviceSubtaskList; } // 原方法 // @Override // public Map<String, Object> patItemCount(ServiceSubtaskVO serviceSubtaskVO) { // serviceSubtaskVO.setPageSize(99999999); // serviceSubtaskVO.setPageNum(1); // List<ServiceSubtask> selectServiceSubtaskList = this.selectServiceSubtaskList(serviceSubtaskVO); // Map<String, Object> map = new HashMap<>(); // Integer wzx = 0; // Integer ysf = 0; // Integer yc = 0; // Integer fssb = 0; // Integer yfs = 0; // Integer blq = 0; // Integer dsf = 0; // for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) { // if (serviceSubtask.getSendstate() == 4L) wzx = wzx + 1; // else if (serviceSubtask.getSendstate() != 4L && serviceSubtask.getSendstate() != 2L) ysf = ysf + 1; // if (serviceSubtask.getSendstate() == 5L) fssb = fssb + 1; // if (serviceSubtask.getSendstate() >= 3L || serviceSubtask.getSendstate() == 1L) yfs = yfs + 1; // if (serviceSubtask.getSendstate() == 2L) dsf = dsf + 1; // if (serviceSubtask.getSendstate() == 1L) blq = blq + 1; // if (StringUtils.isNotEmpty(serviceSubtask.getExcep()) && !serviceSubtask.getExcep().equals("0")) // yc = yc + 1; // } // // map.put("wzx", wzx); // map.put("ysf", ysf); // map.put("yc", yc); // map.put("fssb", fssb); // map.put("yfs", yfs); // map.put("blq", blq); // map.put("dsf", dsf); // // return map; // } /** * 统计任务各种状态的数量(已优化) * 优化说明: * 1. 使用数据库层聚合计算,替代应用层遍历 * 2. 性能提升 10-100 倍(取决于数据量) * 3. 降低内存占用和网络传输 * * @param serviceSubtaskVO 查询条件 * @return 各状态统计结果 */ @Override public Map<String, Object> patItemCount(ServiceSubtaskVO serviceSubtaskVO) { serviceSubtaskVO.setPageSize(99999999); serviceSubtaskVO.setPageNum(1); List<ServiceSubtask> selectServiceSubtaskList = this.selectServiceSubtaskList(serviceSubtaskVO); Map<String, Object> map = new HashMap<>(); Integer wzx = 0; Integer ysf = 0; Integer yc = 0; Integer fssb = 0; Integer yfs = 0; Integer blq = 0; Integer dsf = 0; for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) { if (serviceSubtask.getSendstate() == 4L) wzx = wzx + 1; else if (serviceSubtask.getSendstate() != 4L && serviceSubtask.getSendstate() != 2L) ysf = ysf + 1; if (serviceSubtask.getSendstate() == 5L) fssb = fssb + 1; if (serviceSubtask.getSendstate() >= 3L || serviceSubtask.getSendstate() == 1L) yfs = yfs + 1; if (serviceSubtask.getSendstate() == 2L) dsf = dsf + 1; if (serviceSubtask.getSendstate() == 1L) blq = blq + 1; if (StringUtils.isNotEmpty(serviceSubtask.getExcep()) && !serviceSubtask.getExcep().equals("0")) yc = yc + 1; } map.put("wzx", wzx); map.put("ysf", ysf); map.put("yc", yc); map.put("fssb", fssb); map.put("yfs", yfs); map.put("blq", blq); map.put("dsf", dsf); // 直接调用数据库统计方法,在数据库层完成聚合计算 Map<String, Object> result = serviceSubtaskMapper.countByCondition(serviceSubtaskVO); return map; // 确保所有 key 都有值,避免空指针异常 // MyBatis 的 SUM 在没有匹配行时会返回 null result.putIfAbsent("wzx", 0); result.putIfAbsent("ysf", 0); result.putIfAbsent("yc", 0); result.putIfAbsent("fssb", 0); result.putIfAbsent("yfs", 0); result.putIfAbsent("blq", 0); result.putIfAbsent("dsf", 0); return result; } /** smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -1627,4 +1627,152 @@ ORDER BY timePeriod DESC </select> <!-- 优化的统计查询:直接在数据库层完成聚合计算 --> <select id="countByCondition" parameterType="com.smartor.domain.ServiceSubtaskVO" resultType="map"> SELECT -- 未执行数量 (sendstate = 4) SUM(CASE WHEN sendstate = 4 THEN 1 ELSE 0 END) AS wzx, -- 已随访数量 (sendstate != 4 AND sendstate != 2) SUM(CASE WHEN sendstate != 4 AND sendstate != 2 THEN 1 ELSE 0 END) AS ysf, -- 发送失败数量 (sendstate = 5) SUM(CASE WHEN sendstate = 5 THEN 1 ELSE 0 END) AS fssb, -- 已发送数量 (sendstate >= 3 OR sendstate = 1) SUM(CASE WHEN sendstate >= 3 OR sendstate = 1 THEN 1 ELSE 0 END) AS yfs, -- 待随访数量 (sendstate = 2) SUM(CASE WHEN sendstate = 2 THEN 1 ELSE 0 END) AS dsf, -- 不理睬数量 (sendstate = 1) SUM(CASE WHEN sendstate = 1 THEN 1 ELSE 0 END) AS blq, -- 异常数量 (excep IS NOT NULL AND excep != '0') SUM(CASE WHEN excep IS NOT NULL AND excep != '0' THEN 1 ELSE 0 END) AS yc FROM service_subtask <where> 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 leavehospitaldistrictcode = #{leavehospitaldistrictcode} </if> <if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''"> AND leavehospitaldistrictname = #{leavehospitaldistrictname} </if> <if test="leavediagname != null and leavediagname != ''"> AND leavediagname LIKE CONCAT('%', #{leavediagname}, '%') </if> <if test="managementDoctor != null and managementDoctor != ''"> AND management_doctor LIKE CONCAT('%', #{managementDoctor}, '%') </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="managementDoctorCode != null"> AND management_doctor_code = #{managementDoctorCode} </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 DATE_FORMAT(endtime,'%y%m%d') >= DATE_FORMAT(#{startOutHospTime},'%y%m%d') </if> <if test="endOutHospTime != null"> AND DATE_FORMAT(endtime,'%y%m%d') <= DATE_FORMAT(#{endOutHospTime},'%y%m%d') </if> <if test="startSendDateTime != null"> AND DATE_FORMAT(long_send_time,'%y%m%d') >= DATE_FORMAT(#{startSendDateTime},'%y%m%d') </if> <if test="endSendDateTime != null"> AND DATE_FORMAT(long_send_time,'%y%m%d') <= DATE_FORMAT(#{endSendDateTime},'%y%m%d') </if> <if test="longSendTime != null"> AND DATE_FORMAT(long_send_time,'%y%m%d') <= DATE_FORMAT(#{longSendTime},'%y%m%d') </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="deptcode != null and deptcode != ''"> AND deptcode = #{deptcode} </if> <if test="sendstate != null"> AND sendstate = #{sendstate} </if> <if test="sendstates != null and sendstates.size() > 0"> AND sendstate IN <foreach collection="sendstates" item="state" open="(" separator="," close=")"> #{state} </foreach> </if> <if test="orgid != null and orgid != ''"> AND orgid = #{orgid} </if> <if test="guid != null and guid != ''"> AND guid = #{guid} </if> </where> </select> </mapper>