ludc
2023-04-26 7f0570d20aac189f1b170942bd7100b281a1c824
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,988 @@
package com.vci.ubcs.code.service.impl;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.revision.model.TreeWrapperOptions;
import com.vci.ubcs.code.entity.CodeClassify;
import com.vci.ubcs.code.entity.CodeClstemplateEntity;
import com.vci.ubcs.code.entity.CodeOsbtmtypeEntity;
import com.vci.ubcs.code.entity.CodeOsbtmtypeattributeEntity;
import com.vci.ubcs.code.enumpack.FrameworkDataLCStatus;
import com.vci.ubcs.code.mapper.CodeClassifyMapper;
import com.vci.ubcs.code.mapper.CodeClstemplateMapper;
import com.vci.ubcs.code.mapper.CodeOsbtmtypeMapper;
import com.vci.ubcs.code.mapper.CodeOsbtmtypeattributeMapper;
import com.vci.ubcs.code.po.CodeClassifyPO;
import com.vci.ubcs.code.service.ICodeClassifyService;
import com.vci.ubcs.code.service.ICodeKeyattrrepeatService;
import com.vci.ubcs.code.service.ICodeRuleService;
import com.vci.ubcs.code.vo.CodeOsattributeVO;
import com.vci.ubcs.code.vo.CodeOsbtmtypeVO;
import com.vci.ubcs.code.vo.pagemodel.CodeClassifyVO;
import com.vci.ubcs.code.vo.pagemodel.CodeKeyAttrRepeatRuleVO;
import com.vci.ubcs.code.vo.pagemodel.CodeRuleVO;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.bo.WriteExcelData;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.poi.bo.ReadExcelOption;
import com.vci.ubcs.starter.poi.bo.WriteExcelOption;
import com.vci.ubcs.starter.poi.constant.ExcelLangCodeConstant;
import com.vci.ubcs.starter.poi.util.ExcelUtil;
import com.vci.ubcs.starter.revision.service.RevisionModelUtil;
import com.vci.ubcs.starter.util.LocalFileUtil;
import com.vci.ubcs.starter.web.pagemodel.BaseQueryObject;
import com.vci.ubcs.starter.web.pagemodel.DataGrid;
import com.vci.ubcs.starter.web.pagemodel.Tree;
import com.vci.ubcs.starter.web.util.BeanUtilForVCI;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.log.exception.ServiceException;
import org.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.ubcs.code.constant.FrameWorkDefaultValueConstant.*;
@Service
public class CodeClassifyServiceImpl extends ServiceImpl<CodeClassifyMapper, CodeClassify> implements ICodeClassifyService {
   @Resource
   private CodeClassifyMapper codeClassifyMapper;
   @Resource
   private CodeClstemplateMapper codeClstemplateMapper;
   @Resource
   private ICodeRuleService codeRuleService;
   @Resource
   private CodeOsbtmtypeMapper codeOsbtmtypeMapper;
   @Resource
   CodeOsbtmtypeattributeMapper codeOsbtmtypeattributeMapper;
   /**
    * æ—¥å¿—
    */
   private Logger logger = LoggerFactory.getLogger(getClass());
   /**
    * å¯¹è±¡çš„æ“ä½œ
    */
   @Resource
   private RevisionModelUtil revisionModelUtil;
   @Resource
   private ICodeKeyattrrepeatService iCodeKeyattrrepeatService;
   /**
    * ä¸Šçº§èŠ‚ç‚¹çš„å±žæ€§åç§°
    */
   public static  final String PARENT_FIELD_NAME = "parentCodeClassifyOid";
   /**
    * ä½¿ç”¨æŸ¥è¯¢å°è£…器来查询
    * @param wrapper æŸ¥è¯¢å°è£…器
    * @return æ•°æ®å¯¹è±¡
    */
   @Override
   public List<CodeClassify> selectByWrapper(Wrapper wrapper) {
      return codeClassifyMapper.selectList(wrapper);
   }
   @Override
   public IPage<CodeClassifyVO> selectPlCodeClassifyPage(IPage<CodeClassifyVO> page, CodeClassifyVO plCodeClassify) {
      return page.setRecords(codeClassifyMapper.selectPlCodeClassifyPage(page, plCodeClassify));
   }
   @Override
   public R addSave(CodeClassify codeClassifyEntity) {
      if(StringUtils.isNotBlank(codeClassifyEntity.getParentCodeClassifyOid()) && StringUtils.isNotBlank(codeClassifyEntity.getBtmTypeId())){
         return R.fail("只有在顶层的主题库分类才能设置业务类型");
      }
      codeClassifyEntity.setCreator(AuthUtil.getUser().getUserName());
      codeClassifyEntity.setCreateTime(new Date());
      codeClassifyEntity.setTs(new Date());
      codeClassifyEntity.setOwner(AuthUtil.getUser().getUserName());
      codeClassifyEntity.setLastModifier(AuthUtil.getUser().getUserName());
      codeClassifyEntity.setLastModifyTime(new Date());
      codeClassifyEntity.setRevisionSeq(1);
      codeClassifyEntity.setVersionSeq(1);
      int insertNumber = codeClassifyMapper.insert(codeClassifyEntity);
      return R.status(SqlHelper.retBool(insertNumber));
   }
   /**
    * ä¿®æ”¹ä¸»é¢˜åº“分类
    * @param codeClassifyEntity ä¸»é¢˜åº“分类数据传输对象
    * @return æ‰§è¡Œç»“æžœ
    */
   @Override
   public R editSave(CodeClassify codeClassifyEntity) {
      if(codeClassifyEntity == null || codeClassifyEntity.getOid() == null){
         return R.fail("传入数据不能为空!");
      }
      //检查ts
      Map<String,Object> condition = new HashMap<>(2);
      condition.put("oid",codeClassifyEntity.getOid());
      condition.put("ts",codeClassifyEntity.getTs());
      CodeClassify detail = codeClassifyMapper
         .selectOne(Condition.getQueryWrapper(condition,CodeClassify.class));
      if(detail == null){//不是最新的不让改
         return R.fail("当前数据不是最新,请刷新后再修改!");
      }
      if(StringUtils.isNotBlank(codeClassifyEntity.getParentCodeClassifyOid()) && StringUtils.isNotBlank(codeClassifyEntity.getBtmTypeId())){
         return R.fail("只有在顶层的主题库分类才能设置业务类型");
      }
      codeClassifyEntity.setLastModifier(AuthUtil.getUser().getUserName());
      codeClassifyEntity.setLastModifyTime(new Date());
      int insertNumber = codeClassifyMapper.updateById(codeClassifyEntity);
//         //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。只有启用状态的分类才推送
//         if(FRAMEWORK_DATA_ENABLED.equals(codeClassifyDO.getLcStatus()));
//         {
//             codeDuckingServiceI.insertCache1(CACHE_TYPE_CLASSIFY_EDIT,FRAMEWORK_DATA_ENABLED,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, codeClassifyDO.getOid(), codeClassifyDTO.getTs());
//         }
      return R.status(SqlHelper.retBool(insertNumber));
//      return BaseResult.success(codeClassifyDO2VO(codeClassifyDO));
   }
   /**
    * æ£€æŸ¥ ä¸»é¢˜åº“分类是否删除
    * @param codeClassifyEntity ä¸»é¢˜åº“分类数据传输对象,必须要有oid和ts属性
    * @return æ‰§è¡Œç»“æžœ success为true为可以删除,false表示有数据引用,obj为true表示有下级
    */
   @Override
   public R checkIsCanDelete(CodeClassify codeClassifyEntity) {
      if(codeClassifyEntity == null || codeClassifyEntity.getOid() == null){
         return R.fail("传入数据不能为空!");
      }
      CodeClassify codeClassifyNew = selectByOid(codeClassifyEntity.getOid());
      if(codeClassifyNew == null){
         return R.fail("未查询到相关数据!");
      }
      codeClassifyNew.setTs(codeClassifyEntity.getTs());
      return checkIsCanDeleteForDO(codeClassifyEntity);
   }
   /**
    * ä¸»é”®æŸ¥è¯¢æ•°æ®å¯¹è±¡
    * @param oid ä¸»é”®
    * @return  æ•°æ®å¯¹è±¡
    */
   private CodeClassify selectByOid(String oid){
      CodeClassify codeClassifyEntity = codeClassifyMapper.selectById(oid.trim());
      if(codeClassifyEntity == null || StringUtils.isBlank(codeClassifyEntity.getOid())){
         throw new ServiceException("dataOidNotExist");//根据主键id未查到相关数据
      }
      return codeClassifyEntity;
   }
   /**
    * æ ¡éªŒæ˜¯å¦å¯ä»¥åˆ é™¤ï¼Œå¦‚果存在下级,并且下级有数据引用则不能删除
    * @param codeClassifyEntity æ•°æ®åº“中的数据对象
    * @return success为true为可以删除,false表示有数据引用,obj为true表示有下级
    */
   private R checkIsCanDeleteForDO(CodeClassify codeClassifyEntity) {
      //检查ts
//      Map<String,Object> condition = new HashMap<>(2);
//      condition.put("oid",codeClassifyEntity.getOid());
//      condition.put("ts",codeClassifyEntity.getTs());
      CodeClassify detail = codeClassifyMapper.selectOne(Condition.getQueryWrapper(codeClassifyEntity));
//         .selectOne(Condition.getQueryWrapper(condition,CodeClassify.class));
      if(detail == null){//不是最新的不让改
         throw new ServiceException("当前数据不是最新,请刷新后再修改!");
//         return R.fail("当前数据不是最新,请刷新后再修改!");
      }
      //校验下级是否有引用
      if(checkChildIsLinked(detail.getOid())){
         return R.fail("dataCascadeLinkedNotDelete");
      }
      return R.data(checkHasChild(detail.getOid()));
   }
   /**
    * æ£€æŸ¥æ˜¯å¦æœ‰ä¸‹çº§æ˜¯å¦å…³è”了数据
    *
    * @param oid ä¸»é”®
    * @return true è¡¨ç¤ºæœ‰å¼•用,false表示没有引用
    */
   @Override
   public boolean checkChildIsLinked(String oid) {
      Map<String,String> childOids = codeClassifyMapper.selectAllLevelChildOid(oid.trim());
      if(!CollectionUtils.isEmpty(childOids)){
         for(String childOid: childOids.keySet()){
            if(!checkIsLinked(childOid)){
               return false;
            }
         }
         return true;
      }
      return false;
   }
   /**
    * æ ¡éªŒæ˜¯å¦è¢«å¼•用
    * @param oid ä¸»é”®
    */
   private boolean checkIsLinked(String oid) {
      //TODO æ·»åŠ éœ€è¦æ ¡éªŒå¼•ç”¨çš„åœ°æ–¹
      return false;
   }
   @Override
   public boolean checkHasChild(String oid) {
      if(StringUtils.isBlank(oid)){
         throw new ServiceException("oid不能为空!");
      }
      return codeClassifyMapper.checkHasChild(oid.trim());
   }
   /**
    * åˆ é™¤ä¸»é¢˜åº“分类
    * @param codeClassify ä¸»é¢˜åº“分类数据传输对象,oid和ts需要传输
    * @return åˆ é™¤ç»“果反馈::success:成功,fail:失败
    */
   @Override
   public R deleteCodeClassify(CodeClassify codeClassify) {
      if(codeClassify == null || codeClassify.getOid() == null){
         throw new ServiceException("传入参数不能为空!");
      }
      codeClassify = codeClassifyMapper.selectById(codeClassify.getOid());
      R result = checkIsCanDeleteForDO(codeClassify);
      //先简称是否有关联模板,有模板要先删除
      Map<String,Object> condition = new HashMap<>(2);
      condition.put("codeClassifyOid",codeClassify.getOid());
      List<CodeClstemplateEntity> codeClstemplateEntities = codeClstemplateMapper.selectByMap(condition);
//      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(CodeClassifyTemplateDO.class);
//      queryWrapper.addQueryMap("codeClassifyOid",codeClassifyDTO.getOid());
//      List<CodeClassifyTemplateDO> codeClassifyTemplateDOListHaveTemplate =  codeClassifyTemplateMapper.selectByWrapper(queryWrapper);
      if(codeClstemplateEntities.size()>0){
         return R.fail("分类关联模板,请先删除!");
      }
      //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。
      //1、查询要删除的父类数据
      List<CodeClassify> deletes = new ArrayList<CodeClassify>();
      deletes.add(codeClassify);
      if(result.isSuccess()) {
         //找下级的,这个是可以删除的时候
         Map<String,String> childrenOids = codeClassifyMapper.selectAllLevelChildOid(codeClassify.getOid().trim());
         if (!CollectionUtils.isEmpty(childrenOids)) {
            Collection<Collection<String>> childrenCollections = VciBaseUtil.switchCollectionForOracleIn(childrenOids.keySet());
            for(Collection<String> s : childrenCollections){
               //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。
               //2、查询要删除的子类数据
               List<CodeClassify>  codeClassifyDOList = codeClassifyMapper.selectBatchIds(s);
               deletes.addAll(codeClassifyDOList);
               codeClassifyMapper.deleteBatchIds(s);
            }
         }
      }else{
         return result;
      }
      //执行删除操作
      int deleteCount = codeClassifyMapper.deleteById(codeClassify.getOid());
      //处理数据集成逻辑,成功后执行集成第一步
      for (CodeClassify codeClassifyTemp:deletes){
         //codeDuckingServiceI.insertCache1(CACHE_TYPE_CLASSIFY_DELETE,FRAMEWORK_DATA_DISABLED,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, codeClassifyDO1.getOid(), DateUtils.addHours(new Date(),1));//这里是当前时间
         //存储要删除的数据
//         CacheUtil.put();
         CacheUtil.put("ubcs:code", "bean:id:", codeClassifyTemp.getOid(), codeClassifyTemp);
//         codeDuckingServiceI.cacheDeleteData(codeClassifyTemp.getOid(), codeClassifyTemp);
      }
      return R.data(deleteCount>0);
//      return null;
   }
   /**
    * å¯ç”¨ã€åœç”¨
    * @param oid ä¸»é”®
    * @param lcStatus çŠ¶æ€
    * @return æ‰§è¡Œç»“æžœ
    */
   @Override
   public R updateLcStatus(String oid, String lcStatus){
      //查询修改前ts
      CodeClassify codeClassify = codeClassifyMapper.selectById(oid);//主要是为了查询ts
      codeClassify.setLcStatus(lcStatus);
      codeClassify.setTs(new Date());
      codeClassify.setLastModifyTime(new Date());
      codeClassify.setLastModifier(AuthUtil.getUser().getUserName());
      //启用、停用
//      int u = codeClassifyMapper.updateLcStatus(oid,lcStatus);
      int count = codeClassifyMapper.updateById(codeClassify);
//        //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。
//        if(u!=0) {
//            codeDuckingServiceI.insertCache1(lcStatus,lcStatus,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, oid, codeClassifyDO_old.getTs());
//        }
      return R.data(SqlHelper.retBool(count));
   }
   /**
    * ä¸»é”®æ‰¹é‡èŽ·å–ä¸»é¢˜åº“åˆ†ç±»
    * @param oidCollections ä¸»é”®é›†åˆï¼Œä½†æ˜¯å—性能影响,建议一次查询不超过10000个
    * @return ä¸»é¢˜åº“分类显示对象
    */
   @Override
   public Collection<CodeClassifyVO> listCodeClassifyByOids(Collection<String> oidCollections) {
      VciBaseUtil.alertNotNull(oidCollections,"数据对象主键集合");
      List<CodeClassify> codeClassifyDOList = listCodeClassifyDOByOidCollections(oidCollections);
      return codeClassifyDO2VOs(codeClassifyDOList);
   }
   /**
    * ä½¿ç”¨ä¸»é”®é›†åˆæŸ¥è¯¢æ•°æ®å¯¹è±¡
    * @param oidCollections ä¸»é”®çš„集合
    * @return æ•°æ®å¯¹è±¡åˆ—表
    */
   private List<CodeClassify> listCodeClassifyDOByOidCollections(Collection<String> oidCollections){
      List<CodeClassify> codeClassifyList = new ArrayList<CodeClassify>();
      if(!CollectionUtils.isEmpty(oidCollections)){
         Collection<Collection<String>> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections);
         for(Collection<String> oids: oidCollectionsList){
            List<CodeClassify> tempDOList =  codeClassifyMapper.selectBatchIds(oids);
            if(!CollectionUtils.isEmpty(tempDOList)){
               codeClassifyList.addAll(tempDOList);
            }
         }
      }
      return  codeClassifyList;
   }
   /**
    * æ‰¹é‡æ•°æ®å¯¹è±¡è½¬æ¢ä¸ºæ˜¾ç¤ºå¯¹è±¡
    * @param codeClassifys æ•°æ®å¯¹è±¡åˆ—表
    * @return æ˜¾ç¤ºå¯¹è±¡
    */
   @Override
   public List<CodeClassifyVO> codeClassifyDO2VOs(Collection<CodeClassify>  codeClassifys) {
      List<CodeClassifyVO> voList = new ArrayList<CodeClassifyVO>();
      if(!CollectionUtils.isEmpty(codeClassifys)){
         for(CodeClassify s: codeClassifys){
            CodeClassifyVO vo =  codeClassifyDO2VO(s);
            if(vo != null){
               voList.add(vo);
            }
         }
      }
      return voList;
   }
   /**
    * æ•°æ®å¯¹è±¡è½¬æ¢ä¸ºæ˜¾ç¤ºå¯¹è±¡
    * @param  codeClassify æ•°æ®å¯¹è±¡
    * @return æ˜¾ç¤ºå¯¹è±¡
    */
   @Override
   public  CodeClassifyVO codeClassifyDO2VO(CodeClassify codeClassify) {
      CodeClassifyVO vo = new CodeClassifyVO();
      if(codeClassify != null){
         BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassify,vo);
         //如果有lcstatus的类的话
         vo.setLcStatusText(FrameworkDataLCStatus.getTextByValue(vo.getLcStatus()));
      }
      return vo;
   }
   /**
    * å‚ç…§æ ‘ ä¸»é¢˜åº“分类
    * @param treeQueryObject æ ‘形查询对象
    * @return ä¸»é¢˜åº“分类显示树
    */
   @Override
   public List<Tree> referTree(TreeQueryObject treeQueryObject) {
      if(treeQueryObject == null){
         treeQueryObject = new TreeQueryObject();
      }
      if(treeQueryObject.getConditionMap() == null){
         treeQueryObject.setConditionMap(new HashMap<>());
      }
      if(treeQueryObject.getConditionMap().containsKey(LC_STATUS)) {
         treeQueryObject.getConditionMap().remove(LC_STATUS);
      }
      if(treeQueryObject.getExtandParamsMap() ==null || !treeQueryObject.getExtandParamsMap().containsKey(REFER_SHOW_DISABLED_QUERY_KEY)) {
      }
      treeQueryObject.getConditionMap().put(LC_STATUS, FRAMEWORK_DATA_ENABLED);
      return treeCodeClassify(treeQueryObject);
   }
   /**
    * æŸ¥è¯¢ä¸»é¢˜åº“分类 æ ‘
    * @param treeQueryObject æ ‘查询对象
    * @return ä¸»é¢˜åº“分类 æ˜¾ç¤ºæ ‘
    */
   @Override
   public List<Tree> treeCodeClassify(TreeQueryObject treeQueryObject) {
      List<CodeClassify> doList =codeClassifyMapper.selectCodeClassifyVOByTree(treeQueryObject.getParentOid());
      List<CodeClassifyVO> voList = codeClassifyDO2VOs(doList);
      TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(PARENT_FIELD_NAME.toLowerCase(Locale.ROOT));
      treeWrapperOptions.copyFromTreeQuery(treeQueryObject);
      List<Tree> tree= revisionModelUtil.doList2Trees(voList,treeWrapperOptions,(CodeClassifyVO s) ->{
         //可以在这里处理树节点的显示
         return s.getId() + " " + s.getName() + (FrameworkDataLCStatus.DISABLED.getValue().equalsIgnoreCase(s
            .getLcStatus()) ? (" ã€åœç”¨ã€‘ ") : "");
      });
      Iterator var6 =  tree.listIterator();
      while(var6.hasNext()){
         Tree trees = (Tree) var6.next();
         boolean checkHasChild=codeClassifyMapper.checkHasChild(trees.getOid());
         if(checkHasChild){
            trees.setLeaf(false);
         }else{
            trees.setLeaf(true);
         }
      }
      return tree;
   }
//   /**
//    * æ ¹æ®æ ‘形查询对象来查询数据对象
//    *
//    * @param treeQueryObject æ ‘形查询对象
//    * @return æŸ¥è¯¢ç»“æžœ,数据对象
//    */
//   @Override
//   public List<CodeClassifyVO> selectCodeClassifyDOByTree(TreeQueryObject treeQueryObject) {
//      VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(null,CodeClassifyDO.class);
//      VciParentQueryOption parentQueryOption = new VciParentQueryOption();
//      parentQueryOption.setParentFieldName(PARENT_FIELD_NAME);
//      queryWrapperForDO.parentQueryChild(treeQueryObject,parentQueryOption);
//      if(StringUtils.isBlank(treeQueryObject.getSort())) {
//         PageHelper pageHelper = new PageHelper(-1);
//         pageHelper.addDefaultAsc("id");
//         queryWrapperForDO.setPageHelper(pageHelper);
//      }
//      return codeClassifyMapper.selectByWrapper(queryWrapperForDO);
//   }
   /**
    * å¯¼å‡ºåˆ†ç±»
    *
    * @param oid åˆ†ç±»ä¸»é”®
    * @return excel文件路径
    */
   @Override
   public String exportClassify(String oid) {
      VciBaseUtil.alertNotNull(oid,"分类的主键");
      CodeClassify codeClassify = codeClassifyMapper.selectById(oid);
      codeClassify.setDataLevel(0);
      codeClassify.setPath(codeClassify.getId());
      List<CodeClassifyVO> codeClassifyVOS = listChildrenClassify(oid, true, "id", false);
      if(codeClassifyVOS ==null){
         codeClassifyVOS = new ArrayList<>();
      }
      CodeClassifyVO codeClassifyVO = new CodeClassifyVO();
      BeanUtils.copyProperties(codeClassify,codeClassifyVO);
      codeClassifyVOS.add(codeClassifyVO);
      //查询一下规则的编号,和关键属性重复规则
      List<String> codeRuleOids = codeClassifyVOS.stream().filter(s -> StringUtils.isNotBlank(s.getCoderuleoid())).map(CodeClassifyVO::getCoderuleoid).collect(Collectors.toList());
      Map<String, CodeRuleVO> ruleVOMap = new HashMap<>();
      if(!CollectionUtils.isEmpty(codeRuleOids)){
         VciBaseUtil.switchCollectionForOracleIn(codeRuleOids).stream().forEach(ruleOids->{
//            Collection<CodeRuleVO> ruleVOS = codeRuleService.listCodeRuleByOids(ruleOids);
            Collection<CodeRuleVO> ruleVOS = null;
            ruleVOMap.putAll( Optional.ofNullable(ruleVOS).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getOid(),t->t)));
         });
      }
      //找关键属性规则
      List<String> keyRuleOids = codeClassifyVOS.stream().filter(s -> StringUtils.isNotBlank(s.getCodekeyattrrepeatoid())).map(CodeClassifyVO::getCodekeyattrrepeatoid).collect(Collectors.toList());
      Map<String, CodeKeyAttrRepeatRuleVO> keyRuleVOMap = new HashMap<>();
      if(!CollectionUtils.isEmpty(keyRuleOids)){
         VciBaseUtil.switchCollectionForOracleIn(keyRuleOids).stream().forEach(ruleOids->{
            Collection<CodeKeyAttrRepeatRuleVO> ruleVOS = iCodeKeyattrrepeatService.listCodeKeyAttrRepeatRuleByOids(ruleOids);
            keyRuleVOMap.putAll( Optional.ofNullable(ruleVOS).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getOid(),t->t)));
         });
      }
      //ok,写excel
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + "导出分类.xls";
      try {
         new File(excelName).createNewFile();
      } catch (Throwable e) {
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e);
      }
      List<WriteExcelData> excelDataList = new ArrayList<>();
      excelDataList.add(new WriteExcelData(0,0,"分类编号"));
      excelDataList.add(new WriteExcelData(0,1,"分类名称"));
      excelDataList.add(new WriteExcelData(0,2,"业务类型编号"));
      excelDataList.add(new WriteExcelData(0,3,"业务类型名称"));
      excelDataList.add(new WriteExcelData(0,4,"编码规则编号"));
      excelDataList.add(new WriteExcelData(0,5,"编码规则名称"));
      excelDataList.add(new WriteExcelData(0,6,"查重规则编号"));
      excelDataList.add(new WriteExcelData(0,7,"查重规则名称"));
      excelDataList.add(new WriteExcelData(0,8,"分类路径"));
      excelDataList.add(new WriteExcelData(0,9,"状态"));
      excelDataList.add(new WriteExcelData(0,10,"分类层级"));
      excelDataList.add(new WriteExcelData(0,11,"描述"));
      for (int i = 0; i < codeClassifyVOS.size(); i++) {
         CodeClassifyVO vo = codeClassifyVOS.get(i);
         excelDataList.add(new WriteExcelData(i+1,0,vo.getId()));
         excelDataList.add(new WriteExcelData(i+1,1,vo.getName()));
         excelDataList.add(new WriteExcelData(i+1,2,vo.getBtmtypeid()));
         excelDataList.add(new WriteExcelData(i+1,3,vo.getBtmtypename()));
         excelDataList.add(new WriteExcelData(i+1,4, StringUtils.isNotBlank(vo.getCoderuleoid())?ruleVOMap.getOrDefault(vo.getCoderuleoid(),new CodeRuleVO()).getId():""));
         excelDataList.add(new WriteExcelData(i+1,5, StringUtils.isNotBlank(vo.getCoderuleoid())?ruleVOMap.getOrDefault(vo.getCoderuleoid(),new CodeRuleVO()).getName():""));
         excelDataList.add(new WriteExcelData(i+1,6, StringUtils.isNotBlank(vo.getCodekeyattrrepeatoid())?keyRuleVOMap.getOrDefault(vo.getCodekeyattrrepeatoid(),new CodeKeyAttrRepeatRuleVO()).getId():""));
         excelDataList.add(new WriteExcelData(i+1,7, StringUtils.isNotBlank(vo.getCodekeyattrrepeatoid())?keyRuleVOMap.getOrDefault(vo.getCodekeyattrrepeatoid(),new CodeKeyAttrRepeatRuleVO()).getName():""));
         excelDataList.add(new WriteExcelData(i+1,8,vo.getOid().equalsIgnoreCase(codeClassify.getOid())?vo.getPath():codeClassify.getPath() + vo.getPath()));
         excelDataList.add(new WriteExcelData(i+1,9,FrameworkDataLCStatus.getTextByValue(vo.getLcStatus())));
         excelDataList.add(new WriteExcelData(i+1,10,vo.getDataLevel()));
         excelDataList.add(new WriteExcelData(i+1,11,vo.getDescription()));
      }
      WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
      ExcelUtil.writeDataToFile(excelName, excelOption);
      return excelName;
   }
   /**
    * èŽ·å–å­çº§çš„ä¸»é¢˜åº“åˆ†ç±»
    *
    * @param codeClassifyOid åˆ†ç±»çš„主键
    * @param allLevel        æ˜¯å¦æ‰€æœ‰çš„层级
    * @param fieldInPath åœ¨è·¯å¾„中的字段
    * @param enable æ˜¯å¦åªæ˜¾ç¤ºå¯ç”¨
    * @return åˆ†ç±»çš„æ˜¾ç¤ºå¯¹è±¡
    */
   @Override
   public List<CodeClassifyVO> listChildrenClassify(String codeClassifyOid, boolean allLevel, String fieldInPath, boolean enable) {
      if(allLevel){
         List<CodeClassify> classifyDOS = codeClassifyMapper.selectAllLevelChildHasPath(codeClassifyOid);
         if(!CollectionUtils.isEmpty(classifyDOS)){
            classifyDOS = classifyDOS.stream().filter(s->FRAMEWORK_DATA_ENABLED.equalsIgnoreCase(s.getLcStatus())).collect(Collectors.toList());
         }
         return codeClassifyDO2VOs(classifyDOS);
      }else{
         //只查询一条,那path就没必要查询了
         Map<String,Object> conditionMap = new HashMap<>();
         conditionMap.put("parentcodeclassifyoid",codeClassifyOid);
         if (enable){
            conditionMap.put("lcstatus",FRAMEWORK_DATA_ENABLED);
         }
         return codeClassifyDO2VOs(codeClassifyMapper.selectByMap(conditionMap));
      }
   }
   /**
    * åˆ›å»ºå¯¼å…¥æ¨¡æ¿
    *
    * @return excel文件路径
    */
   @Override
   public String createImportExcel() {
      //ok,写excel
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + "分类导入模板.xls";
      try {
         new File(excelName).createNewFile();
      } catch (Throwable e) {
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e);
      }
      List<WriteExcelData> excelDataList = new ArrayList<>();
      WriteExcelData excelData = new WriteExcelData(0, 0, "分类编号");
      excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
      excelDataList.add(excelData);
      WriteExcelData excelData1 = new WriteExcelData(0, 1, "分类名称");
      excelData1.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
      excelDataList.add(excelData1);
      excelDataList.add(new WriteExcelData(0,2,"业务类型编号"));
      excelDataList.add(new WriteExcelData(0,3,"编码规则编号"));
      excelDataList.add(new WriteExcelData(0,4,"查重规则编号"));
      WriteExcelData excelData2 = new WriteExcelData(0, 5, "分类路径");
      excelData2.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
      excelDataList.add(excelData2);
      excelDataList.add(new WriteExcelData(0,6,"状态"));
      WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
      ExcelUtil.writeDataToFile(excelName, excelOption);
      return excelName;
   }
   /**
    * å¯¼å…¥åˆ†ç±»
    *
    * @param file1 æ–‡ä»¶çš„信息
    * @return é”™è¯¯æ–‡ä»¶çš„地址
    */
   @Override
   public void importClassify(File file1) {
      VciBaseUtil.alertNotNull(file1,"excel文件");
      if(!file1.exists()){
         throw new VciBaseException("导入的excel文件不存在,{0}",new String[]{file1.getPath()});
      }
      ReadExcelOption excelOption = new ReadExcelOption();
      List<CodeClassifyPO> poList = null;
      try{
         poList = ExcelUtil.readDataObjectFromExcel(file1,CodeClassifyPO.class,excelOption,(value,po,fieldName)->{
            po.setLcStatus(FrameworkDataLCStatus.getValueByText(po.getLcStatusText()));
            if(StringUtils.isBlank(po.getLcStatusText())){
               po.setLcStatus(FrameworkDataLCStatus.ENABLED.getValue());
            }
         });
      }catch (Exception e){
         if(logger.isErrorEnabled()){
            logger.error("读取excel内容的时候出现了错误",e);
         }
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
      }
      //去除整行都是空的情况
      if(CollectionUtils.isEmpty(poList)){
         throw new VciBaseException(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{});
      }
      poList = poList.stream().filter(s->!(StringUtils.isBlank(s.getId()) && StringUtils.isBlank(s.getName()) && StringUtils.isBlank(s.getPath()))).collect(Collectors.toList());
      List<CodeClassify> codeClassify = new ArrayList<>();
      //看看路径是否有重复
      Map<String/**路径**/, Long/**个数**/> pathCountMap = poList.stream().filter(s->StringUtils.isNotBlank(s.getPath())).collect(Collectors.groupingBy(s -> s.getPath(), Collectors.counting()));
      List<String> repeatPaths = Optional.ofNullable(pathCountMap).orElse(new HashMap<>()).entrySet().stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey()).collect(Collectors.toList());
      if(!CollectionUtils.isEmpty(repeatPaths)){
         //有重复的内容
         List<String> rowIndexList = new ArrayList<>();
         poList.stream().forEach(po->{
            if(repeatPaths.contains(po.getPath())){
               rowIndexList.add(po.getRowIndex());
            }
         });
         throw new VciBaseException("路径有重复,{0}",new String[]{rowIndexList.stream().collect(Collectors.joining(","))});
      }
      //编号获取业务类型服务
      List<String> ruleOids = poList.stream().filter(
            s -> StringUtils.isNotBlank(s.getCodeRuleId()))
         .map(CodeClassifyPO::getCodeRuleId)
         .collect(Collectors.toList());
      Map<String, CodeRuleVO> ruleVOMap = Optional.ofNullable(ruleOids.size()==0 ? null:codeRuleService.listCodeRuleByOids(ruleOids)
      ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2));
      List<String> keyOids = poList.stream().filter(s -> StringUtils.isNotBlank(s.getKeyRepeatRuleId()))
         .map(CodeClassifyPO::getKeyRepeatRuleId).collect(Collectors.toList());
      Map<String,CodeKeyAttrRepeatRuleVO> keyRuleVOMap =Optional.ofNullable(keyOids.size()==0 ? null: iCodeKeyattrrepeatService.listCodeKeyAttrRepeatRuleByOids(keyOids)
      ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2));
      List<String> btmOids = poList.stream().filter(s -> StringUtils.isNotBlank(s.getKeyRepeatRuleId()))
         .map(CodeClassifyPO::getBtmTypeId).collect(Collectors.toList());
      Map<String, CodeOsbtmtypeEntity> btmVOMap = Optional.ofNullable(btmOids.size()==0 ? null: codeOsbtmtypeMapper.selectBatchIds(btmOids)
      ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2));
//      Map<String, CodeOsbtmtypeVO> btmVOMap = null;
      Map<String/**路径**/,String/**主键**/> oidPathMap = new HashMap<>();
      //我们需要查询所有已经存在的分类,主要是路径,用来判断分类的数据
      List<CodeClassify> existClassifyDOs = codeClassifyMapper.selectAllLevelChildHasPath("");
      Map<String/**路径**/, CodeClassify/**已经存在的数据**/> pathDOMap = Optional.ofNullable(existClassifyDOs).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> {
         String path = s.getPath();
         if(StringUtils.isNotBlank(path) && path.startsWith("#")){
            return path.substring(1);
         }
         return path;
      }, t -> t));
      poList.stream().forEach(po->{
         CodeClassify classify = new CodeClassify();
         VciBaseUtil.alertNotNull(po.getId(),"分类编号",po.getName(),"分类名称",po.getPath(),"分类路径");
         if(StringUtils.isNotBlank(po.getBtmTypeId()) && !btmVOMap.containsKey(po.getBtmTypeId().toLowerCase(Locale.ROOT))){
            throw new VciBaseException("第{0}行的业务类型{1}在系统中不存在",new String[]{String.valueOf(VciBaseUtil.getInt(po.getRowIndex())+1),po.getBtmTypeId()});
         }
         if(StringUtils.isNotBlank(po.getCodeRuleId()) && !ruleVOMap.containsKey(po.getCodeRuleId().toLowerCase(Locale.ROOT))){
            throw new VciBaseException("第{0}行的编码规则{1}在系统中不存在",new String[]{String.valueOf(po.getRowIndex()+1),po.getCodeRuleId()});
         }
         if(StringUtils.isNotBlank(po.getKeyRepeatRuleId()) && !keyRuleVOMap.containsKey(po.getKeyRepeatRuleId().toLowerCase(Locale.ROOT))){
            throw new VciBaseException("第{0}行的关键属性查重规则{1}在系统中不存在",new String[]{String.valueOf(po.getRowIndex()+1),po.getKeyRepeatRuleId()});
         }
         classify.setOid(VciBaseUtil.getPk());
         classify.setId(po.getId());
         classify.setName(po.getName());
         classify.setDescription(po.getDescription());
         oidPathMap.put(po.getPath(),classify.getOid());
         if(StringUtils.isNotBlank(po.getBtmTypeId())){
            CodeOsbtmtypeVO typeVO = (CodeOsbtmtypeVO)btmVOMap.get(po.getBtmTypeId().toLowerCase(Locale.ROOT));
            classify.setBtmTypeId(typeVO.getId());
            classify.setBtmTypeName(typeVO.getName());
         }
         if(StringUtils.isNotBlank(po.getCodeRuleId())){
            CodeRuleVO codeRuleVO = ruleVOMap.get(po.getCodeRuleId().toLowerCase(Locale.ROOT));
            classify.setCodeRuleOid(codeRuleVO.getOid());
         }
         if(StringUtils.isNotBlank(po.getKeyRepeatRuleId())){
            CodeKeyAttrRepeatRuleVO repeatRuleVO = keyRuleVOMap.get(po.getKeyRepeatRuleId());
            classify.setCodeKeyAttrRepeatOid(repeatRuleVO.getOid());
         }
         classify.setLcStatus(po.getLcStatus());
         classify.setPath(po.getPath());
         codeClassify.add(classify);
      });
      //要看存在的,修改路径对应的主键
      Map<String/**路径**/,String/**主键**/> catchedOidPathMap = new HashMap<>();
      if(!CollectionUtils.isEmpty(oidPathMap)){
         oidPathMap.forEach((path,oid)->{
            if(pathDOMap.containsKey(path)){
               //说明存在
               catchedOidPathMap.put(path,pathDOMap.get(path).getOid());
            }else{
               catchedOidPathMap.put(path,oid);
            }
         });
      }
      List<CodeClassify> addClassifyDOList = new ArrayList<>();
      List<CodeClassify> editClassifyDOList = new ArrayList<>();
      codeClassify.stream().forEach(classifyDO->{
         //要看上级是不是存在哦
         String parentPath = classifyDO.getPath();
         if(parentPath.contains("#")) {
            parentPath = parentPath.substring(0, parentPath.lastIndexOf("#"));
         }
         if((!catchedOidPathMap.containsKey(parentPath) && !pathDOMap.containsKey(parentPath) )&& !classifyDO.getPath().equalsIgnoreCase(classifyDO.getId())){
            throw new VciBaseException("分类编号[{0}],分类名称[{1}],路径为[{2}]的上级分类在系统中,在本次导入的数据和系统中均没有找到",new String[]{classifyDO.getId(),classifyDO.getName(),classifyDO.getPath()});
         }
         if (!classifyDO.getPath().equalsIgnoreCase(classifyDO.getId())){
            //不是顶级的时候,要设置上级的主键
            classifyDO.setParentCodeClassifyOid(catchedOidPathMap.containsKey(parentPath)?catchedOidPathMap.get(parentPath):pathDOMap.get(parentPath).getOid());
         }
         if(classifyDO.getPath().equalsIgnoreCase(classifyDO.getId()) && StringUtils.isBlank(classifyDO.getBtmTypeId())){
            throw new VciBaseException("分类编号[{0}],分类名称[{1}],是顶层分类,需要设置业务类型编号",new String[]{classifyDO.getId(),classifyDO.getName()});
         }
         if(pathDOMap.containsKey(classifyDO.getPath())){
            //存在,需要修改对象
            classifyDO.setOid(catchedOidPathMap.get(classifyDO.getPath()));
            CodeClassify classifyDOInDB = pathDOMap.get(classifyDO.getPath());
            classifyDOInDB.setOid(classifyDO.getOid());
            classifyDOInDB.setId(classifyDO.getId());
            classifyDOInDB.setName(classifyDO.getName());
            classifyDOInDB.setDescription(classifyDO.getDescription());
            classifyDOInDB.setBtmTypeId(classifyDO.getBtmTypeId());
            classifyDOInDB.setBtmTypeName(classifyDO.getBtmTypeName());
            classifyDOInDB.setCodeRuleOid(classifyDO.getCodeRuleOid());
            classifyDOInDB.setCodeRuleOidName(classifyDO.getCodeRuleOidName());
            classifyDOInDB.setParentCodeClassifyOid(classifyDO.getParentCodeClassifyOid());
            classifyDOInDB.setCodeKeyAttrRepeatOid(classifyDO.getCodeKeyAttrRepeatOid());
            classifyDOInDB.setCodeKeyAttrRepeatOidName(classifyDO.getCodeKeyAttrRepeatOidName());
            if(classifyDOInDB.getOrderNum() == null){
               classifyDOInDB.setOrderNum(0);
            }
            editClassifyDOList.add(classifyDOInDB);
         }else{
            //是新的,直接添加就行了
            //判断号怎么处理?
            classifyDO.setOrderNum(0);
            addClassifyDOList.add(classifyDO);
         }
      });
      if(!CollectionUtils.isEmpty(editClassifyDOList)){
         VciBaseUtil.switchCollectionForOracleIn(editClassifyDOList).stream().forEach(
//            classifyDOs->{codeClassifyMapper..updateById(classifyDOs.stream().collect(Collectors.toList()));
            classifyDos->{
               for (CodeClassify classifyDo : classifyDos) {
                  codeClassifyMapper.updateById(classifyDo);
               }
//            }
            });
      }
      if(!CollectionUtils.isEmpty(addClassifyDOList)){
//         revisionModelUtil.wrapperForBatchAdd(addClassifyDOList);
         VciBaseUtil.switchCollectionForOracleIn(addClassifyDOList).stream().forEach(classifyDOs->{
            for (CodeClassify classifyDO : classifyDOs) {
               classifyDO.setCreateTime(new Date());
               classifyDO.setTs(new Date());
               classifyDO.setBtmname("codeclassify");
               classifyDO.setLcStatus("Enabled");
               classifyDO.setOwner(AuthUtil.getUser().getUserName());
               classifyDO.setCreator(AuthUtil.getUser().getUserName());
               classifyDO.setLastModifier(AuthUtil.getUser().getUserName());
               classifyDO.setLastModifyTime(new Date());
               codeClassifyMapper.insert(classifyDO);
            }
//            codeClassifyMapper.batchInsert(classifyDOs.stream().collect(Collectors.toList()));
         });
      }
   }
   /**
    * èŽ·å–åˆ†ç±»å…³è”çš„å±žæ€§
    *
    * @param baseQueryObject æŸ¥è¯¢å¯¹è±¡ï¼Œå¿…须有codeClassifyOid,支持id和name两种查询条件
    * @return å±žæ€§çš„信息,包含默认的属性
    */
   @Override
   public DataGrid<CodeOsattributeVO> listClassifyLinkAttr(BaseQueryObject baseQueryObject) {
      if(baseQueryObject == null){
         baseQueryObject = new BaseQueryObject();
      }
      if(baseQueryObject.getConditionMap() == null){
         baseQueryObject.setConditionMap(new HashMap<>());
      }
      String classifyOid = baseQueryObject.getConditionMap().getOrDefault("codeClassifyOid","");
      String id = baseQueryObject.getConditionMap().getOrDefault("id","");
      String name = baseQueryObject.getConditionMap().getOrDefault("name","");
      if(StringUtils.isBlank(classifyOid)){
         return new DataGrid<>();
      }
      CodeClassifyVO topClassifyVO = getTopClassifyVO(classifyOid);
      if(topClassifyVO == null || StringUtils.isBlank(topClassifyVO.getBtmtypeid())){
         return new DataGrid<>();
      }
      Map<String,Object> condition = new HashMap<>(1);
      condition.put("pkbtmtype",topClassifyVO.getBtmtypeid());
      List<CodeOsbtmtypeattributeEntity> unDefaultAttributes = codeOsbtmtypeattributeMapper.selectByMap(condition);
//      List<OsBtmTypeAttributeVO> unDefaultAttributes = btmService. (topClassifyVO.getBtmtypeid());
      List<CodeOsattributeVO> attributeVOS = new ArrayList<>();
      if(!CollectionUtils.isEmpty(unDefaultAttributes)){
         unDefaultAttributes.stream().forEach(attr->{
            CodeOsattributeVO attributeVO = new CodeOsattributeVO();
            BeanUtils.copyProperties(attr,attributeVO);
            attributeVO.setAttributedatatype(attr.getAttrdatatype());
            attributeVO.setAttrlength(Short.valueOf(attr.getAttributelength()));
            attributeVO.setBtmtypeid(attr.getReferbtmtypeid());
            attributeVO.setBtmtypename(attr.getReferbtmtypename());
            boolean add = true;
            if(StringUtils.isNotBlank(id) && !attributeVO.getId().contains(id.replace("*",""))){
               add = false;
            }
            if(StringUtils.isNotBlank(name) && !attributeVO.getId().contains(name.replace("*",""))){
               add = false;
            }
            if(add){
               attributeVOS.add(attributeVO);
            }
         });
      }
//      if(!CollectionUtils.isEmpty(attributeService.getDefaultAttributeVOs())){
//         attributeService.getDefaultAttributeVOs().stream().forEach(attr->{
//            boolean add = true;
//            if(StringUtils.isNotBlank(id) && !attr.getId().contains(id.replace("*",""))){
//               add = false;
//            }
//            if(StringUtils.isNotBlank(name) && !attr.getId().contains(name.replace("*",""))){
//               add = false;
//            }
//            if(add){
//               attributeVOS.add(attr);
//            }
//         });
//      }
      DataGrid<CodeOsattributeVO> dataGrid = new DataGrid<>();
      dataGrid.setData(attributeVOS);
      dataGrid.setTotal(attributeVOS.size());
      return dataGrid;
   }
   /**
    * èŽ·å–å½“å‰åˆ†ç±»çš„é¡¶å±‚åˆ†ç±»
    *
    * @param codeClassifyOid åˆ†ç±»çš„主键
    * @return é¡¶å±‚分类的信息
    */
   @Override
   public CodeClassifyVO getTopClassifyVO(String codeClassifyOid) {
      VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
//      List<Map<String,Object>> classifyDOS = codeClassifyMapper.selectAllLevelParentByOid(codeClassifyOid);
      List<CodeClassify> classifyDOS = selectAllLevelParentByOid(codeClassifyOid);
      if(!CollectionUtils.isEmpty(classifyDOS)){
         CodeClassify classifyDO = classifyDOS.stream().filter(s -> StringUtils.isBlank(s.getParentCodeClassifyOid())).findFirst().orElseGet(() -> null);
         if(classifyDO!=null){
            return codeClassifyDO2VO(classifyDO);
         }
      }
      return null;
   }
   /**
    * èŽ·å–å½“å‰åˆ†ç±»çš„æ‰€æœ‰ä¸Šçº§åˆ†ç±»ï¼ˆå«æœ¬æ¬¡æŸ¥è¯¢å±‚çº§å·ï¼‰
    * @param oid ä¸»é”®
    * @return æ‰€æœ‰çš„上级
    */
   @Override
   public List<CodeClassify> selectAllLevelParentByOid(String oid){
      // String sql = "select oid,level from " + VciBaseUtil.getTableName(MdmBtmTypeConstant.CODE_CLASSIFY) + " start with oid= :oid connect by prior PARENTCODECLASSIFYOID = oid ";
      // Map< String,String> conditionMap = new HashMap< String,String>();
      // conditionMap.put("oid",oid);
      List<Map<String,Object>> cbos = codeClassifyMapper.selectAllLevelParentByOid(oid);
      Map<String,String> oidLevelMap = new HashMap<>();
      Optional.ofNullable(cbos).orElseGet(()->new ArrayList<>()).stream().forEach(cbo->{
         oidLevelMap.put(cbo.get("OID").toString(),cbo.get("LEVEL").toString());
      });
      if(CollectionUtils.isEmpty(oidLevelMap)){
         return new ArrayList<>();
      }
      //使用主键查询一下
      List<CodeClassify> classifyDOS = codeClassifyMapper.selectBatchIds(oidLevelMap.keySet());
      if(!CollectionUtils.isEmpty(classifyDOS)){
         classifyDOS.stream().forEach(classifyDO->{
            classifyDO.setDataLevel(VciBaseUtil.getInt(oidLevelMap.getOrDefault(classifyDO.getOid(),"0")));
         });
      }
      return classifyDOS;
   }
   /**
    * ä½¿ç”¨ç¼–号的路径获取对象
    *
    * @param idPath ç¼–号的路径,一定要从最顶层节点开始,格式为xxx/yyy/zz è¿™æ ·
    * @return åˆ†ç±»çš„æ˜¾ç¤ºå¯¹è±¡
    */
   @Override
   public CodeClassifyVO getObjectByIdPath(String idPath) {
      List<Map<String, Object>> idPathValues = codeClassifyMapper.selectByFieldPath("/" + idPath);
      CodeClassify classifyDO = null;
      if (idPathValues != null){
         classifyDO = codeClassifyMapper.selectById(idPathValues.get(0).get("oid").toString());
      }
      return codeClassifyDO2VO(classifyDO);
   }
   /**
    * ä¸»é¢˜åº“的树
    *
    * @param treeQueryObject æ ‘形查询对象
    * @return ä¸»é¢˜åº“显示树
    */
   @Override
   public List<Tree> treeTopCodeClassify(TreeQueryObject treeQueryObject) {
      if(treeQueryObject == null){
         treeQueryObject = new TreeQueryObject();
      }
      if(treeQueryObject.getConditionMap() == null){
         treeQueryObject.setConditionMap(new HashMap<>());
      }
      treeQueryObject.getConditionMap().put(PARENT_FIELD_NAME, "=null");
      return treeCodeClassify(treeQueryObject);
   }
}