| | |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.common.utils.PageUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import com.smartor.domain.PatMedInhosp; |
| | | import com.smartor.domain.PatMedInhospVO; |
| | | import com.smartor.domain.PatMedReq; |
| | |
| | | |
| | | @Autowired |
| | | private IPatMedOuthospService iPatMedOuthospService; |
| | | |
| | | //todo |
| | | @Autowired |
| | | private ISysConfigService configService; |
| | | |
| | | |
| | | /** |
| | | * 查询患者住院记录列表 |
| | |
| | | return success(patMedInhospService.getDeptCodeByPatId(patMedInhosp)); |
| | | } |
| | | |
| | | /** |
| | | * 查询出、入院看病人次和人数(人数分为首次服务、再次服务、专病服务) |
| | | */ |
| | | @PostMapping("/selectPatMedInhospListCount") |
| | | @ApiOperation("查询出、入院看病人次和人数") |
| | | public AjaxResult selectPatMedInhospListCount(@RequestBody PatMedReq patMedReq) { |
| | |
| | | // } |
| | | // } |
| | | |
| | | @ApiOperation("测试定时任务dealOutHospInfo") |
| | | @PostMapping("/dealOutHospInfo") |
| | | public void dealOutHospInfo() { |
| | | String config = configService.selectConfigByKey("visit.early.day"); |
| | | //出院表 |
| | | patMedInhospService.dealOutHospInfo(config); |
| | | } |
| | | } |
| | |
| | | |
| | | import com.github.pagehelper.ISelect; |
| | | import com.ruoyi.common.annotation.Log; |
| | | import com.ruoyi.common.constant.CacheConstants; |
| | | import com.ruoyi.common.constant.Constants; |
| | | import com.ruoyi.common.constant.HttpStatus; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | |
| | | import com.ruoyi.common.utils.DtoConversionUtils; |
| | | import com.ruoyi.common.utils.PageUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.common.utils.reflect.ReflectUtils; |
| | | import com.ruoyi.common.utils.uuid.IdUtils; |
| | | import com.smartor.domain.*; |
| | | import com.smartor.mapper.PatMedInhospMapper; |
| | | import com.smartor.mapper.PatMedOuthospMapper; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import net.bytebuddy.implementation.bytecode.Throw; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.collections4.MapUtils; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | |
| | | @Value("${spring.profiles.active}") |
| | | private String active; |
| | | |
| | | @Autowired |
| | | private RedisCache redisCache; |
| | | |
| | | /** |
| | | * 查询患者随访信息 |
| | |
| | | ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid()); |
| | | if (ObjectUtils.isNotEmpty(serviceTask)) serviceSubtask.setPreachform(serviceTask.getPreachform()); |
| | | } |
| | | Map<String, Object> map = serviceSubtaskService.patItemCount(serviceSubtaskVO); |
| | | |
| | | /** |
| | | * 代码优化 分离统计 |
| | | 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); |
| | | map.put("serviceSubtaskList", serviceSubtaskList); |
| | | List<Map<String, Object>> list = new ArrayList<>(); |
| | | list.add(map); |
| | |
| | | } |
| | | }); |
| | | return getDataTable2(total, list); |
| | | } |
| | | |
| | | /** |
| | | * 统计随访数据 |
| | | */ |
| | | @ApiOperation("统计随访数据") |
| | | @PostMapping("/patItemCount") |
| | | public Map<String, Object> patItemCount(@RequestBody ServiceSubtaskVO serviceSubtaskVO) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | // 通过redis记录结果 |
| | | Map<String, Object> redisMap = new HashMap<>(); |
| | | LoginUser loginUser = getLoginUser(); |
| | | SysUser user = null; |
| | | Long userId = null; |
| | | if(ObjectUtils.isNotEmpty(loginUser)){ |
| | | user = loginUser.getUser(); |
| | | if(ObjectUtils.isNotEmpty(user)){ |
| | | userId = user.getUserId(); |
| | | } |
| | | } |
| | | if(ObjectUtils.isNotEmpty(userId)){ |
| | | redisMap = redisCache.getCacheObject(userId + "patItemCount"); |
| | | //记录是否有可用缓存 |
| | | Boolean redisFlag = false; |
| | | ServiceSubtaskVO oldCondition = null; |
| | | if(MapUtils.isNotEmpty(redisMap)){ |
| | | oldCondition = (ServiceSubtaskVO)redisMap.get("searchCondition"); |
| | | // 比较查询条件是否一致 |
| | | if(ObjectUtils.isNotEmpty(oldCondition) && |
| | | isSameCondition(oldCondition, serviceSubtaskVO)){ |
| | | // 条件一致,使用缓存 |
| | | redisFlag = true; |
| | | map = redisMap; |
| | | redisCache.setCacheObject(userId + "patItemCount", map, 120, TimeUnit.MINUTES); |
| | | } |
| | | } |
| | | |
| | | // 如果没有缓存或者条件不一致,重新查询 |
| | | if(!redisFlag){ |
| | | map = serviceSubtaskService.patItemCount(serviceSubtaskVO); |
| | | map.put("searchCondition", serviceSubtaskVO); |
| | | redisCache.setCacheObject(userId + "patItemCount", map, 120, TimeUnit.MINUTES); |
| | | } |
| | | } |
| | | |
| | | map.put("code", HttpStatus.SUCCESS); |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * 比较两个ServiceSubtaskVO的查询条件是否一致 |
| | | * 使用反射比较所有字段,排除分页参数和无关字段 |
| | | */ |
| | | private boolean isSameCondition(ServiceSubtaskVO oldCondition, ServiceSubtaskVO newCondition) { |
| | | // 使用ReflectUtils的通用方法比较,排除分页参数等无关字段 |
| | | return ReflectUtils.equalsAllFields( |
| | | oldCondition, |
| | | newCondition, |
| | | // 排除的字段:分页参数、序列化ID、时间戳等 |
| | | "pageNum", "pageSize", "serialVersionUID", |
| | | "createBy", "createTime", "updateBy", "updateTime", |
| | | "searchValue", "params" |
| | | ); |
| | | } |
| | | |
| | | |
| | |
| | | serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString()); |
| | | serviceSubtask.setServiceSubtaskRecordList(serviceSubtaskRecordService.selectServiceSubtaskRecordList(serviceSubtaskRecord)); |
| | | } |
| | | //todo 代码优化 |
| | | 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); |
| | |
| | | import java.lang.reflect.Modifier; |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.lang.reflect.Type; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.commons.lang3.Validate; |
| | | import org.apache.poi.ss.usermodel.DateUtil; |
| | |
| | | } |
| | | return new RuntimeException(msg, e); |
| | | } |
| | | |
| | | /** |
| | | * 比较两个相同类型对象的所有字段值是否相等 |
| | | * 使用反射获取所有字段(包括父类字段),并逐个比较 |
| | | * |
| | | * @param obj1 第一个对象 |
| | | * @param obj2 第二个对象 |
| | | * @return 如果所有字段值都相等返回true,否则返回false |
| | | * *示例1:比较所有字段 |
| | | * * boolean result = ReflectUtils.equalsAllFields(user1, user2); |
| | | */ |
| | | public static boolean equalsAllFields(Object obj1, Object obj2) |
| | | { |
| | | return equalsAllFields(obj1, obj2, new String[]{}); |
| | | } |
| | | |
| | | /** |
| | | * 比较两个相同类型对象的所有字段值是否相等(可排除指定字段) |
| | | * 使用反射获取所有字段(包括父类字段),并逐个比较 |
| | | * |
| | | * @param obj1 第一个对象 |
| | | * @param obj2 第二个对象 |
| | | * @param excludeFields 要排除的字段名称数组 |
| | | * @return 如果所有字段值都相等返回true,否则返回false |
| | | * // 示例2:排除分页参数 |
| | | * * boolean result = ReflectUtils.equalsAllFields(vo1, vo2, "pageNum", "pageSize"); |
| | | */ |
| | | public static boolean equalsAllFields(Object obj1, Object obj2, String... excludeFields) |
| | | { |
| | | // 两个对象都为null,认为相等 |
| | | if (obj1 == null && obj2 == null) return true; |
| | | |
| | | // 只有一个为null,不相等 |
| | | if (obj1 == null || obj2 == null) return false; |
| | | |
| | | // 如果是同一个对象引用,直接返回true |
| | | if (obj1 == obj2) return true; |
| | | |
| | | // 类型不同,不相等 |
| | | if (!obj1.getClass().equals(obj2.getClass())) return false; |
| | | |
| | | // 将排除字段转换为Set,便于快速查找 |
| | | Set<String> excludeFieldSet = new HashSet<>(Arrays.asList(excludeFields)); |
| | | |
| | | // 获取所有字段(包括父类字段) |
| | | List<Field> allFields = getAllFields(obj1); |
| | | |
| | | // 逐个比较字段值 |
| | | for (Field field : allFields) |
| | | { |
| | | // 跳过排除的字段 |
| | | if (excludeFieldSet.contains(field.getName())) continue; |
| | | |
| | | // 跳过static和transient字段 |
| | | if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | try{ |
| | | makeAccessible(field); |
| | | Object value1 = field.get(obj1); |
| | | Object value2 = field.get(obj2); |
| | | |
| | | // 使用Objects.equals进行比较,可以正确处理null值 |
| | | if (!Objects.equals(value1, value2)) |
| | | { |
| | | //logger.debug("字段 [{}] 的值不相等: obj1={}, obj2={}", field.getName(), value1, value2); |
| | | return false; |
| | | } |
| | | }catch (IllegalAccessException e) |
| | | { |
| | | //logger.error("访问字段 [{}] 时发生错误: {}", field.getName(), e.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 获取对象的所有字段(包括父类字段) |
| | | * |
| | | * @param obj 目标对象 |
| | | * @return 所有字段的列表 |
| | | */ |
| | | public static List<Field> getAllFields(Object obj) |
| | | { |
| | | List<Field> allFields = new ArrayList<>(); |
| | | Class<?> clazz = obj.getClass(); |
| | | |
| | | // 循环向上遍历父类,获取所有字段 |
| | | while (clazz != null && clazz != Object.class) |
| | | { |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | allFields.addAll(Arrays.asList(fields)); |
| | | clazz = clazz.getSuperclass(); |
| | | } |
| | | |
| | | return allFields; |
| | | } |
| | | |
| | | /** |
| | | * 比较两个对象指定字段的值是否相等 |
| | | * |
| | | * @param obj1 第一个对象 |
| | | * @param obj2 第二个对象 |
| | | * @param includeFields 要比较的字段名称数组 |
| | | * @return 如果指定字段值都相等返回true,否则返回false |
| | | * |
| | | * // 示例3:只比较关键字段 |
| | | * boolean result = ReflectUtils.equalsSpecifiedFields(user1, user2, "userId", "userName", "email"); |
| | | */ |
| | | public static boolean equalsSpecifiedFields(Object obj1, Object obj2, String... includeFields) |
| | | { |
| | | // 两个对象都为null,认为相等 |
| | | if (obj1 == null && obj2 == null) return true; |
| | | |
| | | // 只有一个为null,不相等 |
| | | if (obj1 == null || obj2 == null) return false; |
| | | |
| | | // 如果是同一个对象引用,直接返回true |
| | | if (obj1 == obj2) return true; |
| | | |
| | | // 类型不同,不相等 |
| | | if (!obj1.getClass().equals(obj2.getClass())) return false; |
| | | |
| | | // 如果没有指定字段,返回true |
| | | if (includeFields == null || includeFields.length == 0) return true; |
| | | |
| | | // 逐个比较指定字段的值 |
| | | for (String fieldName : includeFields) |
| | | { |
| | | Field field = getAccessibleField(obj1, fieldName); |
| | | if (field == null) |
| | | { |
| | | //logger.warn("在 [{}] 中未找到字段 [{}]", obj1.getClass().getName(), fieldName); |
| | | continue; |
| | | } |
| | | |
| | | try |
| | | { |
| | | makeAccessible(field); |
| | | Object value1 = field.get(obj1); |
| | | Object value2 = field.get(obj2); |
| | | |
| | | // 使用Objects.equals进行比较,可以正确处理null值 |
| | | if (!Objects.equals(value1, value2)) |
| | | { |
| | | //logger.debug("字段 [{}] 的值不相等: obj1={}, obj2={}", fieldName, value1, value2); |
| | | return false; |
| | | } |
| | | } |
| | | catch (IllegalAccessException e) |
| | | { |
| | | //logger.error("访问字段 [{}] 时发生错误: {}", fieldName, e.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | } |
| | |
| | | @ApiModelProperty(value = "人数") |
| | | private Integer rs; |
| | | |
| | | /** |
| | | * 首次随访人数 |
| | | */ |
| | | @ApiModelProperty(value = "首次随访人数") |
| | | private Integer scsf; |
| | | |
| | | /** |
| | | * 再次随访人数 |
| | | */ |
| | | @ApiModelProperty(value = "再次随访人数") |
| | | private Integer zcsf; |
| | | |
| | | /** |
| | | * 专病随访人数 |
| | | */ |
| | | @ApiModelProperty(value = "专病随访人数") |
| | | private Integer zbsf; |
| | | } |
| | |
| | | |
| | | @ApiModelProperty(value = "随访部门编码集合") |
| | | private List<String> visitDeptCodes; |
| | | |
| | | // /** |
| | | // * 日期限制 目前由前端控制 |
| | | // */ |
| | | // @ApiModelProperty(value = "日期限制:0全部服务 1截止当前日期") |
| | | // private String dateLimit; |
| | | } |
| | |
| | | <select id="selectPatMedInhospCount" parameterType="com.smartor.domain.PatMedReq" |
| | | resultType="com.smartor.domain.PatMedRes"> |
| | | SELECT SUM( rs ) AS rs, |
| | | SUM( rc ) AS rc |
| | | SUM( rc ) AS rc, |
| | | SUM( scsf ) AS scsf, |
| | | SUM( zcsf ) AS zcsf, |
| | | SUM( zbsf ) AS zbsf |
| | | FROM ( |
| | | <!-- 出院人次--> |
| | | SELECT |
| | | COUNT(1) AS rc, |
| | | 0 AS rs |
| | | 0 AS rs, |
| | | 0 AS scsf, |
| | | 0 AS zcsf, |
| | | 0 AS zbsf |
| | | FROM |
| | | pat_med_inhosp |
| | | <where> |
| | |
| | | </foreach> |
| | | </if> |
| | | </if> |
| | | |
| | | </where> |
| | | <!-- 随访服务人数 --> |
| | | union all |
| | | select |
| | | 0 AS rc, |
| | | count(1) AS rs |
| | | count(1) AS rs, |
| | | 0 AS scsf, |
| | | 0 AS zcsf, |
| | | 0 AS zbsf |
| | | FROM |
| | | service_subtask |
| | | <where> |
| | |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | <!-- 首次随访人数 --> |
| | | union all |
| | | select |
| | | 0 AS rc, |
| | | 0 AS rs, |
| | | count(1) AS scsf, |
| | | 0 AS zcsf, |
| | | 0 AS zbsf |
| | | FROM |
| | | service_subtask |
| | | <where> |
| | | del_flag = 0 |
| | | and service_type=2 |
| | | and is_visit_again = 0 |
| | | <if test="orgid != null"> |
| | | AND orgid = #{orgid} |
| | | </if> |
| | | <if test="startDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) >= date_format( #{startDate}, '%y%m%d' ) |
| | | </if> |
| | | <if test="endDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) <= date_format(#{endDate},'%y%m%d') |
| | | </if> |
| | | <if test="deptcodeList != null and deptcodeList.size() > 0"> |
| | | and deptcode in |
| | | <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | <!-- 再次随访人数 --> |
| | | union all |
| | | select |
| | | 0 AS rc, |
| | | 0 AS rs, |
| | | 0 AS scsf, |
| | | count(1) AS zcsf, |
| | | 0 AS zbsf |
| | | FROM |
| | | service_subtask |
| | | <where> |
| | | del_flag = 0 |
| | | and service_type=2 |
| | | and is_visit_again = 1 |
| | | <if test="orgid != null"> |
| | | AND orgid = #{orgid} |
| | | </if> |
| | | <if test="startDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) >= date_format( #{startDate}, '%y%m%d' ) |
| | | </if> |
| | | <if test="endDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) <= date_format(#{endDate},'%y%m%d') |
| | | </if> |
| | | <if test="deptcodeList != null and deptcodeList.size() > 0"> |
| | | and deptcode in |
| | | <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | <!-- 专病随访人数 --> |
| | | union all |
| | | select |
| | | 0 AS rc, |
| | | 0 AS rs, |
| | | 0 AS scsf, |
| | | 0 AS zcsf, |
| | | count(1) AS zbsf |
| | | FROM |
| | | service_subtask |
| | | <where> |
| | | del_flag = 0 |
| | | and service_type=13 |
| | | <if test="orgid != null"> |
| | | AND orgid = #{orgid} |
| | | </if> |
| | | <if test="startDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) >= date_format( #{startDate}, '%y%m%d' ) |
| | | </if> |
| | | <if test="endDate != null"> |
| | | AND date_format( visit_time, '%y%m%d' ) <= date_format(#{endDate},'%y%m%d') |
| | | </if> |
| | | <if test="deptcodeList != null and deptcodeList.size() > 0"> |
| | | and deptcode in |
| | | <foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | ) AS combined_data |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <if test="taskGuid != null">and task_guid = #{taskGuid}</if> |
| | | <if test="isabnormal != null">and isabnormal = #{isabnormal}</if> |
| | | <if test="isVisitAgain != null">and is_visit_again = #{isVisitAgain}</if> |
| | | <!-- <if test="dateLimit != null and dateLimit = '1'"> and CURDATE() + 1 > long_send_time</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>--> |