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.code.bo.TreeWrapperOptions; import com.vci.ubcs.code.entity.CodeClassify; import com.vci.ubcs.code.entity.CodeClstemplateEntity; 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.service.ICodeClassifyService; import com.vci.ubcs.code.service.ICodeKeyattrrepeatService; import com.vci.ubcs.code.service.ICodeRuleService; 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 org.springblade.core.cache.utils.CacheUtil; import org.springblade.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.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; import static com.vci.ubcs.code.constant.FrameWorkDefaultValueConstant.*; @Service public class CodeClassifyServiceImpl extends ServiceImpl implements ICodeClassifyService { @Resource private CodeClassifyMapper codeClassifyMapper; @Resource private CodeClstemplateMapper codeClstemplateMapper; @Resource private ICodeRuleService codeRuleService; /** * 对象的操作 */ @Resource private RevisionModelUtil revisionModelUtil; @Resource private ICodeKeyattrrepeatService iCodeKeyattrrepeatService; /** * 上级节点的属性名称 */ public static final String PARENT_FIELD_NAME = "parentCodeClassifyOid"; /** * 使用查询封装器来查询 * @param wrapper 查询封装器 * @return 数据对象 */ @Override public List selectByWrapper(Wrapper wrapper) { return codeClassifyMapper.selectList(wrapper); } @Override public IPage selectPlCodeClassifyPage(IPage 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.setLastModifier(AuthUtil.getUser().getUserName()); codeClassifyEntity.setLastModifyTime(new Date()); 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 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("传入数据不能为空!"); } codeClassifyEntity = selectByOid(codeClassifyEntity.getOid()); 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 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){//不是最新的不让改 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 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 condition = new HashMap<>(2); condition.put("codeClassifyOid",codeClassify.getOid()); List codeClstemplateEntities = codeClstemplateMapper.selectByMap(condition); // VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(CodeClassifyTemplateDO.class); // queryWrapper.addQueryMap("codeClassifyOid",codeClassifyDTO.getOid()); // List codeClassifyTemplateDOListHaveTemplate = codeClassifyTemplateMapper.selectByWrapper(queryWrapper); if(codeClstemplateEntities.size()>0){ return R.fail("分类关联模板,请先删除!"); } //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。 //1、查询要删除的父类数据 List deletes = new ArrayList(); deletes.add(codeClassify); if(result.isSuccess()) { //找下级的,这个是可以删除的时候 Map childrenOids = codeClassifyMapper.selectAllLevelChildOid(codeClassify.getOid().trim()); if (!CollectionUtils.isEmpty(childrenOids)) { Collection> childrenCollections = VciBaseUtil.switchCollectionForOracleIn(childrenOids.keySet()); for(Collection s : childrenCollections){ //处理数据集成逻辑,成功后执行集成第一步,分类数据特殊处理。 //2、查询要删除的子类数据 List 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); //启用、停用 // 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 listCodeClassifyByOids(Collection oidCollections) { VciBaseUtil.alertNotNull(oidCollections,"数据对象主键集合"); List codeClassifyDOList = listCodeClassifyDOByOidCollections(oidCollections); return codeClassifyDO2VOs(codeClassifyDOList); } /** * 使用主键集合查询数据对象 * @param oidCollections 主键的集合 * @return 数据对象列表 */ private List listCodeClassifyDOByOidCollections(Collection oidCollections){ List codeClassifyList = new ArrayList(); if(!CollectionUtils.isEmpty(oidCollections)){ Collection> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections); for(Collection oids: oidCollectionsList){ List tempDOList = codeClassifyMapper.selectBatchIds(oids); if(!CollectionUtils.isEmpty(tempDOList)){ codeClassifyList.addAll(tempDOList); } } } return codeClassifyList; } /** * 批量数据对象转换为显示对象 * @param codeClassifys 数据对象列表 * @return 显示对象 */ @Override public List codeClassifyDO2VOs(Collection codeClassifys) { List voList = new ArrayList(); 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 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 treeCodeClassify(TreeQueryObject treeQueryObject) { List doList =codeClassifyMapper.selectCodeClassifyVOByTree(treeQueryObject.getParentOid()); 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 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 codeClassifyVOS = listChildrenClassify(oid, true, "id", false); // if(codeClassifyVOS ==null){ // codeClassifyVOS = new ArrayList<>(); // } // CodeClassifyVO codeClassifyVO = new CodeClassifyVO(); // BeanUtils.copyProperties(codeClassify,codeClassifyVO); // codeClassifyVOS.add(codeClassifyVO); // // //查询一下规则的编号,和关键属性重复规则 // List codeRuleOids = codeClassifyVOS.stream().filter(s -> org.apache.commons.lang3.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 -> org.apache.commons.lang3.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 = 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 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; } /** * 获取子级的主题库分类 * * @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); 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("lcstatus",FRAMEWORK_DATA_ENABLED); } return codeClassifyDO2VOs(codeClassifyMapper.selectByMap(conditionMap)); } } }