package org.springblade.code.service.impl; import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus; import com.vci.mdm.bo.CodeClassifyFullInfoBO; import com.vci.mdm.dao.CodeClassifyDaoI; import com.vci.mdm.dao.CodeClassifyTemplateDaoI; import com.vci.mdm.dto.CodeClassifyDTO; import com.vci.mdm.model.CodeClassifyDO; import com.vci.mdm.model.CodeClassifyTemplateDO; import com.vci.mdm.pagemodel.CodeClassifyVO; import com.vci.mdm.pagemodel.CodeKeyAttrRepeatRuleVO; import com.vci.mdm.pagemodel.CodeRuleVO; import com.vci.mdm.po.CodeClassifyPO; import com.vci.mdm.service.*; import com.vci.starter.poi.bo.ReadExcelOption; import com.vci.starter.poi.bo.WriteExcelData; import com.vci.starter.poi.bo.WriteExcelOption; import com.vci.starter.poi.constant.ExcelLangCodeConstant; import com.vci.starter.poi.util.ExcelUtil; import com.vci.starter.revision.bo.TreeWrapperOptions; import com.vci.starter.revision.service.RevisionModelUtil; import com.vci.starter.web.constant.QueryOptionConstant; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.*; import com.vci.starter.web.util.*; import com.vci.starter.web.wrapper.VciParentQueryOption; import com.vci.starter.web.wrapper.VciQueryWrapperForDO; import com.vci.web.pageModel.BatchCBO; import com.vci.web.pageModel.OsAttributeVO; import com.vci.web.pageModel.OsBtmTypeAttributeVO; import com.vci.web.pageModel.OsBtmTypeVO; import com.vci.web.service.OsAttributeServiceI; import com.vci.web.service.OsBtmServiceI; import com.vci.web.service.WebBoServiceI; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.util.HSSFColor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; 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.frameworkcore.constant.FrameWorkDefaultValueConstant.*; import static com.vci.frameworkcore.constant.FrameWorkLangCodeConstant.*; /** * 主题库分类服务 * @author weidy * @date 2022-01-20 */ @Service public class CodeClassifyServiceImpl implements CodeClassifyServiceI{ /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 数据操作层 */ @Resource private CodeClassifyDaoI codeClassifyMapper; /** * 业务类型操作的服务 */ @Autowired private WebBoServiceI boService; /** * 对象的操作 */ @Autowired private RevisionModelUtil revisionModelUtil; /** * 规则的服务 */ @Autowired private CodeRuleServiceI codeRuleService; /** * 关键属性的服务 */ @Autowired private CodeKeyAttrRepeatRuleServiceI keyAttrRepeatRuleService; /** * 数据集成 */ @Autowired private CodeDuckingServiceI codeDuckingServiceI; /** * 业务类型的服务 */ @Autowired private OsBtmServiceI btmService; /** * 属性服务 */ @Autowired private OsAttributeServiceI attributeService; /** * 数据操作层 */ @Resource private CodeClassifyTemplateDaoI codeClassifyTemplateMapper; /** * 上级节点的属性名称 */ public static final String PARENT_FIELD_NAME = "parentCodeClassifyOid"; /** * 查询主题库分类 树 * @param treeQueryObject 树查询对象 * @return 主题库分类 显示树 * @throws VciBaseException 查询条件不符合要求的时候会抛出异常 */ @Override public List treeCodeClassify(TreeQueryObject treeQueryObject) throws VciBaseException{ List doList =selectCodeClassifyDOByTree(treeQueryObject); List voList = codeClassifyDO2VOs(doList); TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(PARENT_FIELD_NAME.toLowerCase(Locale.ROOT)); treeWrapperOptions.copyFromTreeQuery(treeQueryObject); List 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 treeTopCodeClassify(TreeQueryObject treeQueryObject) { if(treeQueryObject == null){ treeQueryObject = new TreeQueryObject(); } if(treeQueryObject.getConditionMap() == null){ treeQueryObject.setConditionMap(new HashMap<>()); } treeQueryObject.getConditionMap().put(PARENT_FIELD_NAME, QueryOptionConstant.ISNULL); return treeCodeClassify(treeQueryObject); } /** * 根据树形查询对象来查询数据对象 * * @param treeQueryObject 树形查询对象 * @return 查询结果,数据对象 */ @Override public List 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 codeClassifyDOs 数据对象列表 * @return 显示对象 * @throws VciBaseException 参数为空或者不存在的时候会抛出异常 */ @Override public List codeClassifyDO2VOs(Collection codeClassifyDOs) throws VciBaseException{ List voList = new ArrayList(); if(!CollectionUtils.isEmpty(codeClassifyDOs)){ for(CodeClassifyDO s: codeClassifyDOs){ CodeClassifyVO vo = codeClassifyDO2VO(s); if(vo != null){ voList.add(vo); } } } return voList; } /** * 数据对象转换为显示对象 * @param codeClassifyDO 数据对象 * @return 显示对象 * @throws VciBaseException 拷贝属性出错的时候会抛出异常 */ @Override public CodeClassifyVO codeClassifyDO2VO(CodeClassifyDO codeClassifyDO) throws VciBaseException{ CodeClassifyVO vo = new CodeClassifyVO(); if(codeClassifyDO != null){ BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyDO,vo); //如果有lcstatus的类的话 vo.setLcStatusText(FrameworkDataLCStatus.getTextByValue(vo.getLcStatus())); } return vo; } /** * 增加主题库分类 * @param codeClassifyDTO 主题库分类数据传输对象 * @return 执行结果 * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常 */ @Override public CodeClassifyVO addSave(CodeClassifyDTO codeClassifyDTO) throws VciBaseException{ VciBaseUtil.alertNotNull(codeClassifyDTO,"需要添加的数据对象"); //将DTO转换为DO CodeClassifyDO codeClassifyDO = new CodeClassifyDO(); BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyDTO,codeClassifyDO); if(StringUtils.isNotBlank(codeClassifyDO.getParentCodeClassifyOid()) && StringUtils.isNotBlank(codeClassifyDO.getBtmTypeId())){ throw new VciBaseException("只有在顶层的主题库分类才能设置业务类型"); } BatchCBO cbo_insert = codeClassifyMapper.insert(codeClassifyDO); // //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理 // ClientBusinessObject[] clientBusinessObjects = cbo_insert.getCreateCboArray(); // if(clientBusinessObjects.length!=0); // { // codeDuckingServiceI.insertCache1(CACHE_TYPE_CLASSIFY_ADD,FRAMEWORK_DATA_ENABLED,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, codeClassifyDO.getOid(), DateUtils.addHours(new Date(),1)); // } return codeClassifyDO2VO(codeClassifyDO); } /** * 修改主题库分类 * @param codeClassifyDTO 主题库分类数据传输对象 * @return 执行结果 * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常 */ @Override public BaseResult editSave(CodeClassifyDTO codeClassifyDTO) throws VciBaseException{ VciBaseUtil.alertNotNull(codeClassifyDTO,"数据对象",codeClassifyDTO.getOid(),"主题库分类主键"); //检查ts CodeClassifyDO codeClassifyDOCopyFromDTO = new CodeClassifyDO(); BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyDTO,codeClassifyDOCopyFromDTO); boolean tsBoolean = boService.checkTs(codeClassifyDOCopyFromDTO); if(!tsBoolean){//不是最新的不让改 return BaseResult.fail("当前数据不是最新,请刷新后再修改!"); } //将DTO转换为DO CodeClassifyDO codeClassifyDO = selectByOid(codeClassifyDTO.getOid()); revisionModelUtil.copyFromDTOIgnore(codeClassifyDTO,codeClassifyDO); if(StringUtils.isNotBlank(codeClassifyDO.getParentCodeClassifyOid()) && StringUtils.isNotBlank(codeClassifyDO.getBtmTypeId())){ throw new VciBaseException("只有在顶层的主题库分类才能设置业务类型"); } codeClassifyMapper.updateByPrimaryKey(codeClassifyDO); // //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。只有启用状态的分类才推送 // 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 BaseResult.success(codeClassifyDO2VO(codeClassifyDO)); } /** * 检查 主题库分类是否删除 * @param codeClassifyDTO 主题库分类数据传输对象,必须要有oid和ts属性 * @return 执行结果 success为true为可以删除,false表示有数据引用,obj为true表示有下级 * @throws VciBaseException 参数为空,被引用时抛出异常 */ @Override public BaseResult checkIsCanDelete(CodeClassifyDTO codeClassifyDTO) throws VciBaseException{ VciBaseUtil.alertNotNull(codeClassifyDTO,"数据传输对象",codeClassifyDTO.getOid(),"主键"); CodeClassifyDO codeClassifyDO = selectByOid(codeClassifyDTO.getOid()); return checkIsCanDeleteForDO(codeClassifyDTO,codeClassifyDO); } /** * 校验是否可以删除,如果存在下级,并且下级有数据引用则不能删除 * @param codeClassifyDTO 数据传输对象 * @param codeClassifyDO 数据库中的数据对象 * @return success为true为可以删除,false表示有数据引用,obj为true表示有下级 */ private BaseResult checkIsCanDeleteForDO(CodeClassifyDTO codeClassifyDTO, CodeClassifyDO codeClassifyDO) { CodeClassifyDO tsDO = new CodeClassifyDO(); BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyDTO,tsDO); boService.checkTs(tsDO); //校验下级是否有引用 if(checkChildIsLinked(codeClassifyDO.getOid())){ return BaseResult.fail(DATA_CASCADE_LINKED_NOT_DELETE,new String[]{""}); } return BaseResult.success(checkHasChild(codeClassifyDO.getOid())); } /** * 检查是否有下级是否关联了数据 * * @param oid 主键 * @return true 表示有引用,false表示没有引用 * @throws VciBaseException 参数为空和有引用的时候会抛出异常 */ @Override public boolean checkChildIsLinked(String oid) throws VciBaseException { VciBaseUtil.alertNotNull(oid,"主键"); Map 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 主键 * @return true表示有下级,false表示没有下级 * @throws VciBaseException 参数错误,或者数据不存在的时候会抛出异常 */ @Override public boolean checkHasChild(String oid) throws VciBaseException { VciBaseUtil.alertNotNull(oid,"主键"); return codeClassifyMapper.checkHasChild(oid.trim()); } /** * 校验是否被引用 * @param oid 主键 * @throws VciBaseException 被引用的时候会抛出异常 */ private boolean checkIsLinked(String oid) throws VciBaseException{ //TODO 添加需要校验引用的地方 return false; } /** * 删除主题库分类 * @param codeClassifyDTO 主题库分类数据传输对象,oid和ts需要传输 * @return 删除结果反馈::success:成功,fail:失败 * @throws VciBaseException 参数为空,被引用时抛出异常 */ @Override public BaseResult deleteCodeClassify(CodeClassifyDTO codeClassifyDTO) throws VciBaseException{ VciBaseUtil.alertNotNull(codeClassifyDTO,"主题库分类数据对象",codeClassifyDTO.getOid(),"主题库分类的主键"); CodeClassifyDO codeClassifyDO = selectByOid(codeClassifyDTO.getOid()); BaseResult baseResult = checkIsCanDeleteForDO(codeClassifyDTO,codeClassifyDO); //先简称是否有关联模板,有模板要先删除 VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(CodeClassifyTemplateDO.class); queryWrapper.addQueryMap("codeClassifyOid",codeClassifyDTO.getOid()); List codeClassifyTemplateDOListHaveTemplate = codeClassifyTemplateMapper.selectByWrapper(queryWrapper); if(codeClassifyTemplateDOListHaveTemplate.size()>0){ return BaseResult.fail("分类关联模板,请先删除!"); } //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。 //1、查询要删除的父类数据 List deletes = new ArrayList(); deletes.add(codeClassifyDO); if(baseResult.isSuccess()) { //找下级的,这个是可以删除的时候 Map childrenOids = codeClassifyMapper.selectAllLevelChildOid(codeClassifyDO.getOid().trim()); if (!CollectionUtils.isEmpty(childrenOids)) { Collection> childrenCollections = VciBaseUtil.switchCollectionForOracleIn(childrenOids.keySet()); for(Collection s : childrenCollections){ //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。 //2、查询要删除的子类数据 List codeClassifyDOList = codeClassifyMapper.selectByPrimaryKeyCollection(s); deletes.addAll(codeClassifyDOList); codeClassifyMapper.batchDeleteByOids(s); } } }else{ return baseResult; } //执行删除操作 BatchCBO batchCBO = codeClassifyMapper.deleteByPrimaryKey(codeClassifyDO.getOid()); //处理数据集成逻辑,成功后执行集成第一步 for (CodeClassifyDO codeClassifyDO1:deletes){ //codeDuckingServiceI.insertCache1(CACHE_TYPE_CLASSIFY_DELETE,FRAMEWORK_DATA_DISABLED,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, codeClassifyDO1.getOid(), DateUtils.addHours(new Date(),1));//这里是当前时间 //存储要删除的数据 codeDuckingServiceI.cacheDeleteData(codeClassifyDO1.getOid(), codeClassifyDO1); } return (batchCBO!=null && batchCBO.getDeleteCbos() !=null &&batchCBO.getDeleteCbos().size() > 0)?BaseResult.successMsg(DELETE_SUCCESS):BaseResult.fail(DELETE_FAIL); } /** * 主键获取主题库分类 * @param oid 主键 * @return 主题库分类显示对象 * @throws VciBaseException 参数为空,数据不存在时会抛出异常 */ @Override public CodeClassifyVO getObjectByOid(String oid) throws VciBaseException{ return codeClassifyDO2VO(selectByOid(oid)); } /** * 主键查询数据对象 * @param oid 主键 * @return 数据对象 * @throws VciBaseException 参数为空,并且数据不存在的时候会抛出异常 */ private CodeClassifyDO selectByOid(String oid) throws VciBaseException{ VciBaseUtil.alertNotNull(oid,"主键"); CodeClassifyDO codeClassifyDO = codeClassifyMapper.selectByPrimaryKey(oid.trim()); if(codeClassifyDO == null || StringUtils.isBlank(codeClassifyDO.getOid())){ throw new VciBaseException(DATA_OID_NOT_EXIST); } return codeClassifyDO; } /** * 主键批量获取主题库分类 * @param oidCollections 主键集合,但是受性能影响,建议一次查询不超过10000个 * @return 主题库分类显示对象 * @throws VciBaseException 查询出现异常时会抛出 */ @Override public Collection listCodeClassifyByOids(Collection oidCollections) throws VciBaseException{ VciBaseUtil.alertNotNull(oidCollections,"数据对象主键集合"); List codeClassifyDOList = listCodeClassifyDOByOidCollections(oidCollections); return codeClassifyDO2VOs(codeClassifyDOList); } /** * 使用主键集合查询数据对象 * @param oidCollections 主键的集合 * @return 数据对象列表 */ private List listCodeClassifyDOByOidCollections(Collection oidCollections){ List codeClassifyDOList = new ArrayList(); if(!CollectionUtils.isEmpty(oidCollections)){ Collection> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections); for(Collection oids: oidCollectionsList){ List tempDOList = codeClassifyMapper.selectByPrimaryKeyCollection(oids); if(!CollectionUtils.isEmpty(tempDOList)){ codeClassifyDOList.addAll(tempDOList); } } } return codeClassifyDOList; } /** * 参照树 主题库分类 * @param treeQueryObject 树形查询对象 * @return 主题库分类显示树 * @throws VciBaseException 查询条件和分页出错的时候会抛出异常 */ @Override public List referTree(TreeQueryObject treeQueryObject) throws VciBaseException{ 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 oid 主键 * @param lcStatus 状态 * @return 执行结果 */ @Override public BaseResult updateLcStatus(String oid, String lcStatus){ //查询修改前ts CodeClassifyDO codeClassifyDO_old = selectByOid(oid);//主要是为了查询ts //启用、停用 int u = codeClassifyMapper.updateLcStatus(oid,lcStatus); // //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。 // if(u!=0) { // codeDuckingServiceI.insertCache1(lcStatus,lcStatus,DOCKING_DEFAULT_CLASSIFY, DOCKING_DEFAULT_CLASSIFYOID, oid, codeClassifyDO_old.getTs()); // } BaseResult baseResult = u==0?BaseResult.error("修改失败!"):BaseResult.success("修改成功"); return baseResult; } /** * 使用查询封装器来查询 * @param queryWrapper 查询封装器 * @return 数据对象 */ @Override public List selectByWrapper(VciQueryWrapperForDO queryWrapper) { return codeClassifyMapper.selectByWrapper(queryWrapper); } /** * 使用分类主键获取分类相关的所有信息 * * @param codeClassifyOid 分类的主键 * @return 分类上级,下级的信息 */ @Override public CodeClassifyFullInfoBO getClassifyFullInfo(String codeClassifyOid) { VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键"); CodeClassifyFullInfoBO fullInfo = new CodeClassifyFullInfoBO(); CodeClassifyDO classifyDO = selectByOid(codeClassifyOid); //查询上级 fullInfo.setCurrentClassifyVO(codeClassifyDO2VO(classifyDO)); fullInfo.setParentClassifyVOs(codeClassifyDO2VOs(codeClassifyMapper.selectAllLevelParentByOid(codeClassifyOid))); if(!CollectionUtils.isEmpty(fullInfo.getParentClassifyVOs())){ fullInfo.setTopClassifyVO(fullInfo.getParentClassifyVOs().stream().filter(s->StringUtils.isBlank(s.getParentcodeclassifyoid())).findFirst().orElseGet(()->null)); } return fullInfo; } /** * 获取当前分类的顶层分类 * * @param codeClassifyOid 分类的主键 * @return 顶层分类的信息 */ @Override public CodeClassifyVO getTopClassifyVO(String codeClassifyOid) { VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键"); List classifyDOS = codeClassifyMapper.selectAllLevelParentByOid(codeClassifyOid); if(!CollectionUtils.isEmpty(classifyDOS)){ CodeClassifyDO classifyDO = classifyDOS.stream().filter(s -> StringUtils.isBlank(s.getParentCodeClassifyOid())).findFirst().orElseGet(() -> null); if(classifyDO!=null){ return codeClassifyDO2VO(classifyDO); } } return null; } /** * 统计子节点的个数 * * @param codeClassifyOid 分类的主键 * @return 个数 */ @Override public int countChildrenByClassifyOid(String codeClassifyOid) { Map conditionMap = new HashMap<>(); conditionMap.put("parentCodeClassifyOid",codeClassifyOid); return codeClassifyMapper.countByCondition(conditionMap).intValue(); } /** * 获取子级的主题库分类 * * @param codeClassifyOid 分类的主键 * @param allLevel 是否所有的层级 * @param fieldInPath 在路径中的字段 * @param enable 是否只显示启用 * @return 分类的显示对象 */ @Override public List listChildrenClassify(String codeClassifyOid, boolean allLevel, String fieldInPath, boolean enable) { if(allLevel){ List classifyDOS = codeClassifyMapper.selectAllLevelChildHasPath(codeClassifyOid,fieldInPath,enable); if(!CollectionUtils.isEmpty(classifyDOS)){ classifyDOS = classifyDOS.stream().filter(s->FRAMEWORK_DATA_ENABLED.equalsIgnoreCase(s.getLcStatus())).collect(Collectors.toList()); } return codeClassifyDO2VOs(classifyDOS); }else{ //只查询一条,那path就没必要查询了 Map conditionMap = new HashMap<>(); conditionMap.put("parentcodeclassifyoid",codeClassifyOid); if (enable){ conditionMap.put(VciQueryWrapperForDO.LC_STATUS_FIELD,FRAMEWORK_DATA_ENABLED); } return codeClassifyDO2VOs(codeClassifyMapper.selectByCondition(conditionMap,new PageHelper(-1))); } } /** * 反向从子级获取父级的主题库分类 * * @param codeClassifyOid 分类的主键 * @return 分类的显示对象 */ @Override public List listParentClassify(String codeClassifyOid){ List classifyDOS = codeClassifyMapper.listParentClassify(codeClassifyOid); return codeClassifyDO2VOs(classifyDOS); } /** * 导出分类 * * @param oid 分类主键 * @return excel文件路径 */ @Override public String exportClassify(String oid) { VciBaseUtil.alertNotNull(oid,"分类的主键"); CodeClassifyVO classifyVO = getObjectByOid(oid); classifyVO.setDataLevel(0); classifyVO.setPath(classifyVO.getId()); List codeClassifyVOS = listChildrenClassify(oid, true, "id", false); if(codeClassifyVOS ==null){ codeClassifyVOS = new ArrayList<>(); } codeClassifyVOS.add(classifyVO); //查询一下规则的编号,和关键属性重复规则 List codeRuleOids = codeClassifyVOS.stream().filter(s -> StringUtils.isNotBlank(s.getCoderuleoid())).map(CodeClassifyVO::getCoderuleoid).collect(Collectors.toList()); Map ruleVOMap = new HashMap<>(); if(!CollectionUtils.isEmpty(codeRuleOids)){ VciBaseUtil.switchCollectionForOracleIn(codeRuleOids).stream().forEach(ruleOids->{ Collection ruleVOS = codeRuleService.listCodeRuleByOids(ruleOids); ruleVOMap.putAll( Optional.ofNullable(ruleVOS).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getOid(),t->t))); }); } //找关键属性规则 List keyRuleOids = codeClassifyVOS.stream().filter(s -> StringUtils.isNotBlank(s.getCodekeyattrrepeatoid())).map(CodeClassifyVO::getCodekeyattrrepeatoid).collect(Collectors.toList()); Map keyRuleVOMap = new HashMap<>(); if(!CollectionUtils.isEmpty(keyRuleOids)){ VciBaseUtil.switchCollectionForOracleIn(keyRuleOids).stream().forEach(ruleOids->{ Collection ruleVOS = keyAttrRepeatRuleService.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 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(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 excelName; } /** * 创建导入模板 * * @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 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 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 classifyDOList = new ArrayList<>(); //看看路径是否有重复 Map pathCountMap = poList.stream().filter(s->StringUtils.isNotBlank(s.getPath())).collect(Collectors.groupingBy(s -> s.getPath(), Collectors.counting())); List 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 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(","))}); } Map ruleVOMap = Optional.ofNullable(codeRuleService.listCodeRuleByIds( poList.stream().filter(s->StringUtils.isNotBlank(s.getCodeRuleId())).map(CodeClassifyPO::getCodeRuleId).collect(Collectors.toList())) ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2)); Map keyRuleVOMap =Optional.ofNullable(keyAttrRepeatRuleService.listCodeKeyAttrRepeatRuleByIds( poList.stream().filter(s->StringUtils.isNotBlank(s.getKeyRepeatRuleId())).map(CodeClassifyPO::getKeyRepeatRuleId).collect(Collectors.toList())) ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2)); Map btmVOMap = Optional.ofNullable(btmService.listBtmByIds( poList.stream().filter(s -> StringUtils.isNotBlank(s.getBtmTypeId())).map(CodeClassifyPO::getBtmTypeId).collect(Collectors.toList())) ).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t,(o1,o2)->o2)); Map oidPathMap = new HashMap<>(); //我们需要查询所有已经存在的分类,主要是路径,用来判断分类的数据 List existClassifyDOs = codeClassifyMapper.selectAllLevelChildHasPath("", "id", false); Map 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->{ CodeClassifyDO classifyDO = new CodeClassifyDO(); 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()}); } classifyDO.setOid(VciBaseUtil.getPk()); classifyDO.setId(po.getId()); classifyDO.setName(po.getName()); classifyDO.setDescription(po.getDescription()); oidPathMap.put(po.getPath(),classifyDO.getOid()); if(StringUtils.isNotBlank(po.getBtmTypeId())){ OsBtmTypeVO typeVO = btmVOMap.get(po.getBtmTypeId().toLowerCase(Locale.ROOT)); classifyDO.setBtmTypeId(typeVO.getId()); classifyDO.setBtmTypeName(typeVO.getName()); } if(StringUtils.isNotBlank(po.getCodeRuleId())){ CodeRuleVO codeRuleVO = ruleVOMap.get(po.getCodeRuleId().toLowerCase(Locale.ROOT)); classifyDO.setCodeRuleOid(codeRuleVO.getOid()); } if(StringUtils.isNotBlank(po.getKeyRepeatRuleId())){ CodeKeyAttrRepeatRuleVO repeatRuleVO = keyRuleVOMap.get(po.getKeyRepeatRuleId()); classifyDO.setCodeKeyAttrRepeatOid(repeatRuleVO.getOid()); } classifyDO.setLcStatus(po.getLcStatus()); classifyDO.setPath(po.getPath()); classifyDOList.add(classifyDO); }); //要看存在的,修改路径对应的主键 Map 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 addClassifyDOList = new ArrayList<>(); List editClassifyDOList = new ArrayList<>(); classifyDOList.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())); CodeClassifyDO classifyDOInDB = pathDOMap.get(classifyDO.getPath()); 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.batchUpdate(classifyDOs.stream().collect(Collectors.toList())); }); } if(!CollectionUtils.isEmpty(addClassifyDOList)){ revisionModelUtil.wrapperForBatchAdd(addClassifyDOList); VciBaseUtil.switchCollectionForOracleIn(addClassifyDOList).stream().forEach(classifyDOs->{ codeClassifyMapper.batchInsert(classifyDOs.stream().collect(Collectors.toList())); }); } } /** * 获取分类关联的属性 * * @param baseQueryObject 查询对象,必须有codeClassifyOid,支持id和name两种查询条件 * @return 属性的信息,包含默认的属性 */ @Override public DataGrid 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<>(); } List unDefaultAttributes = btmService.listAttributeByBtmId(topClassifyVO.getBtmtypeid()); List attributeVOS = new ArrayList<>(); if(!CollectionUtils.isEmpty(unDefaultAttributes)){ unDefaultAttributes.stream().forEach(attr->{ OsAttributeVO attributeVO = new OsAttributeVO(); BeanUtil.convert(attr,attributeVO); attributeVO.setAttributeDataType(attr.getAttrDataType()); attributeVO.setAttrLength(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 dataGrid = new DataGrid<>(); dataGrid.setData(attributeVOS); dataGrid.setTotal(attributeVOS.size()); return dataGrid; } /** * 使用编号的路径获取对象 * * @param idPath 编号的路径,一定要从最顶层节点开始,格式为xxx/yyy/zz 这样 * @return 分类的显示对象 */ @Override public CodeClassifyVO getObjectByIdPath(String idPath) { CodeClassifyDO classifyDO = codeClassifyMapper.selectByFieldPath(idPath, VciQueryWrapperForDO.ID_FIELD); return codeClassifyDO2VO(classifyDO); } /** * 使用编号的路径获取对象 * * @param clsfNamePath 编号的路径,一定要从最顶层节点开始,格式为xxx/yyy/zz 这样 * @return 分类的显示对象 */ @Override public CodeClassifyVO getObjectByClsfNamePath(String clsfNamePath){ CodeClassifyDO classifyDO = codeClassifyMapper.selectByFieldPath(clsfNamePath, "name"); return codeClassifyDO2VO(classifyDO); } /*** * 根据上级节点获取下级节点代号路径和名称路径 * @param classifyId * @param enable * @return */ @Override public List getIdPathToNamePathByParentId(String codeClassifyId,boolean enable){ List classifyDOs= codeClassifyMapper.getIdPathToNamePathByParentId(codeClassifyId,enable); return codeClassifyDO2VOs(classifyDOs); } }