陈昶聿
9 小时以前 2a9c68fe5130227d88b71e8eb57aced6b10d4d91
【丽水】统计随访数据 增加redis记录结果 提高查询效率
已修改2个文件
213 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -17,6 +17,7 @@
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;
@@ -106,9 +107,9 @@
        List<Map<String, Object>> list = new ArrayList<>();
        list.add(map);
         **/
        //todo 代码优化
        Map<String, Object> map = serviceSubtaskService.patItemCount(serviceSubtaskVO);
//        Map<String, Object> map = patItemCount(serviceSubtaskVO);
        //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);
@@ -145,14 +146,24 @@
        if(ObjectUtils.isNotEmpty(userId)){
            redisMap = redisCache.getCacheObject(userId + "patItemCount");
            //记录是否有可用缓存
//            Boolean redisFlag = false;
//            Map oldConditionMap = (Map)redisMap.get("searchCondition");
            Boolean redisFlag = false;
            ServiceSubtaskVO oldCondition = null;
            if(MapUtils.isNotEmpty(redisMap)){
                map = redisMap;
                redisCache.setCacheObject(userId + "patItemCount", map, 120, TimeUnit.MINUTES);
            }else {
                oldCondition = (ServiceSubtaskVO)redisMap.get(userId + "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);
                map.put(userId + "searchCondition", serviceSubtaskVO);
                redisCache.setCacheObject(userId + "patItemCount", map, 120, TimeUnit.MINUTES);
            }
        }
@@ -161,6 +172,22 @@
        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"
        );
    }
    /**
     * 导出单一任务(随访宣教)列表
ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
@@ -6,7 +6,13 @@
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;
@@ -407,4 +413,166 @@
        }
        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;
    }
}