Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
@@ -5,30 +5,55 @@
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.code.bo.TreeWrapperOptions;
import com.vci.ubcs.code.bo.CodeClassifyFullInfoBO;
import com.vci.ubcs.code.entity.CodeClassify;
import com.vci.ubcs.code.entity.CodeClstemplateEntity;
import com.vci.ubcs.code.entity.CodeClassifyTemplate;
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.CodeClassifyTemplateMapper;
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.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.TreeQueryObject;
import com.vci.ubcs.com.vci.starter.revision.service.RevisionModelUtil;
import com.vci.ubcs.com.vci.starter.web.pagemodel.Tree;
import com.vci.ubcs.com.vci.starter.web.util.BeanUtilForVCI;
import com.vci.ubcs.com.vci.starter.web.util.VciBaseUtil;
import com.vci.ubcs.code.vo.pagemodel.CodeKeyAttrRepeatRuleVO;
import com.vci.ubcs.code.vo.pagemodel.CodeRuleVO;
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.model.TreeQueryObject;
import com.vci.ubcs.starter.revision.model.TreeWrapperOptions;
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.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.log.exception.ServiceException;
import com.vci.ubcs.core.log.exception.ServiceException;
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;
@@ -41,10 +66,22 @@
   private CodeClassifyMapper codeClassifyMapper;
   @Resource
   private CodeClstemplateMapper codeClstemplateMapper;
   private CodeClassifyTemplateMapper codeClassifyTemplateMapper;
   @Resource
   private ICodeRuleService codeRuleService;
   @Resource
   private CodeOsbtmtypeMapper codeOsbtmtypeMapper;
   @Resource
   CodeOsbtmtypeattributeMapper codeOsbtmtypeattributeMapper;
   @Resource
   ICodeRuleService ICodeRuleService;
   /**
    * 日志
    */
   private Logger logger = LoggerFactory.getLogger(getClass());
   /**
    * 对象的操作
    */
@@ -52,7 +89,7 @@
   private RevisionModelUtil revisionModelUtil;
   @Resource
   private ICodeKeyattrrepeatService iCodeKeyattrrepeatService;
   private ICodeKeyAttrRepeatService iCodeKeyattrrepeatService;
   /**
    * 上级节点的属性名称
    */
@@ -81,8 +118,11 @@
      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));
   }
@@ -133,7 +173,11 @@
      if(codeClassifyEntity == null || codeClassifyEntity.getOid() == null){
         return R.fail("传入数据不能为空!");
      }
      codeClassifyEntity = selectByOid(codeClassifyEntity.getOid());
      CodeClassify codeClassifyNew = selectByOid(codeClassifyEntity.getOid());
      if(codeClassifyNew == null){
         return R.fail("未查询到相关数据!");
      }
      codeClassifyNew.setTs(codeClassifyEntity.getTs());
      return checkIsCanDeleteForDO(codeClassifyEntity);
   }
@@ -159,11 +203,11 @@
   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(condition,CodeClassify.class));
//      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("当前数据不是最新,请刷新后再修改!");
@@ -210,7 +254,7 @@
      if(StringUtils.isBlank(oid)){
         throw new ServiceException("oid不能为空!");
      }
      return codeClassifyMapper.checkHasChild(oid.trim());
      return !codeClassifyMapper.checkHasChild(oid.trim());
   }
@@ -232,7 +276,7 @@
      //先简称是否有关联模板,有模板要先删除
      Map<String,Object> condition = new HashMap<>(2);
      condition.put("codeClassifyOid",codeClassify.getOid());
      List<CodeClstemplateEntity> codeClstemplateEntities = codeClstemplateMapper.selectByMap(condition);
      List<CodeClassifyTemplate> codeClstemplateEntities = codeClassifyTemplateMapper.selectByMap(condition);
//      VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(CodeClassifyTemplateDO.class);
//      queryWrapper.addQueryMap("codeClassifyOid",codeClassifyDTO.getOid());
//      List<CodeClassifyTemplateDO> codeClassifyTemplateDOListHaveTemplate =  codeClassifyTemplateMapper.selectByWrapper(queryWrapper);
@@ -256,7 +300,8 @@
               //2、查询要删除的子类数据
               List<CodeClassify>  codeClassifyDOList = codeClassifyMapper.selectBatchIds(s);
               deletes.addAll(codeClassifyDOList);
               codeClassifyMapper.deleteBatchIds(s);
//               codeClassifyMapper.deleteBatchIds(s);
               baseMapper.deleteBatchIds(s);
            }
         }
@@ -292,6 +337,9 @@
      //查询修改前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);
@@ -421,7 +469,8 @@
      return tree;
   }
   //   /**
//   /**
//    * 根据树形查询对象来查询数据对象
//    *
//    * @param treeQueryObject 树形查询对象
@@ -449,75 +498,75 @@
    */
   @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 -> org.apache.commons.lang3.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->{
      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);
//            ruleVOMap.putAll( Optional.ofNullable(ruleVOS).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getOid(),t->t)));
//         });
//      }
//      //找关键属性规则
//      List<String> keyRuleOids = codeClassifyVOS.stream().filter(s -> org.apache.commons.lang3.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, org.apache.commons.lang3.StringUtils.isNotBlank(vo.getCoderuleoid())?ruleVOMap.getOrDefault(vo.getCoderuleoid(),new CodeRuleVO()).getId():""));
//         excelDataList.add(new WriteExcelData(i+1,5, org.apache.commons.lang3.StringUtils.isNotBlank(vo.getCoderuleoid())?ruleVOMap.getOrDefault(vo.getCoderuleoid(),new CodeRuleVO()).getName():""));
//         excelDataList.add(new WriteExcelData(i+1,6, org.apache.commons.lang3.StringUtils.isNotBlank(vo.getCodekeyattrrepeatoid())?keyRuleVOMap.getOrDefault(vo.getCodekeyattrrepeatoid(),new CodeKeyAttrRepeatRuleVO()).getId():""));
//         excelDataList.add(new WriteExcelData(i+1,7, org.apache.commons.lang3.StringUtils.isNotBlank(vo.getCodekeyattrrepeatoid())?keyRuleVOMap.getOrDefault(vo.getCodekeyattrrepeatoid(),new CodeKeyAttrRepeatRuleVO()).getName():""));
//         excelDataList.add(new WriteExcelData(i+1,8,vo.getOid().equalsIgnoreCase(classifyVO.getOid())?vo.getPath():classifyVO.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 null;
//      return excelName;
            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;
   }
   /**
@@ -547,4 +596,472 @@
         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 oid 主键
    * @return 主题库分类显示对象
    * @throws VciBaseException 参数为空,数据不存在时会抛出异常
    */
   @Override
   public  CodeClassifyVO getObjectByOid(String oid) throws VciBaseException{
      return codeClassifyDO2VO(selectByOid(oid));
   }
   /**
    * 使用编号的路径获取对象
    *
    * @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);
   }
   /**
    * 获取这个分类下的业务类型,当前没有就获取上级的第一个业务类型
    * @param oid 当前分类的oid
    * @return oid,id,name,btmtypeid,btmtypename,没有就返回null
    */
   @Override
   public CodeClassify selectBtmOrParentBtm(String oid){
      List<CodeClassify> oidList = selectAllLevelParents(oid);
      return oidList.size()==0?null:oidList.get(0);
   }
   /**
    * 获取所有层级上级关联业务类型数据
    * @param oid 当前分类的oid
    * @return oid,id,name,btmtypeid,btmtypename
    */
   @Override
   public List<CodeClassify> selectAllLevelParents(String oid){
//      String sql = "select oid,id,name,btmtypeid,btmtypename from " + VciBaseUtil.getTableName(MdmBtmTypeConstant.CODE_CLASSIFY) + " where btmtypeid is not null start with oid= :oid connect by prior PARENTCODECLASSIFYOID=oid ";
//      Map< String,String> conditionMap = new HashMap< String,String>();
//      conditionMap.put("oid",oid);
//      List<Map> dataList = boService.queryBySqlForMap(sql,conditionMap);
      List<Map<String, Object>> dataList = codeClassifyMapper.selectAllLevelParents(oid);
      List<CodeClassify> oidList = new ArrayList<CodeClassify>();
      if(!CollectionUtils.isEmpty(dataList)){
         for(Map data:dataList){
            CodeClassify codeClassifyDO = new CodeClassify();
            codeClassifyDO.setOid(VciBaseUtil.getStringValueFromObject(data.get("OID")));
            codeClassifyDO.setId(VciBaseUtil.getStringValueFromObject(data.get("ID")));
            codeClassifyDO.setName(VciBaseUtil.getStringValueFromObject(data.get("NAME")));
            codeClassifyDO.setBtmTypeId(VciBaseUtil.getStringValueFromObject(data.get("BTMTYPEID")));
            codeClassifyDO.setBtmTypeName(VciBaseUtil.getStringValueFromObject(data.get("BTMTYPENAME")));
            oidList.add(codeClassifyDO);
         }
      }
      return oidList;
   }
   /**
    * 使用分类主键获取分类相关的所有信息
    *
    * @param codeClassifyOid 分类的主键
    * @return 分类上级,下级的信息
    */
   @Override
   public CodeClassifyFullInfoBO getClassifyFullInfo(String codeClassifyOid) {
      VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
      CodeClassifyFullInfoBO fullInfo = new CodeClassifyFullInfoBO();
      CodeClassify classifyDO = selectByOid(codeClassifyOid);
      //查询上级
      fullInfo.setCurrentClassifyVO(codeClassifyDO2VO(classifyDO));
      List<Map<String, Object>> maps = codeClassifyMapper.selectAllLevelParentByOid(codeClassifyOid);
      List<CodeClassify> codeClassifyList = new ArrayList<>();
      for (Map<String, Object> map : maps) {
         CodeClassify codeClassify = new CodeClassify();
         codeClassify.setOid(String.valueOf(map.get("OID")));
         codeClassify.setOid(String.valueOf(map.get("LEVEL")));
         codeClassifyList.add(codeClassify);
      }
      fullInfo.setParentClassifyVOs(codeClassifyDO2VOs(codeClassifyList));
      if(!CollectionUtils.isEmpty(fullInfo.getParentClassifyVOs())){
         fullInfo.setTopClassifyVO(fullInfo.getParentClassifyVOs().stream().filter(s->StringUtils.isBlank(s.getParentcodeclassifyoid())).findFirst().orElseGet(()->null));
      }
      return fullInfo;
   }
}