| | |
| | | import com.vci.ubcs.code.bo.CodeTemplateAttrSqlBO; |
| | | import com.vci.ubcs.code.dto.*; |
| | | import com.vci.ubcs.code.entity.CodeAllCode; |
| | | import com.vci.ubcs.code.entity.CodeSynonym; |
| | | import com.vci.ubcs.code.enumpack.*; |
| | | import com.vci.ubcs.code.lifecycle.CodeAllCodeLC; |
| | | import com.vci.ubcs.code.mapper.CommonsMapper; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import javax.annotation.Resource; |
| | | import javax.xml.bind.ValidationEvent; |
| | | import java.beans.BeanInfo; |
| | | import java.beans.Introspector; |
| | | import java.beans.PropertyDescriptor; |
| | |
| | | @Service |
| | | @Slf4j |
| | | public class MdmIOServiceImpl implements MdmIOService { |
| | | |
| | | |
| | | /** |
| | | * 字段 |
| | |
| | | @Autowired |
| | | private ICodeKeyAttrRepeatService keyRuleService; |
| | | |
| | | @Autowired ICodeSynonymService codeSynonymService; |
| | | |
| | | /** |
| | | * 公式的服务 |
| | | */ |
| | | @Autowired |
| | | private FormulaServiceImpl formulaService; |
| | | |
| | | /** |
| | | * 规则的服务 |
| | | */ |
| | | @Autowired |
| | | private ICodeRuleService ruleService; |
| | | |
| | | /** |
| | | * 业务类型的服务 |
| | | */ |
| | | @Autowired |
| | | private IBtmTypeClient btmTypeClient; |
| | | |
| | | /*** |
| | | * 申请集团编码服务 |
| | | */ |
| | | @Resource |
| | | private IMdmInterJtClient mdmInterJtClient; |
| | | |
| | | /*** |
| | | * 密级服务 |
| | | */ |
| | | @Resource |
| | | private IWebSecretClient secretService; |
| | | |
| | | /** |
| | | * 日志保存工具类 |
| | | */ |
| | | @Autowired |
| | | private SaveLogUtil saveLogUtil; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 客户现场excel为老版本,导出的总数限制为65535 |
| | |
| | | //最后弄组合规则 |
| | | batchSwitchComponentAttrOnOrder(attrVOS,allCboList); |
| | | |
| | | |
| | | Map<String, ClientBusinessObject> rowIndexCboMap = allCboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t)); |
| | | |
| | | |
| | | List<ClientBusinessObject> needSaveCboList = allCboList.stream().filter(cbo -> { |
| | | String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); |
| | |
| | | Map<String,String>resembleMap=new HashMap<>(); |
| | | List<DataResembleVO> dataResembleVOS=new ArrayList<>(); |
| | | String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId(); |
| | | //相似项查询规则 |
| | | bathcResembleQuery(codeClassifyOid,templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS); |
| | | if(resembleMap.size()>0) { |
| | | if(!CollectionUtils.isEmpty(dataResembleVOS)) { |
| | |
| | | Map<String, String> resembleMap = new HashMap<>(); |
| | | List<DataResembleVO> dataResembleVOS = new ArrayList<>(); |
| | | String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); |
| | | // 相似项查询 |
| | | bathcResembleQuery(templateVO.getCodeclassifyoid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS); |
| | | if (resembleMap.size() > 0) { |
| | | if (!CollectionUtils.isEmpty(dataResembleVOS)) { |
| | |
| | | createRedisDatas(uuid + "-resemble", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false); |
| | | } |
| | | } |
| | | |
| | | //生成class缓存 |
| | | Map<String, String> rowIndexClsOidMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t.getAttributeValue(CODE_CLASSIFY_OID_FIELD))); |
| | | createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,true); |
| | |
| | | Map<String,String>resembleMap=new HashMap<>(); |
| | | List<DataResembleVO> dataResembleVOS=new ArrayList<>(); |
| | | String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId(); |
| | | //相似项查询 |
| | | bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS); |
| | | if(resembleMap.size()>0) { |
| | | isCreateUUid=true; |
| | |
| | | } |
| | | } |
| | | /** |
| | | * 校验关键属性 |
| | | * 校验关键属性,和近义词查询规则 |
| | | * @param classifyFullInfo 分类的全部信息 |
| | | * @param templateVO 模板的内容,必须包含模板属性 |
| | | * @param cboList 批量的数据 |
| | |
| | | CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo); |
| | | //注意的是keyRuleVO可能为空,表示不使用规则控制 |
| | | //获取所有的关键属性 |
| | | Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); |
| | | Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> keyAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); |
| | | |
| | | // TODO:2024-02-01 先获取配置了近义词查询规则的属性,不同于关键属性,设置了近义词查询规则的属性可能是多条不同的近义词查询规则 |
| | | Map<String, CodeClassifyTemplateAttrVO> sysonymAttrMaps = templateVO.getAttributes().stream().filter(item -> Func.isNotBlank(item.getSysonymRuleOids())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); |
| | | // 有配置近义词查询规则属性 |
| | | Map<String, List<CodeSynonym>> codeSynonymMaps = new HashMap<>(); |
| | | if(!sysonymAttrMaps.isEmpty()){ |
| | | // 查询近义词规则,存储方式key:属性id,value近义词查询规则列表 |
| | | codeSynonymMaps = codeSynonymService.getCodeSynonymByOids(sysonymAttrMaps); |
| | | } |
| | | |
| | | boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag()); |
| | | //全部去空的优先级大于去空 |
| | |
| | | CodeImportResultVO resultVO = new CodeImportResultVO(); |
| | | resultVO.setKeyAttrRuleInfo(String.format(keyRuleVO ==null?"":"查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}", |
| | | new String[]{trim?"是":"否",ignoreCase?"是":"否",ignoreWidth?"是":"否",trimAll?"是":"否"})); |
| | | //resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO)); |
| | | getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO,resultVO); |
| | | //resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(keyAttrMap,cboList,keyRuleVO)); |
| | | |
| | | // 先在表格中查询关键属性重复的列 |
| | | getSelfRepeatRowIndex(keyAttrMap,cboList,keyRuleVO,resultVO); |
| | | // 再在表格中查询近义词查询规则的列 |
| | | //getSelfRepeatSysnomRowIndex(sysonymAttrMaps,cboList,codeSynonymMaps,resultVO); |
| | | |
| | | if(!CollectionUtils.isEmpty(resultVO.getSelfRepeatRowIndexList())){ |
| | | //我们移除本身重复的数据 |
| | | cboList = cboList.stream().filter(s->!resultVO.getSelfRepeatRowIndexList().contains(s.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList()); |
| | | } |
| | | //2.判断关键属性在系统里是否重复 |
| | | //因为数据量很大,所以得想办法并行 |
| | | //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo(); |
| | | Map<String,List<BaseModel>> indexTODataMap=new ConcurrentHashMap<>(); |
| | | // 查询不需要参与关键属性校验的除自己以外的所有分类oid |
| | | final String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid()); |
| | |
| | | //每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示 |
| | | //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo); |
| | | Map<String, String> conditionMap = new HashMap<>(); |
| | | ketAttrMap.forEach((attrId, attrVO) -> { |
| | | keyAttrMap.forEach((attrId, attrVO) -> { |
| | | String value =cbo.getAttributeValue(attrId.toLowerCase(Locale.ROOT)); |
| | | if (value == null) { |
| | | value = ""; |
| | | } |
| | | value= value.replace(REQUIRED_CHAR,SPECIAL_CHAR); |
| | | // 关键属性查询条件map获取 |
| | | engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap); |
| | | // 近义词查询规则条件map获取 |
| | | //engineService.wrapperSynonymAttrConditionMap(value); |
| | | }); |
| | | if (!CollectionUtils.isEmpty(ketAttrMap)) { |
| | | |
| | | if (!CollectionUtils.isEmpty(keyAttrMap)) { |
| | | // 添加不参与关键属性校验的分类oid判断 |
| | | if(Func.isNotBlank(isParticipateCheckOids)){ |
| | | conditionMap.put("t.codeclsfid",QueryOptionConstant.NOTIN+isParticipateCheckOids); |
| | | } |
| | | if(isEdit){//如果是更改则需排除系统本身 |
| | | //如果是更改则需排除系统本身 |
| | | if(isEdit){ |
| | | conditionMap.put("t.id",QueryOptionConstant.NOTEQUAL+cbo.getId()); |
| | | } |
| | | conditionMap.put("t.lastr", "1"); |
| | |
| | | String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); |
| | | String oid=cbo.getOid(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | // 关键属性重复校验值处理 |
| | | for (int i = 0; i < attrVOList.size(); i++) { |
| | | CodeClassifyTemplateAttrVO attrVO = attrVOList.get(i); |
| | | String attrId = attrVO.getId().toLowerCase(Locale.ROOT); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取近义词查询存在相同的行号 |
| | | * @param sysonymAttr |
| | | * @param dataList |
| | | * @param CodeSynonymMaps |
| | | * @param resultVO |
| | | */ |
| | | private void getSelfRepeatSysnomRowIndex(Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> sysonymAttr, |
| | | List<ClientBusinessObject> dataList, Map<String, List<CodeSynonym>> CodeSynonymMaps,CodeImportResultVO resultVO) { |
| | | Set<String> selfRepeatRowIndexList = new CopyOnWriteArraySet<>(); |
| | | Map<String,List<String>> keyAttrOkOidTORepeatOidMap=new HashMap<>(); |
| | | //必须将属性按照顺序排序好 |
| | | List<CodeClassifyTemplateAttrVO> attrVOList = sysonymAttr.values().stream().sorted(((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()))).collect(Collectors.toList()); |
| | | Map<String/**行号**/,String/**关键属性的组合内容**/> rowIndexKeyStringMap = new HashMap<>(); |
| | | Map<String/**关键属性的组合内容**/,String/**第一个关键属性的数据oid**/> okOidKeyStringMap = new HashMap<>(); |
| | | dataList.parallelStream().forEach(cbo-> { |
| | | String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); |
| | | String oid = cbo.getOid(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < attrVOList.size(); i++) { |
| | | CodeClassifyTemplateAttrVO attrVO = attrVOList.get(i); |
| | | String attrId = attrVO.getId().toLowerCase(Locale.ROOT); |
| | | String value = cbo.getAttributeValue(attrId); |
| | | List<CodeSynonym> codeSynonyms = CodeSynonymMaps.get(attrId); |
| | | // 对近义词查询值进行转换 |
| | | value = synonymConversion(codeSynonyms,value); |
| | | // 如果codeSynonyms是多个就需要考虑组合问题 |
| | | sb.append(value).append("${sys}"); |
| | | } |
| | | String keyString = sb.toString(); |
| | | if(rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)){ |
| | | selfRepeatRowIndexList.add(rowIndex); |
| | | String okOid=okOidKeyStringMap.getOrDefault(keyString,""); |
| | | if(StringUtils.isNotBlank(okOid)){ |
| | | List<String>newOidList=new ArrayList<>(); |
| | | newOidList.add(oid); |
| | | if(keyAttrOkOidTORepeatOidMap.containsKey(okOid)){ |
| | | List<String> oldOidList = keyAttrOkOidTORepeatOidMap.get(okOid); |
| | | newOidList.addAll(oldOidList); |
| | | } |
| | | keyAttrOkOidTORepeatOidMap.put(okOid,newOidList); |
| | | } |
| | | }else { |
| | | okOidKeyStringMap.put(sb.toString(),oid); |
| | | rowIndexKeyStringMap.put(rowIndex, sb.toString()); |
| | | } |
| | | }); |
| | | //因为只是关键属性重复,所以我们不能重复的多条选一条来报错 |
| | | resultVO.setKeyAttrRepeatRowIndexList(selfRepeatRowIndexList); |
| | | resultVO.setKeyAttrOkOidTORepeatOidMap(keyAttrOkOidTORepeatOidMap); |
| | | } |
| | | |
| | | /** |
| | | * 近义词与源值相互转换 |
| | | * @param codeSynonyms |
| | | * @param value |
| | | * @return |
| | | */ |
| | | private String synonymConversion(List<CodeSynonym> codeSynonyms,String value){ |
| | | // 只有一条近义词查询规则时 |
| | | if(codeSynonyms.isEmpty() || codeSynonyms.size() == 1){ |
| | | return value.replace(codeSynonyms.get(0).getSourceValue(),codeSynonyms.get(0).getSynonymValue()); |
| | | } |
| | | // 近义词规则可能出现的情况是一个源值对应多个近义词,而反查时同样会出现一个近义词对应多个源值 |
| | | // codeSynonyms.stream().map() |
| | | |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * excel的标题上获取字段所在的位置 |
| | | * @param titleRowData 标题的内容 |
| | | * @param attrNameIdMap 模板中属性名称和英文的映射 |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | private List<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String,String>> oldDataMap){ |
| | | List<ClientBusinessObject> clientBusinessObjectList=new ArrayList<>(); |
| | | DefaultAttrAssimtUtil.mapToLowerCase(oldDataMap,true); |