Преглед изворни кода

Merge remote-tracking branch 'origin/dev/ruleClass2rd20210818' into test

zhaops пре 4 година
родитељ
комит
6dc3683a0a

+ 3 - 0
cdssman-service/src/main/java/com/diagbot/client/CdssCoreClient.java

@@ -221,4 +221,7 @@ public interface CdssCoreClient {
     @PostMapping("/klDisease/searchConceptRuleClass")
     RespDTO<List<GetAllForRelationDTO>> searchConceptRuleClass(@Valid @RequestBody SearchConceptVO searchConceptVO);
 
+    //在集合业务中,搜索术语
+    @PostMapping("/klDisease/searchCollectionConceptVO")
+    RespDTO<List<GetAllForRelationDTO>> searchCollectionConcept(SearchCollectionConceptVO searchCollectionConceptVO);
 }

+ 6 - 0
cdssman-service/src/main/java/com/diagbot/client/hystrix/CdssCoreHystrix.java

@@ -302,4 +302,10 @@ public class CdssCoreHystrix implements CdssCoreClient {
         log.error("【hystrix】调用{}异常", "searchConceptRuleClass");
         return null;
     }
+
+    @Override
+    public RespDTO<List<GetAllForRelationDTO>> searchCollectionConcept(SearchCollectionConceptVO searchCollectionConceptVO) {
+        log.error("【hystrix】调用{}异常", "searchConceptRuleClass");
+        return null;
+    }
 }

+ 17 - 0
cdssman-service/src/main/java/com/diagbot/dto/ConceptCollectionMatchDTO.java

@@ -0,0 +1,17 @@
+package com.diagbot.dto;
+
+import com.diagbot.vo.ConceptCollectionBaseVO;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/8/18 13:50
+ */
+@Data
+public class ConceptCollectionMatchDTO {
+    List<ConceptCollectionBaseVO> matchList;
+    List<ConceptCollectionBaseVO> unMatchList;
+}

+ 51 - 1
cdssman-service/src/main/java/com/diagbot/facade/KlConceptCollectionFacade.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.diagbot.client.UserServiceClient;
 import com.diagbot.dto.ConceptCollectionDTO;
+import com.diagbot.dto.ConceptCollectionMatchDTO;
 import com.diagbot.dto.DictionaryInfoDTO;
 import com.diagbot.dto.RespDTO;
 import com.diagbot.entity.KlConcept;
@@ -27,6 +28,7 @@ import com.diagbot.util.UserUtils;
 import com.diagbot.vo.ConceptCollectionBaseVO;
 import com.diagbot.vo.ConceptCollectionPageVO;
 import com.diagbot.vo.ConceptCollectionSaveVO;
+import com.diagbot.vo.ConceptCollectionVO;
 import com.diagbot.vo.IdVO;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
@@ -34,7 +36,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
+import java.util.Arrays;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -51,7 +55,7 @@ public class KlConceptCollectionFacade {
     @Autowired
     KlLibraryInfoFacade klLibraryInfoFacade;
     @Autowired
-            @Qualifier("klRelationServiceImpl")
+    @Qualifier("klRelationServiceImpl")
     KlRelationService klRelationService;
     @Autowired
     KlRelationFacade klRelationFacade;
@@ -111,6 +115,7 @@ public class KlConceptCollectionFacade {
 
     /**
      * 保存(新增和修改)
+     *
      * @param conceptCollectionSaveVO
      * @return
      */
@@ -337,4 +342,49 @@ public class KlConceptCollectionFacade {
         klRelationOrderFacade.remove(new QueryWrapper<KlRelationOrder>().in("t_relation_id", relationIds));
         return true;
     }
+
+    /**
+     * 批量校验标准术语是否存在
+     *
+     * @param conceptCollectionVO
+     * @return
+     */
+    public ConceptCollectionMatchDTO collectionMatch(ConceptCollectionVO conceptCollectionVO) {
+        ConceptCollectionMatchDTO retDTO = new ConceptCollectionMatchDTO();
+        List<String> conceptNames = Arrays.stream(conceptCollectionVO.getConceptLibNames().trim().split("\\\n"))
+                .filter(i -> StringUtils.isNotBlank(i))
+                .map(i -> i.trim())
+                .distinct()
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(conceptNames)) {
+            return retDTO;
+        }
+        List<KlConcept> klConceptList = klConceptFacade.list(new QueryWrapper<KlConcept>()
+                .eq("is_deleted", IsDeleteEnum.N.getKey())
+                .eq("lib_type", conceptCollectionVO.getConceptLibType())
+                .in("lib_name", conceptNames));
+        Map<String, Long> klConceptMap = new HashMap<>();
+
+        if (ListUtil.isNotEmpty(klConceptList)) {
+            klConceptMap = klConceptList.stream().collect(Collectors.toMap(KlConcept::getLibName, KlConcept::getId));
+        }
+
+        List<ConceptCollectionBaseVO> matchList = Lists.newLinkedList();
+        List<ConceptCollectionBaseVO> unMatchList = Lists.newLinkedList();
+        for (String name : conceptNames) {
+            ConceptCollectionBaseVO baseVO = new ConceptCollectionBaseVO();
+            baseVO.setConceptLibName(name);
+            baseVO.setConceptLibType(conceptCollectionVO.getConceptLibType());
+            if (klConceptMap.containsKey(name)) {
+                baseVO.setConceptId(klConceptMap.get(name));
+                matchList.add(baseVO);
+            } else {
+                unMatchList.add(baseVO);
+            }
+        }
+        retDTO.setMatchList(matchList);
+        retDTO.setUnMatchList(unMatchList);
+
+        return retDTO;
+    }
 }

+ 7 - 11
cdssman-service/src/main/java/com/diagbot/facade/KlConceptFacade.java

@@ -38,17 +38,7 @@ import com.diagbot.util.ListUtil;
 import com.diagbot.util.RespDTOUtil;
 import com.diagbot.util.StringUtil;
 import com.diagbot.util.UserUtils;
-import com.diagbot.vo.ConceptRelationVO;
-import com.diagbot.vo.GetAllForRelationVO;
-import com.diagbot.vo.KlConceptAllVO;
-import com.diagbot.vo.KlConceptClearVO;
-import com.diagbot.vo.KlConceptInfoVO;
-import com.diagbot.vo.KlConceptSatarOrdisaVO;
-import com.diagbot.vo.KlConceptSaveSubVO;
-import com.diagbot.vo.KlConceptSaveVO;
-import com.diagbot.vo.KlLibraryInfoVO;
-import com.diagbot.vo.SearchConceptVO;
-import com.diagbot.vo.SearchVO;
+import com.diagbot.vo.*;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang3.StringUtils;
@@ -693,4 +683,10 @@ public class KlConceptFacade extends KlConceptServiceImpl {
         param.setPerson(person);
         return param;
     }
+
+    public List<GetAllForRelationDTO> searchCollectionConceptFac(SearchCollectionConceptVO searchCollectionConceptVO) {
+        RespDTO<List<GetAllForRelationDTO>> relationDTORespDTO = cdssCoreClient.searchCollectionConcept(searchCollectionConceptVO);
+        RespDTOUtil.respNGDeal(relationDTORespDTO, "在集合业务中,搜索术语失败");
+        return relationDTORespDTO.data;
+    }
 }

+ 19 - 0
cdssman-service/src/main/java/com/diagbot/vo/ConceptCollectionVO.java

@@ -0,0 +1,19 @@
+package com.diagbot.vo;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/8/18 13:28
+ */
+@Data
+public class ConceptCollectionVO {
+    @NotNull(message = "术语类型不允许为空")
+    private Integer conceptLibType;
+    @NotBlank(message = "术语名称不允许为空")
+    private String conceptLibNames;
+}

+ 49 - 0
cdssman-service/src/main/java/com/diagbot/vo/SearchCollectionConceptVO.java

@@ -0,0 +1,49 @@
+package com.diagbot.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @className: com.diagbot.vo-> SearchCollectionConceptVO
+ * @description: 在集合业务中,搜索术语
+ * @author: kongwz
+ * @createDate: 2021-08-18 16:07
+ * @version: 1.0
+ * @todo:
+ */
+@Setter
+@Getter
+public class SearchCollectionConceptVO {
+    /**
+     * 词性id
+     */
+    @ApiModelProperty(value="词性id")
+    @NotNull(message ="请输入搜索词的词性" )
+    private Integer libType;
+    /**
+     * 需要排除的概念id集合
+     */
+    @ApiModelProperty(value="需要排除的概念id集合")
+    private List<Long> excludedConceptIds;
+
+    @ApiModelProperty(value="搜索关键词")
+    private List<String> names;
+
+    @ApiModelProperty(value="逻辑运算符")
+    @NotNull(message ="请输入逻辑运算符" )
+    private Integer logicalOperator;
+
+    @Override
+    public String toString() {
+        return "SearchCollectionConceptVO{" +
+                "libType=" + libType +
+                ", excludedConceptIds=" + excludedConceptIds +
+                ", names=" + names +
+                ", logicalOperator=" + logicalOperator +
+                '}';
+    }
+}

+ 15 - 3
cdssman-service/src/main/java/com/diagbot/web/KlConceptCollectionController.java

@@ -3,10 +3,12 @@ package com.diagbot.web;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.diagbot.annotation.SysLogger;
 import com.diagbot.dto.ConceptCollectionDTO;
+import com.diagbot.dto.ConceptCollectionMatchDTO;
 import com.diagbot.dto.RespDTO;
 import com.diagbot.facade.KlConceptCollectionFacade;
 import com.diagbot.vo.ConceptCollectionPageVO;
 import com.diagbot.vo.ConceptCollectionSaveVO;
+import com.diagbot.vo.ConceptCollectionVO;
 import com.diagbot.vo.IdVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -35,8 +37,8 @@ public class KlConceptCollectionController {
     @ApiOperation(value = "获取术语集合列表[zhaops]",
             notes = "collectionLibName:术语集合名称 <br>" +
                     "collectionLibType: 术语集合类型 <br>" +
-                    "conceptLibName: 术语集合类型 <br>" +
-                    "collectionRemark: 基础术语名称 <br>")
+                    "conceptLibName: 基础术语名称 <br>" +
+                    "collectionRemark: 术语集合说明 <br>")
     @PostMapping("/getPage")
     @SysLogger("getPage")
     public RespDTO<IPage<ConceptCollectionDTO>> getPage(@Valid @RequestBody ConceptCollectionPageVO conceptCollectionPageVO) {
@@ -50,7 +52,7 @@ public class KlConceptCollectionController {
                     "collectionLibName:术语集合名称 <br>" +
                     "relationId: 关系类型 <br>" +
                     "conceptLibType: 术语集合类型 <br>" +
-                    "collectionRemark: 基础术语名称 <br>" +
+                    "collectionRemark: 术语集合说明 <br>" +
                     "conceptId: 基础术语id,必填 <br>" +
                     "conceptLibType: 基础术语类型,必填 <br>" +
                     "conceptLibName: 基础术语名称 <br>")
@@ -78,4 +80,14 @@ public class KlConceptCollectionController {
         Boolean data = klConceptCollectionFacade.deleteById(idVO);
         return RespDTO.onSuc(data);
     }
+
+    @ApiOperation(value = "批量校验标准术语是否存在[zhaops]",
+            notes = "conceptLibNames: 基础术语名称 <br>" +
+                    "conceptLibType: 基础术语类型 <br>")
+    @PostMapping("/collectionMatch")
+    @SysLogger("collectionMatch")
+    public RespDTO<ConceptCollectionDTO> collectionMatch(@Valid @RequestBody ConceptCollectionVO conceptCollectionVO) {
+        ConceptCollectionMatchDTO data = klConceptCollectionFacade.collectionMatch(conceptCollectionVO);
+        return RespDTO.onSuc(data);
+    }
 }

+ 12 - 0
cdssman-service/src/main/java/com/diagbot/web/KlDiseaseController.java

@@ -132,4 +132,16 @@ public class KlDiseaseController {
         return RespDTO.onSuc(getAllForRelationDTOS);
     }
 
+    @ApiOperation(value = "在集合业务中,搜索术语[by:kongwz]",
+            notes = "names: 搜索关键词集合<br>" +
+                    "libType: 查询术语的词性<br>" +
+                    "excludedConceptIds: 需要排除的概念id集合<br>" +
+                    "logicalOperator: 逻辑运算符 0:and 1:or")
+    @PostMapping("/searchCollectionConceptVO")
+    @SysLogger("searchCollectionConceptVO")
+    public RespDTO<List<GetAllForRelationDTO>> searchCollectionConcept(@Valid @RequestBody SearchCollectionConceptVO searchCollectionConceptVO) {
+        List<GetAllForRelationDTO> getAllForRelationDTOS = klConceptFacade.searchCollectionConceptFac(searchCollectionConceptVO);
+        return RespDTO.onSuc(getAllForRelationDTOS);
+    }
+
 }

+ 18 - 0
common/src/main/java/com/diagbot/biz/push/entity/Scale.java

@@ -0,0 +1,18 @@
+package com.diagbot.biz.push.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @Description:
+ * @author: gaodm
+ * @time: 2021/8/19 10:59
+ */
+@Getter
+@Setter
+public class Scale extends Item {
+    /**
+     * 量表结果
+     */
+    private String result;
+}

+ 299 - 0
common/src/main/java/com/diagbot/util/EntityUtil.java

@@ -1,14 +1,18 @@
 package com.diagbot.util;
 
+import com.diagbot.biz.push.entity.Lis;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.Validate;
 import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.commons.lang3.time.DateUtils;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.math.BigDecimal;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -20,6 +24,7 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 实体对象工具类
@@ -30,6 +35,68 @@ import java.util.Map;
 public class EntityUtil {
 
     private static final String DATE_CLASS_NAME = Date.class.getName();
+    public static String[]  dateFormats = {
+            "yyyy年MM月dd日HH时mm分",
+            "yyyy年MM月dd日HH:mm",
+            "yyyy年MM月dd日H时mm分",
+            "yyyy年MM月dd日HH时m分",
+            "yyyy年MM月dd日H时m分",
+            "yyyy年M月dd日HH时mm分",
+            "yyyy年M月dd日H时mm分",
+            "yyyy年M月dd日HH时m分",
+            "yyyy年M月dd日H时m分",
+            "yyyy年MM月d日HH时mm分",
+            "yyyy年MM月d日H时mm分",
+            "yyyy年MM月d日HH时m分",
+            "yyyy年MM月d日H时m分",
+            "yyyy年M月d日HH时mm分",
+            "yyyy年M月d日H时mm分",
+            "yyyy年M月d日HH时m分",
+            "yyyy年M月d日H时m分",
+            "yyyy-MM-ddHH:mm:ss",
+            "yyyy-MM-ddHH:mm",
+            "yyyy-MM-ddHH:m",
+            "yyyy-MM-ddH:mm",
+            "yyyy-MM-ddH:m",
+            "yyyy-M-ddHH:mm",
+            "yyyy-M-ddHH:m",
+            "yyyy-M-ddH:mm",
+            "yyyy-M-ddH:m",
+            "yyyy-MM-dHH:mm",
+            "yyyy-MM-dHH:m",
+            "yyyy-MM-dH:mm",
+            "yyyy-MM-dH:m",
+            "yyyy-M-dHH:mm",
+            "yyyy-M-dHH:m",
+            "yyyy-M-dH:mm",
+            "yyyy-M-dH:m",
+            "yyyy-MM-dd",
+            "yyyy年MM月dd日H时",
+            "yyyy/MM/ddHH:mm:ss",
+            "yyyy/MM/ddHH:mm",
+            "yyyy/MM/ddHH:m",
+            "yyyy/MM/ddH:mm",
+            "yyyy/MM/ddH:m",
+            "yyyy/MM/ddHH:mm:",
+            "yyyy/M/ddHH:mm",
+            "yyyy/M/ddHH:m",
+            "yyyy/M/ddH:mm",
+            "yyyy/M/ddH:m",
+            "yyyy/MM/dHH:mm",
+            "yyyy/MM/dHH:m",
+            "yyyy/MM/dH:mm",
+            "yyyy/MM/dH:m",
+            "yyyy/M/dHH:mm",
+            "yyyy/M/dHH:m",
+            "yyyy/M/dH:mm",
+            "yyyy/M/dH:m",
+            "yyyy/MM/dd",
+            "yyyy.MM.dd",
+            "yyyy-MM-ddHH:mm:ss.000",
+            "yyyyMMddHH:mm",
+            "yyyy-MM-dd'T'HH:mm:ss",
+            "MM/dd/yyyyHH:mm:ss"
+    };
 
     /**
      * 将list中元素的某一成员组装成list返回。注意:会去重!
@@ -447,4 +514,236 @@ public class EntityUtil {
         }
         return map;
     }
+
+    /**
+     * 以Map<key, V> 形式返回,如果key相同,会覆盖前面的内容
+     *
+     * @param list          列表
+     * @param splitSmybool  key分隔符
+     * @param multiProperty 多个属性
+     * @param <V>
+     * @return
+     */
+    public static <V> List<V> getNoRepeatList(List<V> list, String splitSmybool, String dateProperty, String... multiProperty) {
+        List<V> res = new ArrayList<>();
+        Map<String, V> multiKeyObject = getMultiKeyObject(list, splitSmybool, dateProperty, multiProperty);
+        if (multiKeyObject != null && !multiKeyObject.isEmpty()) {
+            for (String key : multiKeyObject.keySet()) {
+                res.add(multiKeyObject.get(key));
+            }
+        }
+        return res;
+    }
+
+    /**
+     * 以Map<key, V> 形式返回,如果key相同,根据时间排序,后面时间覆盖前面时间
+     *
+     * @param list          列表
+     * @param splitSmybool  key分隔符
+     * @param dateProperty  时间属性
+     * @param multiProperty 多个属性
+     * @param <V>
+     * @return
+     */
+    public static <V> Map<String, V> getMultiKeyObject(List<V> list, String splitSmybool, String dateProperty, String... multiProperty) {
+        if (ListUtil.isEmpty(list)) {
+            return new LinkedHashMap<>();
+        }
+        return list.stream().collect(Collectors.toMap(k -> {
+            List<String> keyList = new ArrayList<>();
+            for (String property : multiProperty) {
+                keyList.add(getProperty(k, property));
+            }
+            return StringUtils.join(keyList, splitSmybool);
+        }, v -> v, (v1, v2) -> {
+            String date1 = getProperty(v1, dateProperty);
+            if (StringUtil.isBlank(date1)) {
+                return v2;
+            }
+            String date2 = getProperty(v2, dateProperty);
+            if (StringUtil.isBlank(date2)) {
+                return v1;
+            }
+            int flag = compareTime(date1, date2);
+            if (flag == 0) {
+                return v1;
+            } else {
+                return v2;
+            }
+        }, LinkedHashMap::new));
+    }
+
+    /**
+     * 获取对象的属性值,直接使用getDeclaredFields()方法只能获取当前类声明的字段,需要递归向上获取
+     *
+     * @param object    : 子类对象
+     * @param fieldName : 父类中的属性名
+     * @return : 父类中的属性值
+     */
+    public static <T> T getProperty(Object object, String fieldName) {
+        try {
+            //根据 对象和属性名通过反射获取Field对象
+            Field field = getDeclaredField(object, fieldName);
+            // 容错处理
+            if (field == null) {
+                return null;
+            }
+            //抑制Java对其的检查
+            field.setAccessible(true);
+            //获取 object 中 field 所代表的属性值
+            return (T) field.get(object);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 对象赋值
+     *
+     * @param object
+     * @param property
+     * @param value
+     */
+    public static void setProperty(Object object, String property, Object value) {
+        //根据 对象和属性名通过反射 调用上面的方法获取 Field对象
+        Field field = getDeclaredField(object, property);
+        //抑制Java对其的检查
+        field.setAccessible(true);
+        try {
+            field.set(object, value);
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 循环向上转型, 获取对象的 DeclaredField
+     *
+     * @param object    : 子类对象
+     * @param fieldName : 父类中的属性名
+     * @return 父类中的属性对象
+     */
+    public static Field getDeclaredField(Object object, String fieldName) {
+        Field field = null;
+        Class<?> clazz = object.getClass();
+        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
+            try {
+                field = clazz.getDeclaredField(fieldName);
+                return field;
+            } catch (Exception e) {
+                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
+                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 比较时间,endDateStr >= startDateStr
+     * @param startDateStr
+     * @param endDateStr
+     * @return -1:无法比较或出错,0:endDateStr < startDateStr,1:endDateStr >= startDateStr
+     */
+    public static int compareTime(String startDateStr, String endDateStr) {
+        int flag = -1;
+        if (StringUtil.isBlank(startDateStr) || StringUtil.isBlank(endDateStr)) {
+            return flag;
+        }
+        try {
+            Date startDate = parseStringDate(startDateStr);
+            Date endDate = parseStringDate(endDateStr);
+            Long timeStart = startDate.getTime();
+            Long timeEnd = endDate.getTime();
+            if (timeEnd >= timeStart) {
+                flag = 1;
+            } else {
+                flag = 0;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return flag;
+    }
+
+    /**
+     * 解析时间
+     *
+     * @param datetime
+     * @return
+     */
+    public static Date parseStringDate(String datetime) {
+        if (StringUtil.isBlank(datetime)) {
+            return null;
+        }
+        Date date = null;
+        try {
+            datetime = remove_ctl(datetime);
+
+            if (datetime.contains("至")) {
+                datetime = datetime.split("至")[1].replaceAll("[\\u4e00-\\u9fa5]", "");
+            }
+
+            if (datetime.length() > 0) {
+                date = DateUtils.parseDate(datetime, dateFormats);
+            }
+        } catch (ParseException ex) {
+            ex.printStackTrace();
+        }
+        return date;
+    }
+
+    /**
+     * 删除字符串中的换行和控制字符
+     *
+     * @param str
+     */
+    public static String remove_ctl(String str) {
+        String trim = "";
+        if (StringUtils.isNotEmpty(str)) {
+            trim = str.replaceAll("\r|\n|\r\n", "").trim();
+        }
+        return trim;
+    }
+
+    public static void main(String[] args) {
+        List<Lis> lisList = Lists.newArrayList();
+        Lis lis = new Lis();
+        lis.setName("血常规");
+        lis.setDetailName("白细胞计数");
+        lis.setUniqueName("");
+        lis.setValue(10.0D);
+        lis.setUnits("");
+        lis.setMinValue(0.0D);
+        lis.setMaxValue(0.0D);
+        lis.setOtherValue("");
+        lis.setDateValue("2021-08-18 10:04:56");
+        lis.setFinishDateValue("");
+        lis.setSource(0);
+        lis.setResult("");
+        lis.setFrequency("");
+
+        Lis lis2 = new Lis();
+        lis2.setName("血常规");
+        lis2.setDetailName("白细胞计数");
+        lis2.setUniqueName("");
+        lis2.setValue(20.0D);
+        lis2.setUnits("");
+        lis2.setMinValue(0.0D);
+        lis2.setMaxValue(0.0D);
+        lis2.setOtherValue("");
+        lis2.setDateValue("2021-08-18 11:04:56");
+        lis2.setFinishDateValue("");
+        lis2.setSource(0);
+        lis2.setResult("");
+        lis2.setFrequency("");
+
+        lisList.add(lis);
+        lisList.add(lis2);
+        Map<String, Lis> multiKeyObject = getMultiKeyObject(lisList, "_", "dateValue", "name", "detailName");
+        System.out.println(multiKeyObject);
+
+    }
 }