package com.vci.ubcs.code.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.common.utils.StringUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.protobuf.ServiceException; import com.vci.ubcs.code.applyjtcodeservice.feign.IMdmInterJtClient; import com.vci.ubcs.code.applyjtcodeservice.vo.DockingPreAttrMappingVO; import com.vci.ubcs.code.bo.AttributeValue; import com.vci.ubcs.code.bo.CodeClassifyFullInfoBO; 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 com.vci.ubcs.code.service.*; import com.vci.ubcs.code.util.ClientBusinessObject; import com.vci.ubcs.code.vo.CodeKeyAttrRepeatVO; import com.vci.ubcs.code.vo.pagemodel.*; import com.vci.ubcs.code.vo.webserviceModel.attrmap.DataObjectVO; import com.vci.ubcs.code.vo.webserviceModel.attrmap.RowDatas; import com.vci.ubcs.code.vo.webserviceModel.result.xml.XMLResultDataObjectDetailDO; import com.vci.ubcs.file.util.VciZipUtil; import com.vci.ubcs.omd.feign.IBtmTypeClient; import com.vci.ubcs.omd.feign.IWebSecretClient; import com.vci.ubcs.omd.vo.BtmTypeVO; 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.SheetDataSet; import com.vci.ubcs.starter.poi.bo.SheetRowData; import com.vci.ubcs.starter.poi.bo.WriteExcelOption; import com.vci.ubcs.starter.poi.util.ExcelUtil; import com.vci.ubcs.starter.revision.model.BaseModel; import com.vci.ubcs.starter.util.DefaultAttrAssimtUtil; import com.vci.ubcs.starter.util.LocalFileUtil; import com.vci.ubcs.starter.util.SaveLogUtil; import com.vci.ubcs.starter.web.constant.QueryOptionConstant; import com.vci.ubcs.starter.web.enumpck.BooleanEnum; import com.vci.ubcs.starter.web.enumpck.UserSecretEnum; import com.vci.ubcs.starter.web.enumpck.VciFieldTypeEnum; import com.vci.ubcs.starter.web.pagemodel.*; import com.vci.ubcs.starter.web.toolmodel.DateConverter; import com.vci.ubcs.starter.web.util.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import oracle.sql.TIMESTAMP; import org.apache.commons.collections4.map.HashedMap; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Workbook; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.secure.BladeUser; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.StringUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; 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; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import static com.alibaba.druid.util.FnvHash.Constants.LIMIT; import static com.vci.ubcs.code.constant.MdmEngineConstant.*; import static com.vci.ubcs.starter.poi.util.ExcelUtil.*; @RequiredArgsConstructor @Service @Slf4j public class MdmIOServiceImpl implements MdmIOService { /** * 字段 */ public static final String ROW_INDEX = "LAY_TABLE_INDEX"; /** * 错误信息的字段 */ public static final String ERROR_MSG = "errorMsg"; @Value("${batchadd.exportattr.type:基本信息}") public String BATCHADD_EXCEPORT_ATTR_TYPE; @Value("${batchadd.redis.time:6000000}") public int BATCHADD_REDIS_TIME; @Value("${batchadd.import_data_limit:5001}") private Integer IMPORT_DATA_LIMIT; /** * 主题库分类的服务 */ @Resource private ICodeClassifyService classifyService; @Resource private MdmEngineService mdmEngineService; /** * 通用查询 */ @Resource private CommonsMapper commonsMapper; /**** * 码值服务 */ @Resource ICodeAllCodeService codeAllCodeService; /** * 模板的服务 */ @Resource private ICodeClstemplateService templateService; /** * 主数据引擎的服务 */ @Resource private MdmEngineService engineService; /*** * resdis缓存服务 */ private final BladeRedis bladeRedis; /** * 生成编码的服务 */ @Resource private MdmProductCodeService productCodeService; /** * 关键属性的配置 */ @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 */ public static final int EXPORT_LIMIT = 65535; /** * 自定义并发ForkJoinPool */ private static final ForkJoinPool customForkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() - 1); /** * 批量申请:选取选中分类下的所有模板关键属性,相似属性,必填属性,写入execl中 * * @param codeClassifyOid 分类的主键 * @return excel的文件地址 */ @Override public String downloadTopImportExcel(String codeClassifyOid) { List templateVOList = new ArrayList<>(); VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键"); CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid); templateVOList = templateService.childTemplates(codeClassifyOid); List codeClassifyVOS = classifyService.getIdPathToNamePathByParentId(codeClassifyOid, true); WriteExcelOption eo = new WriteExcelOption(); LinkedHashMap allFieldToOutNameMap = new LinkedHashMap<>(); templateVOList.stream().forEach(templateVO -> { //组合格式的不导入, // 枚举的提供序列的选择 //时间全部统一为yyyy-MM-dd HH:mm:ss //参照的自行输入名称 //分类注入的不用,都是导入后自动处理的 //编码,状态等字段不导入 if (!CollectionUtils.isEmpty(templateVO.getAttributes())) { List templateAttrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) && (VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); if (CollectionUtils.isEmpty(templateAttrVOS)) { throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性"); } templateAttrVOS.stream().forEach(codetemplateAttr -> { String field = codetemplateAttr.getId(); String name = codetemplateAttr.getName(); CodeClassifyTemplateAttrVO codeBaseAttributeDTO = new CodeClassifyTemplateAttrVO(); boolean res = (StringUtils.isNotBlank(codetemplateAttr.getAttributeGroup()) && codetemplateAttr.getAttributeGroup().equals(BATCHADD_EXCEPORT_ATTR_TYPE))//基本属性字段显示 || (StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag()))//关键属性的存入 || (StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())) //相似属性的存入 || (StringUtils.isNotBlank(codetemplateAttr.getRequireFlag()) && Boolean.parseBoolean(codetemplateAttr.getRequireFlag())); if (allFieldToOutNameMap.containsKey(name)) {//如果存在的话则需要根据具体的去赋值 codeBaseAttributeDTO = allFieldToOutNameMap.get(name); if (StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag())) { codeBaseAttributeDTO.setKeyAttrFlag(codetemplateAttr.getKeyAttrFlag());//属性关键属性 } if (StringUtils.isNotBlank(codetemplateAttr.getRequireFlag()) && Boolean.parseBoolean(codetemplateAttr.getRequireFlag())) { codeBaseAttributeDTO.setRequireFlag(codetemplateAttr.getRequireFlag());//属性必填项 } if (StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())) { codeBaseAttributeDTO.setSameRepeatAttrFlag(codetemplateAttr.getSameRepeatAttrFlag());//属性相似属性 } } else if (res) { allFieldToOutNameMap.put(name, codetemplateAttr); } }); } }); //整理好所有模板需要写入execl的属性信息 Workbook workbook = new HSSFWorkbook(); LinkedList excelDataList = new LinkedList<>(); if (!CollectionUtils.isEmpty(allFieldToOutNameMap)) { excelDataList.add(new WriteExcelData(0, 0, "分类路径")); final int[] index = {0}; allFieldToOutNameMap.values().stream().forEach(attrVO -> { Object text = attrVO.getName(); text = exportKeyAndRequired(workbook, attrVO, text); int colIndex = 1 + index[0]++; WriteExcelData excelData = new WriteExcelData(0, colIndex, text); if (StringUtils.isNotBlank(attrVO.getCodeDateFormat()) || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { excelData.setDateFormat(VciDateUtil.DateTimeFormat); } if (text instanceof RichTextString) { excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); } excelDataList.add(excelData); if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) { //添加数据有效性 List enumValueList = new ArrayList<>(); enumValueList.add(""); List valueList = engineService.listComboboxItems(attrVO); if (!CollectionUtils.isEmpty(valueList)) { valueList.stream().forEach(kv -> { enumValueList.add(kv.getValue()); }); } //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(enumValueList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { List booleanList = new ArrayList<>(); booleanList.add("是"); booleanList.add("否"); //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(booleanList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } }); eo.addSheetDataList(codeClassifyVO.getName() + "导入模板", excelDataList); } LinkedList classPathList = new LinkedList<>(); classPathList.add(new WriteExcelData(0, 0, "分类层级")); WriteExcelData idPathWriteExcelTitle = new WriteExcelData(0, 1, "分类ID路径"); idPathWriteExcelTitle.setWidth(20); idPathWriteExcelTitle.setCenter(false); classPathList.add(idPathWriteExcelTitle); WriteExcelData namePathWriteExcelTitle = new WriteExcelData(0, 2, "分类名称路径"); namePathWriteExcelTitle.setWidth(20); namePathWriteExcelTitle.setCenter(false); classPathList.add(namePathWriteExcelTitle); final int[] rowIndex = {1}; codeClassifyVOS.stream().forEach(codeClassifyVO1 -> { classPathList.add(new WriteExcelData(rowIndex[0], 0, codeClassifyVO1.getDataLevel())); String idPath = codeClassifyVO1.getIdPath().startsWith("#") ? codeClassifyVO1.getIdPath().substring(1) : codeClassifyVO1.getIdPath(); WriteExcelData idPathWriteExcelData = new WriteExcelData(rowIndex[0], 1, idPath); idPathWriteExcelData.setWidth(30); idPathWriteExcelData.setCenter(false); classPathList.add(idPathWriteExcelData); String namePath = codeClassifyVO1.getNamePath().startsWith("#") ? codeClassifyVO1.getNamePath().substring(1) : codeClassifyVO1.getNamePath(); WriteExcelData namePathWriteExcelData = new WriteExcelData(rowIndex[0], 2, namePath); namePathWriteExcelData.setWidth(40); namePathWriteExcelData.setCenter(false); classPathList.add(namePathWriteExcelData); rowIndex[0]++; }); WriteExcelData excelData = new WriteExcelData(); excelData.setMerged(true); excelData.setRow(1); excelData.setRowTo(2); excelData.setCol(4); excelData.setColTo(9); excelData.setCenter(false); excelData.setReadOnly(true); excelData.setObj("导入数据时,分类路径必须填写叶子节点路径\n(选择叶子节点导入则不需要填写分类路径)"); excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); classPathList.add(excelData); eo.addSheetDataList(codeClassifyVO.getName() + "分类对照表", classPathList); String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + "_导入模板.xls"; // eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList); ExcelUtil.writeDataToFile(excelName, eo); return excelName; } /** * 生成导入的文件 * * @param codeClassifyOid 分类的主键 * @param isHistory 是否历史数据导入 * @return excel的文件地址 */ @Override public String createImportExcel(String codeClassifyOid, boolean isHistory) { List templateVOList = new ArrayList<>(); VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键"); CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid); //获取码段宽度 String secWidth = getCodeSegmentWidth(codeClassifyVO.getOid()); if (isHistory) { templateVOList = templateService.childTemplates(codeClassifyOid); } else { //找模板 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid); templateVOList.add(templateVO); } WriteExcelOption eo = new WriteExcelOption(); eo.setAppend(true); //增加模板的信息导入 LinkedList tempEDList = new LinkedList<>(); tempEDList.add(new WriteExcelData(0, 0, "模板主键")); tempEDList.add(new WriteExcelData(0, 1, "模板代号")); tempEDList.add(new WriteExcelData(0, 2, "模板名称")); for (int j = 0; j < templateVOList.size(); j++) { CodeClassifyTemplateVO templateVO = templateVOList.get(j); CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO(); BeanUtils.copyProperties(templateVO, codeClassifyTemplateVO); //组合格式的不导入, // 枚举的提供序列的选择 //时间全部统一为yyyy-MM-dd HH:mm:ss //参照的自行输入名称 //分类注入的不用,都是导入后自动处理的 //编码,状态等字段不导入 List codeClassifyTemplateAttrVOList = codeClassifyTemplateVO.getAttributes(); if (!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) { if (CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) { throw new VciBaseException("模板没有配置属性"); } } //剔除掉默认的属性,以及表单不显示的属性 List templateAttrVOS = codeClassifyTemplateAttrVOList.stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) && (isHistory || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); if (CollectionUtils.isEmpty(templateAttrVOS)) { throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性"); } List idAttrVOList = codeClassifyTemplateVO.getAttributes().stream().filter(s -> s.getId().equalsIgnoreCase(CODE_FIELD)).collect(Collectors.toList()); LinkedList excelDataList = new LinkedList<>(); Workbook workbook = new HSSFWorkbook(); if (isHistory) { excelDataList.add(new WriteExcelData(0, 0, "分类路径", "")); excelDataList.add(new WriteExcelData(0, 1, "码段宽度", "")); excelDataList.add(new WriteExcelData(0, 2, !CollectionUtils.isEmpty(idAttrVOList) ? idAttrVOList.get(0).getName() : "企业编码", idAttrVOList.get(0).getId())); // 填充码段 excelDataList.add(new WriteExcelData(1, 1, secWidth)); } for (int i = 0; i < templateAttrVOS.size(); i++) { CodeClassifyTemplateAttrVO attrVO = templateAttrVOS.get(i); Object text = attrVO.getName(); text = exportKeyAndRequired(workbook, attrVO, text); int colIndex = (isHistory ? 3 : 0) + i; WriteExcelData excelData = new WriteExcelData(0, colIndex, text, attrVO.getId()); if (StringUtils.isNotBlank(attrVO.getCodeDateFormat()) || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { excelData.setDateFormat(VciDateUtil.DateTimeFormat); } if (text instanceof RichTextString) { excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); } excelDataList.add(excelData); if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) { //添加数据有效性 List enumValueList = new ArrayList<>(); enumValueList.add(""); List valueList = engineService.listComboboxItems(attrVO); if (!CollectionUtils.isEmpty(valueList)) { valueList.stream().forEach(kv -> { enumValueList.add(kv.getValue()); }); } //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(enumValueList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { List booleanList = new ArrayList<>(); booleanList.add("是"); booleanList.add("否"); //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(booleanList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } } eo.addSheetDataList(j + templateVO.getName(), excelDataList); tempEDList.add(new WriteExcelData(j + 1, 0, templateVO.getOid())); tempEDList.add(new WriteExcelData(j + 1, 1, templateVO.getId())); tempEDList.add(new WriteExcelData(j + 1, 2, templateVO.getName())); } String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + (isHistory ? "_历史数据导入模板.xls" : "_导入模板.xls"); eo.addSheetDataList(templateVOList.size() + "模板信息【请勿删除或移动】", tempEDList); ExcelUtil.writeDataToFile(excelName, eo); return excelName; } /** * 生成批量修改导入的文件 * * @param codeClassifyOid 分类的主键 * @return excel的文件地址 */ @Override public String downloadImportExcelBatchEdit(String codeClassifyOid) { List templateVOList = new ArrayList<>(); VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键"); CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid); templateVOList = templateService.childTemplates(codeClassifyOid); WriteExcelOption eo = new WriteExcelOption(); eo.setAppend(true); //增加模板的信息导入 LinkedList tempEDList = new LinkedList<>(); tempEDList.add(new WriteExcelData(0, 0, "编号")); for (int j = 0; j < templateVOList.size(); j++) { CodeClassifyTemplateVO templateVO = templateVOList.get(j); CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO(); BeanUtils.copyProperties(templateVO, codeClassifyTemplateVO); //组合格式的不导入, // 枚举的提供序列的选择 //时间全部统一为yyyy-MM-dd HH:mm:ss //参照的自行输入名称 //分类注入的不用,都是导入后自动处理的 //编码,状态等字段不导入 List codeClassifyTemplateAttrVOList = codeClassifyTemplateVO.getAttributes(); if (!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) { if (CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) { throw new VciBaseException("模板没有配置属性"); } } List templateAttrVOS = codeClassifyTemplateAttrVOList.stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) && (VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); if (CollectionUtils.isEmpty(templateAttrVOS)) { throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性"); } // List idAttrVOList = codeClassifyTemplateVO.getAttributes().stream().filter(s -> s.getId().equalsIgnoreCase(CODE_FIELD)).collect(Collectors.toList()); LinkedList excelDataList = new LinkedList<>(); Workbook workbook = new HSSFWorkbook(); // if(isHistory){ excelDataList.add(new WriteExcelData(0, 0, "编码(id)", "")); // excelDataList.add(new WriteExcelData(0,1,"码段宽度","")); // excelDataList.add(new WriteExcelData(0,1,!CollectionUtils.isEmpty(idAttrVOList)?idAttrVOList.get(0).getName():"企业编码",idAttrVOList.get(0).getId())); // } for (int i = 0; i < templateAttrVOS.size(); i++) { CodeClassifyTemplateAttrVO attrVO = templateAttrVOS.get(i); Object text = attrVO.getName(); text = exportKeyAndRequired(workbook, attrVO, text); int colIndex = 1 + i; WriteExcelData excelData = new WriteExcelData(0, colIndex, text, attrVO.getId()); if (StringUtils.isNotBlank(attrVO.getCodeDateFormat()) || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType()) || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { excelData.setDateFormat(VciDateUtil.DateTimeFormat); } if (text instanceof RichTextString) { excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); } excelDataList.add(excelData); if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) { //添加数据有效性 List enumValueList = new ArrayList<>(); enumValueList.add(""); List valueList = engineService.listComboboxItems(attrVO); if (!CollectionUtils.isEmpty(valueList)) { valueList.stream().forEach(kv -> { enumValueList.add(kv.getValue()); }); } //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(enumValueList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) { List booleanList = new ArrayList<>(); booleanList.add("是"); booleanList.add("否"); //默认加1万条 WriteExcelData ed = new WriteExcelData(1, colIndex, ""); ed.setRowTo(100); ed.setColTo(colIndex); ed.setValidation(true); ed.setValidationDataList(booleanList); ed.setValidationErrorMsg("请在序列中选择正确的值"); excelDataList.add(ed); } } eo.addSheetDataList(j + templateVO.getName(), excelDataList); tempEDList.add(new WriteExcelData(j + 1, 0, templateVO.getOid())); tempEDList.add(new WriteExcelData(j + 1, 1, templateVO.getId())); tempEDList.add(new WriteExcelData(j + 1, 2, templateVO.getName())); } String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + ("_属性批量修改模板.xls"); eo.addSheetDataList(templateVOList.size() + "模板信息【请勿删除或移动】", tempEDList); ExcelUtil.writeDataToFile(excelName, eo); return excelName; } /** * 获取码段宽度 * * @param codeClassifyOid * @return */ private String getCodeSegmentWidth(String codeClassifyOid) { CodeClassifyFullInfoBO classifyFullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid); // 要获取码段宽度,先要获取规则,当前没有往上找 CodeRuleVO codeRuleByClassifyFullInfo = mdmEngineService.getCodeRuleByClassifyFullInfo(classifyService.getClassifyFullInfo(codeClassifyOid)); List secVOList = codeRuleByClassifyFullInfo.getSecVOList(); if (secVOList.isEmpty()) { return ""; } StringBuffer secWidth = new StringBuffer(""); secVOList.stream().forEach(item -> { switch (item.getSecType().toLowerCase(Locale.ROOT)) { case "codeclassifysec": case "codevariablesec": case "coderefersec": case "codefixedsec": case "codeattrsec": case "codeserialsec": countSecWith(item, secWidth); break; case "codelevelsec": //层级码段,需要从分类上获取相应的信息 String secValue = ""; if (CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(item.getCodeLevelType())) { //最小层,因为我们只能在叶子节点上申请编码,所以这个就是当前分类的 if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType()) || CollectionUtils.isEmpty(classifyFullInfoBO.getParentClassifyVOs())) { //就是当前分类的 secValue = classifyFullInfoBO.getCurrentClassifyVO().getId(); } else { //我们需要从顶层开始找到当前分类为止 secValue = classifyFullInfoBO.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).map(CodeClassifyVO::getId).collect(Collectors.joining()) + classifyFullInfoBO.getCurrentClassifyVO().getId(); } } else { //指定层,我们需要通过上级的来获取 if (CollectionUtils.isEmpty(classifyFullInfoBO.getParentClassifyVOs())) { //说明当前已经是最高的了 secValue = classifyFullInfoBO.getCurrentClassifyVO().getId(); } else { //这个我们需要看看,层级是不是大于了最大层级的数 List parentClassifyVOList = classifyFullInfoBO.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).collect(Collectors.toList()); if (item.getCodeLevelValue() > (parentClassifyVOList.size() + 1)) { //指定的层级比当前的层级还大了,所以只能获取当前层级了 if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType())) { secValue = classifyFullInfoBO.getCurrentClassifyVO().getId(); } else { secValue = parentClassifyVOList.stream().map(CodeClassifyVO::getId).collect(Collectors.joining()) + classifyFullInfoBO.getCurrentClassifyVO().getId(); } } else { //我们获取其中指定层的内容 if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType())) { CodeClassifyVO classifyVO = parentClassifyVOList.stream().filter(s -> s.getDataLevel().intValue() == item.getCodeLevelValue().intValue()).findFirst().orElseGet(() -> null); if (classifyVO != null) { secValue = classifyVO.getId(); } } else { //小于等于的全部拿出来 secValue = parentClassifyVOList.stream().filter(s -> s.getDataLevel().intValue() <= item.getCodeLevelValue().intValue()).sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).map(CodeClassifyVO::getId).collect(Collectors.joining()); } } } } //看看长度是否需要截断 if (!CodeCutTypeEnum.NONE.getValue().equalsIgnoreCase(item.getValueCutType()) && item.getValueCutLength() != null && item.getValueCutLength() > 0 && secValue.length() > item.getValueCutLength()) { if (CodeCutTypeEnum.RIGHT.getValue().equalsIgnoreCase(item.getValueCutType())) { //左截取是从左边剪掉,右截取是从右边剪掉--保留左边 secValue = secValue.substring(0, item.getValueCutLength()); } else { secValue = secValue.substring(secValue.length() - item.getValueCutLength()); } } secValue = productCodeService.joinPreffixAndSuffix(item, secValue); secWidth.append(secValue.length()).append("#"); break; case "codedatesec": String dateFormatStr = item.getCodeDateFormatStr(); if (Func.isNotEmpty(dateFormatStr)) { // 获取当前时间 Date currentDate = new Date(); // 指定日期格式 SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr); // 将当前时间转换为指定日期格式 // 使用正则表达式去掉除数字以外的所有字符串 String cleanedDate = dateFormat.format(currentDate).replaceAll("[^0-9]", ""); int width = cleanedDate.length(); if (Func.isNotEmpty(item.getPrefixCode())) { width += item.getPrefixCode().length(); } if (Func.isNotEmpty(item.getSuffixCode())) { width += item.getSuffixCode().length(); } secWidth.append(width).append("#"); } break; } }); return secWidth.toString().substring(0, secWidth.length() - 1); } /** * 计算码段长度加前后缀的长度 * * @param codeBasicSecVO * @param secWidth */ private void countSecWith(CodeBasicSecVO codeBasicSecVO, StringBuffer secWidth) { if (Func.isNotEmpty(codeBasicSecVO.getCodeSecLength())) { int width = VciBaseUtil.getInt(codeBasicSecVO.getCodeSecLength()); if (Func.isNotEmpty(codeBasicSecVO.getPrefixCode())) { width += codeBasicSecVO.getPrefixCode().length(); } if (Func.isNotEmpty(codeBasicSecVO.getSuffixCode())) { width += codeBasicSecVO.getSuffixCode().length(); } secWidth.append(width).append("#"); } else { secWidth.append(0).append("#"); } } /** * 导出的时候封装必输和关键属性 * * @param attrVO 属性的显示对象 * @param text 单元格的值 */ private Object exportKeyAndRequired(Workbook workbook, CodeClassifyTemplateAttrVO attrVO, Object text) { //必输加*,关键属性为蓝色 if (VciBaseUtil.getBoolean(attrVO.getRequireFlag()) || VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) { String value = text.toString(); if (VciBaseUtil.getBoolean(attrVO.getRequireFlag())) { value += REQUIRED_CHAR; } if (VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) { value += KEY_ATTR_CHAR; } RichTextString ts = new HSSFRichTextString(value); if (VciBaseUtil.getBoolean(attrVO.getRequireFlag())) { Font font = workbook.createFont(); font.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex()); ts.applyFont(font); } if (VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) { Font font = workbook.createFont(); font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex()); ts.applyFont(font); } return ts; } return text; } /** * 批量申请编码数据 * * @param orderDTO 编码申请信息,必须包含分类主键和码段的信息 * @param file excel文件的信息 * @return 有错误信息的excel的文件 */ @Override public CodeImProtRusultVO batchImportCode(CodeOrderDTO orderDTO, File file) throws Exception { VciBaseUtil.alertNotNull(orderDTO, "编码申请相关的数据", orderDTO.getCodeClassifyOid(), "主题库分类主键"); ReadExcelOption reo = new ReadExcelOption(); reo.setReadAllSheet(true); List sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo); if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData()) || sheetDataSetList.get(0).getRowData().size() < 1) { throw new VciBaseException("没有读取到任何的数据"); } if (sheetDataSetList.size() > LIMIT + 1) { throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据"); } //先找到每一行的标题,然后根据标题来获取对应的属性 SheetDataSet dataSet = sheetDataSetList.get(0); //找第一行,为了找标题 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid()); //校验模板是不是最新的 checkTemplateSync(sheetDataSetList, templateVO, 0); //先不用管属性是否都存在,先转换一下数据 Map errorMap = new ConcurrentHashMap<>(); String redisUUid = batchImportCodes(orderDTO, templateVO, dataSet, errorMap, true); CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO(); List needRowIndexList = new ArrayList<>(); String filePath = returnErrorToExcel(dataSet.getRowData(), errorMap, needRowIndexList, dataSet.getColName()); if (StringUtils.isNotBlank(filePath)) { codeImProtRusultVO.setFilePath(filePath); } if (StringUtils.isNotBlank(redisUUid)) { codeImProtRusultVO.setRedisUuid(redisUUid); } // return null; return codeImProtRusultVO; } /*** * 从顶层批量申请导入方法 * @param codeClassifyOid 分类的主键 * @param classifyAttr 分类路径使用的属性 * @param file excel文件的信息 * @return */ @Override public CodeImProtRusultVO batchTopImportCode(String codeClassifyOid, String classifyAttr, File file) { VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键"); ReadExcelOption reo = new ReadExcelOption(); reo.setReadAllSheet(true); List sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo); if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData()) || sheetDataSetList.get(0).getRowData().size() < 1) { throw new VciBaseException("没有读取到任何的数据"); } if (sheetDataSetList.size() > LIMIT + 1) { throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据"); } //先找到每一行的标题,然后根据标题来获取对应的属性 SheetDataSet dataSet = sheetDataSetList.get(0); CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid); //获取当前模板 CodeClassifyTemplateVO selectCodeClassifyTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid); Map> templateColumnVOMap = new HashMap<>(); createTemplate(selectCodeClassifyTemplateVO, templateColumnVOMap); List childClassifyVOs = classifyService.listChildrenClassify(codeClassifyOid, true, classifyAttr, true); Map pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t)); pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO()); List titleRowData = dataSet.getColName(); Map errorMap = new ConcurrentHashMap<>(); //首先将数据以模板的形式分开 LinkedHashMap> codeclassifyDataMap = new LinkedHashMap<>(); List codeClassifyDatas = new ArrayList<>(); createExeclClassData(dataSet, pathMap, errorMap, codeClassifyDatas); //根据模板将数据整合在一起,去校验 Map/**数据对象**/> templateDatasMap = codeClassifyDatas.stream().collect(Collectors.toMap(CodeImprotDataVO::getTemplateOid, s -> { List l = new ArrayList<>(); l.add(s); return l; }, (List s1, List s2) -> { s1.addAll(s2); return s1; })); String uuid = VciBaseUtil.getPk(); List codeImportTemplateVOS = new ArrayList<>(); Map codeRuleMap = new HashMap<>(); //相似数据 // MapwpResembleMap=new HashMap<>(); // List wpCodeImprotDataVOList=new ArrayList<>(); //按照模板去整理数据 templateDatasMap.keySet().stream().forEach(templateVOOid -> { List codeImprotDataVOS = templateDatasMap.get(templateVOOid); CodeClassifyTemplateVO templateVO = templateService.getObjectHasAttrByOid(templateVOOid); //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); Map fieldNameMap = attrVOS.stream().collect(Collectors.toMap(CodeClassifyTemplateAttrVO::getId, s -> s.getName())); List allCboList = new ArrayList<>(); codeImprotDataVOS.stream().forEach(codeImprotDataVO -> { List columnVOList = new ArrayList(); String templateOid = selectCodeClassifyTemplateVO.getOid(); if (templateColumnVOMap.containsKey(templateOid)) { columnVOList = columnVOList = templateColumnVOMap.get(templateOid); } else { createTemplate(templateVO, templateColumnVOMap); columnVOList = columnVOList = templateColumnVOMap.get(templateOid); } String codeRuleOid = codeImprotDataVO.getCodeRuleOid(); if (!codeRuleMap.containsKey(codeRuleOid)) { CodeImportTemplateVO codeImportTemplateVO = new CodeImportTemplateVO(); codeImportTemplateVO.setRoot(false); codeImportTemplateVO.setCodeClassifyOid(codeImprotDataVO.getCodeClassifyOid()); codeImportTemplateVO.setCodeRuleOid(codeImprotDataVO.getCodeRuleOid()); codeImportTemplateVO.setCodeTemplateOid(codeImprotDataVO.getTemplateOid()); codeImportTemplateVO.setCodeClassifyVO(codeImprotDataVO.getCodeClassifyVO()); codeImportTemplateVO.setCodeClassifyTemplateVO(codeImprotDataVO.getCodeClassifyTemplateVO()); codeImportTemplateVO.setCodeRuleVO(codeImprotDataVO.getCodeRuleVO()); List colNames = codeImprotDataVO.getColNames(); codeImportTemplateVO.setCloNamesList(columnVOList); codeImportTemplateVOS.add(codeImportTemplateVO); codeRuleMap.put(codeRuleOid, codeImportTemplateVO); } List cboList = new ArrayList<>(); excelToCbo(classifyFullInfo, codeImprotDataVO, cboList, true); allCboList.addAll(cboList); //往选择的节点里面加数据 // CodeImprotDataVO wpcodeImprotDataVO=new CodeImprotDataVO(); // BeanUtilForVCI.copyPropertiesIgnoreCase(codeImprotDataVO,wpcodeImprotDataVO); /* wpcodeImprotDataVO.setCodeClassifyOid(codeClassifyOid); wpcodeImprotDataVO.setCodeClassifyVO(classifyFullInfo.getCurrentClassifyVO()); wpcodeImprotDataVO.setCodeClassifyTemplateVO(selectCodeClassifyTemplateVO); wpcodeImprotDataVO.setCodeRuleOid(classifyFullInfo.getCurrentClassifyVO().getCoderuleoid());*/ // wpCodeImprotDataVOList.add(wpcodeImprotDataVO);//往物品对象里添加 }); //都转换完了。需要批量检查 //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中 //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则 batchCheckRequiredAttrOnOrder(templateVO, allCboList, errorMap); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, allCboList, false, errorMap); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) { selfRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前处理的数据文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } //分类注入 // batchSwitchClassifyAttrOnOrder(attrVOS,allCboList,classifyFullInfo,false); //boolean reSwitchBooleanAttrOnOrder(attrVOS, allCboList); //4.校验规则 batchCheckVerifyOnOrder(attrVOS, allCboList, errorMap); //是否需要校验枚举/参照 //5.校验枚举是否正确 batchSwitchEnumAttrOnOrder(attrVOS, allCboList, errorMap); //7.处理参照的情况 batchSwitchReferAttrOnOrder(attrVOS, allCboList, errorMap); //6.时间格式的验证 //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, allCboList, errorMap); //设置默认值 batchSwitchAttrDefault(attrVOS, allCboList); //最后弄组合规则 batchSwitchComponentAttrOnOrder(attrVOS, allCboList); Map rowIndexCboMap = allCboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t)); List needSaveCboList = allCboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); //相似校验 Map resembleMap = new HashMap<>(); List dataResembleVOS = new ArrayList<>(); String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); //相似项查询规则 bathcResembleQuery(codeClassifyOid, templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS); if (resembleMap.size() > 0) { if (!CollectionUtils.isEmpty(dataResembleVOS)) { bladeRedis.set(uuid + "-resemble-data", dataResembleVOS); bladeRedis.expire(uuid + "-resemble-data", BATCHADD_REDIS_TIME);//redis过期时间 // createRedisDatas(uuid + "-resemble", codeImprotDataVOS, resembleMap, false); // wpResembleMap.putAll(resembleMap); } } //排除错误的,剩下正确的 Map newErrorMap = new HashMap<>(); newErrorMap.putAll(resembleMap); newErrorMap.putAll(errorMap); needSaveCboList = allCboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !newErrorMap.containsKey(rowIndex); }).collect(Collectors.toList()); if (newErrorMap.size() > 0) { createRedisDatas(uuid + "-resemble", codeImprotDataVOS, newErrorMap, false); } createRedisDatas(uuid + "-ok", codeImprotDataVOS, newErrorMap, true); }); //往物品节点上加模板 List needRowIndexList = new ArrayList<>(); CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO(); if (errorMap.size() > 0) { String filePath = returnErrorToExcel(dataSet.getRowData(), errorMap, needRowIndexList, dataSet.getColName()); if (StringUtils.isNotBlank(filePath)) { codeImProtRusultVO.setFilePath(filePath); } } if (StringUtils.isNotBlank(uuid)) { //将所有的分类存入缓存之中 codeImProtRusultVO.setRedisUuid(uuid); /** ListcolumnVOList=new ArrayList<>(); CodeImportTemplateVO wpCodeImportTemplateVO=new CodeImportTemplateVO(); wpCodeImportTemplateVO.setRoot(true); wpCodeImportTemplateVO.setCodeClassifyTemplateVO(selectCodeClassifyTemplateVO); wpCodeImportTemplateVO.setCodeClassifyVO(classifyFullInfo.getCurrentClassifyVO()); String templateOid=selectCodeClassifyTemplateVO.getOid(); if(templateColumnVOMap.containsKey(templateOid)){ columnVOList= columnVOList=templateColumnVOMap.get(templateOid); }else{ createTemplate(selectCodeClassifyTemplateVO,templateColumnVOMap); columnVOList= columnVOList=templateColumnVOMap.get(templateOid); } wpCodeImportTemplateVO.setCloNamesList(columnVOList); codeImportTemplateVOS.add(wpCodeImportTemplateVO); if(wpResembleMap.size()>0){ // redisService.setCacheList(uuid + "-resemble-data", wpDataResembleVOList); createRedisDatas(uuid + "-resemble",selectCodeClassifyTemplateVO, wpCodeImprotDataVOList, wpResembleMap, false,codeClassifyOid); } //排除错误的,剩下正确的 Map newErrorMap=new HashMap<>(); newErrorMap.putAll(wpResembleMap); newErrorMap.putAll(errorMap); List needSaveCboList = wpCodeImprotDataVOList.stream().filter(cbo -> { String rowIndex = cbo.getRowIndex(); return !newErrorMap.containsKey(rowIndex); }).collect(Collectors.toList()); createRedisDatas(uuid + "-ok",selectCodeClassifyTemplateVO,wpCodeImprotDataVOList, newErrorMap,true,codeClassifyOid);****/ if (codeImportTemplateVOS.size() > 0) { bladeRedis.set(uuid + "-class", codeImportTemplateVOS); bladeRedis.expire(uuid + "-class", BATCHADD_REDIS_TIME); } } return codeImProtRusultVO; } /** * 导入历史数据 * * @param codeClassifyOid 分类的主键 * @param classifyAttr 分类路径使用的属性 * @param file excel文件的信息 * @return 有错误信息的excel */ @Override public CodeImProtRusultVO batchImportHistoryData(String codeClassifyOid, String classifyAttr, File file) throws Throwable { try { VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键"); ReadExcelOption reo = new ReadExcelOption(); reo.setReadAllSheet(true); List sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo); if (sheetDataSetList.size() > LIMIT + 1) { throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据"); } Map> shetNameMap = new HashMap<>(); //相似项目查重 String uuid = VciBaseUtil.getPk(); boolean isCreateUUid = false; boolean isExport = false; //long start = System.currentTimeMillis(); // 记录导入成功的总数 List importCount = new ArrayList<>(); CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid); for (int i = 0; i < sheetDataSetList.size() - 1; i++) { if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(i).getRowData()) || sheetDataSetList.get(i).getRowData().size() < 1) { continue; } // 单次导入数量限制 if (sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT) { throw new ServiceException(StringUtil.format("为了保证系统的稳定性,请一次不要导入超过{}条的数据", IMPORT_DATA_LIMIT)); } //历史导入的时候不处理编码 //----逻辑内容---- //1. 分类的路径可以在页面上选择是分类编号还是分类的名称 //2. 分类的路径,必须是当前导入选择的分类的节点,以及其下级节点 //3. 通过数据要导入的分类去查找对应的编码规则 //4. 数据存储和批量申请一样, //5. 需要单独处理企业编码的内容, // 5.1 企业编码在当前excel里不能重复 // 5.2 企业编码在系统中不能重复(可以是已经回收的) // 5.3 企业编码的长度,和编码规则的长度要对应上 // 5.4 获取流水码段的值,去除填充的字符,看流水号是多少,然后将流水号和现在的最大流水号判断,小于就直接录入,大于则修改最大流水号 // 5.5 存储企业编码到allcode中 //查询分类和模板 //先找到每一行的标题,然后根据标题来获取对应的属性 SheetDataSet dataSet = sheetDataSetList.get(i); List rowDataList = dataSet.getRowData(); //找第一行,为了找标题 CodeClassifyTemplateVO templateVO = new CodeClassifyTemplateVO(); /** if (!templateService.checkChildHasSameTemplate(classifyFullInfo.getCurrentClassifyVO().getOid())) { throw new VciBaseException("当前的分类以及下级分类的模板不相同"); }***/ //都转换完了。需要批量检查 //找所有的分类路径,需要校验路径是否正确,是否都在当前的分类的下级 List childClassifyVOs = classifyService.listChildrenClassify(codeClassifyOid, true, classifyAttr, true); Map pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t)); List titleRowData = dataSet.getColName(); Map errorMap = new ConcurrentHashMap<>(); pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO()); try { List templateVOList = checkSamesTemplate(titleRowData, sheetDataSetList, i, pathMap, errorMap); templateVO = templateVOList.get(0); } catch (Throwable e) { throw new VciBaseException(e.getMessage()); } List needowDataList = rowDataList.stream().filter(cbo -> { String rowIndex = cbo.getRowIndex(); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); //checkTemplateSync(sheetDataSetList, templateVO,i); //这里不除去默认的属性 List attrVOS = templateVO.getAttributes(); Map fieldIndexMap = new HashMap<>(); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId())); String idFieldName = attrVOS.stream().filter(s -> VciQueryWrapperForDO.ID_FIELD.equalsIgnoreCase(s.getId())).findFirst().orElseGet(() -> new CodeClassifyTemplateAttrVO()).getName(); getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap); //先不用管属性是否都存在,先转换一下数据 List cboList = new ArrayList<>(); String fullPath = getFullPath(classifyFullInfo); //我们需要获取到所有的下级分类的oid的路径,因为后面需要 Map childOidPathMap = getChildClassifyPathMap(classifyFullInfo, fullPath); excelToCbo(classifyFullInfo, fieldIndexMap, needowDataList, templateVO, cboList, fullPath, false); Map classifyVOMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getOid(), t -> t)); classifyVOMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO()); pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO()); //判断编号在excel里本身就重复的 Map idCountMap = cboList.stream().collect(Collectors.groupingBy(ClientBusinessObject::getId, Collectors.counting())); List repeatIdList = new ArrayList<>(); idCountMap.forEach((id, count) -> { if (count > 1) { repeatIdList.add(id); } }); if (!CollectionUtils.isEmpty(repeatIdList)) { cboList.stream().filter(s -> repeatIdList.contains(s.getId())).map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).forEach(rowIndex -> { errorMap.put(rowIndex, "编号在当前excel中重复;"); }); } //我们需要判断这些分类的模板是不是一样的,只需要校验,不用获取 //检查分类的路径 checkClassifyPathInHistory(cboList, errorMap, pathMap, childOidPathMap); //检查规则 Map ruleOidMap = new ConcurrentHashMap(); List unExistRuleClassifyOidList = new CopyOnWriteArrayList<>(); checkRuleOidInHistory(classifyVOMap, ruleOidMap, unExistRuleClassifyOidList); //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中 //我们根据出错的分类的主键,去找行号 if (!CollectionUtils.isEmpty(unExistRuleClassifyOidList)) { cboList.stream().forEach(cbo -> { if (unExistRuleClassifyOidList.contains(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD))) { String row_index = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(row_index, errorMap.getOrDefault(row_index, "") + ";根据分类路径对应的分类,没有设置编码规则"); } }); } //判断必输项 batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap); //优先校验编码是否存在 batchCheckIdExistOnOrder(templateVO, cboList, errorMap); //boolean reSwitchBooleanAttrOnOrder(attrVOS, cboList); // 枚举的内容需要根据名称转换为枚举的值 batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap); batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap); //6.处理分类注入 batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, true); //设置默认值 batchSwitchAttrDefault(attrVOS, cboList); //7.处理组合规则 batchSwitchComponentAttrOnOrder(attrVOS, cboList); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorMap); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) { selfRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前excel文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } //4.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap); if (CollectionUtils.isEmpty(ruleOidMap.values())) { throw new VciBaseException("导入的数据所选择的分类都没有设置编码规则"); } // TODO: 该用oid查询规则的,别用id Map ruleVOMap = ruleService.listCodeRuleByOids(ruleOidMap.values()).stream().collect(Collectors.toMap(s -> s.getOid(), t -> t)); //校验编码规则和码段是否正确 Map> ruleRowIndexMap = new ConcurrentHashMap<>(); checkSecLengthInHistory(cboList, classifyVOMap, ruleVOMap, ruleOidMap, errorMap, ruleRowIndexMap); ruleRowIndexMap.keySet().parallelStream().forEach(ruleOid -> { List rowIndexList = ruleRowIndexMap.get(ruleOid); List thisCbos = cboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList()); //我们需要先查询一下,内容是否已经存在 if (!CollectionUtils.isEmpty(thisCbos)) { List existIds = new ArrayList<>(); // TODO: 2024/12/3 Ludc 这儿查询做了修改改成组成一句sql查询,而不是分批次查询 LambdaQueryWrapper wrapper = Wrappers.query().lambda() .eq(CodeAllCode::getCodeRuleOid, ruleOid); VciBaseUtil.switchCollectionForOracleIn(thisCbos).stream().forEach(cbos -> { wrapper.notIn(CodeAllCode::getId, cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0])); }); wrapper.notIn(CodeAllCode::getLcStatus, CodeAllCodeLC.TASK_BACK.getValue() + "','" + CodeAllCodeLC.OBSOLETED.getValue()); List codeAllCodeList = codeAllCodeService.selectByWrapper(wrapper); existIds.addAll(Optional.ofNullable(codeAllCodeList).orElseGet(() -> new ArrayList<>()).stream().map(s -> { String id = s.getId(); if (StringUtils.isBlank(id)) { id = s.getId(); } return id; }).collect(Collectors.toList())); List existIdCbos = thisCbos.stream().filter(s -> { String id = s.getId(); if (StringUtils.isBlank(id)) { id = s.getAttributeValue("id"); } return existIds.contains(id); }).map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(existIdCbos)) { thisCbos = thisCbos.stream().filter(s -> { String id = s.getId(); if (StringUtils.isBlank(id)) { id = s.getAttributeValue("id"); } return !existIdCbos.contains(id); }).collect(Collectors.toList()); existIdCbos.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";【" + idFieldName + "】在系统中已经被占用"); }); } } }); Map rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t)); if (errorMap.size() > 0) { isExport = true; createRedisDatas(uuid + "-error", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap, false); } createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, templateVO); List needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); //相似校验 Map resembleMap = new HashMap<>(); List dataResembleVOS = new ArrayList<>(); String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); // 相似项查询 bathcResembleQuery(templateVO.getCodeclassifyoid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS); if (resembleMap.size() > 0) { if (!CollectionUtils.isEmpty(dataResembleVOS)) { bladeRedis.set(uuid + "-resemble-data", dataResembleVOS); createRedisDatas(uuid + "-resemble", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false); } } //生成class缓存 Map 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 newErrorMap = new HashMap<>(); newErrorMap.putAll(resembleMap); newErrorMap.putAll(errorMap); //要把以上的错误的都抛出后,再继续处理时间和组合规则 needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !newErrorMap.containsKey(rowIndex); }).collect(Collectors.toList()); if ((errorMap.size() > 0 && needSaveCboList.size() > 0) || resembleMap.size() > 0) { isCreateUUid = true; } List needRowIndexList = needSaveCboList.stream().filter(s -> errorMap.containsKey(s.getAttributeValue(IMPORT_ROW_INDEX))).map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toList()); if (isExport || newErrorMap.size() > 0) { createRedisDatas(uuid + "-ok", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap, true); } else { List dataCBOIdList = new ArrayList<>(); //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo(); List finalNeedSaveCboList = needSaveCboList; CodeClassifyTemplateVO finalTemplateVO = templateVO; final BladeUser user = AuthUtil.getUser(); ruleRowIndexMap.keySet().parallelStream().forEach(ruleOid -> { //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo); List rowIndexList = ruleRowIndexMap.get(ruleOid); List thisCbos = finalNeedSaveCboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList()); List dataCBOList = new CopyOnWriteArrayList<>(); thisCbos.stream().forEach(clientBusinessObject -> { BaseModel baseModel = new BaseModel(); BeanUtil.convert(clientBusinessObject, baseModel); //baseModel.setData(VciBaseUtil.objectToMapString(clientBusinessObject)); dataCBOList.add(baseModel); dataCBOIdList.add(baseModel); }); if (!CollectionUtils.isEmpty(thisCbos)) { try { // TODO 多线程流问题 productCodeService.productCodeAndSaveData(classifyFullInfo, finalTemplateVO, ruleVOMap.get(ruleOid), null, dataCBOList, user); importCount.add(dataCBOList.size()); } catch (Throwable e) { log.error("批量产生编码的时候出错了", e); thisCbos.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage()); }); } } }); if (errorMap.size() > 0) { isExport = true; } createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, finalTemplateVO); engineService.batchSaveSelectChar(templateVO, dataCBOIdList); } } String excelFileName = ""; if (isExport && !CollectionUtils.isEmpty(shetNameMap)) { excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls"; WriteExcelOption eo = new WriteExcelOption(); shetNameMap.forEach((shetName, errorDataList) -> { eo.addSheetDataList(shetName, errorDataList); }); try { new File(excelFileName).createNewFile(); } catch (IOException e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e)); } ExcelUtil.writeDataToFile(excelFileName, eo); saveLogUtil.operateLog("历史数据导入", true, StringUtil.format("错误信息:{}", JSON.toJSONString(shetNameMap))); } else { // 历史数据导入时出现了相似项返回结果时不算导入成功 if (shetNameMap.isEmpty() || !isCreateUUid) { saveLogUtil.operateLog("历史数据导入", false, StringUtil.format("导入到分类{}中,导入成功总数为:{}", JSON.toJSONString(classifyFullInfo), Func.isEmpty(importCount) ? 0 : importCount.get(0))); } } CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO(); if (StringUtils.isNotBlank(excelFileName)) { codeImProtRusultVO.setFilePath(excelFileName); codeImProtRusultVO.setFileOid(""); } if (isCreateUUid) { codeImProtRusultVO.setRedisUuid(uuid); } return codeImProtRusultVO; } catch (Exception e) { saveLogUtil.operateLog("历史数据导入", true, e.toString()); throw e; } } /** * 导入批量编辑数据 * * @param codeClassifyOid 分类的主键 * @param classifyAttr 分类路径使用的属性 * @param file excel文件的信息 * @return 有错误信息的excel */ @Transactional @Override public CodeImProtRusultVO batchImportEdit(String codeClassifyOid, String classifyAttr, File file) throws Throwable { VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键"); ReadExcelOption reo = new ReadExcelOption(); reo.setReadAllSheet(true); List sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo); if (sheetDataSetList.get(0).getRowData().size() > LIMIT + 1) { throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过1万条的数据"); } if (sheetDataSetList.get(0).getRowData().size() == 0) { throw new ServiceException("未读取到excle相关数据,请确认!!!"); } boolean isExport = false; Map> shetNameMap = new HashMap<>(); for (int i = 0; i < sheetDataSetList.size() - 1; i++) { if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(i).getRowData()) || sheetDataSetList.get(i).getRowData().size() < 1) { continue; } // 单次导入数量限制 if (sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT) { throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过" + IMPORT_DATA_LIMIT + "条的数据"); } //查询分类和模板 CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid); //先找到每一行的标题,然后根据标题来获取对应的属性 SheetDataSet dataSet = sheetDataSetList.get(i); List rowDataList = dataSet.getRowData(); //找第一行,为了找标题 CodeClassifyTemplateVO templateVO; //都转换完了。需要批量检查 //找所有的分类路径,需要校验路径是否正确,是否都在当前的分类的下级 List childClassifyVOs = classifyService.listChildrenClassify(codeClassifyOid, true, classifyAttr, true); Map pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t)); List titleRowData = dataSet.getColName(); Map errorMap = new ConcurrentHashMap<>(); pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO()); try { titleRowData.add("分类路径"); List templateVOList = checkSamesTemplate(titleRowData, sheetDataSetList, i, pathMap, errorMap); titleRowData.remove(titleRowData.size() - 1); templateVO = templateVOList.get(0); } catch (Throwable e) { throw new ServiceException(e.getMessage()); } CodeClassifyTemplateVO finalTemplateVO = templateVO; List needowDataList = rowDataList.stream().filter(cbo -> { String rowIndex = cbo.getRowIndex(); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); //这里不除去默认的属性 List attrVOS = templateVO.getAttributes(); Map fieldIndexMap = new HashMap<>(); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId())); fieldIndexMap.put(0, "id"); getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap); //先不用管属性是否都存在,先转换一下数据 CodeOrderDTO orderDTO = new CodeOrderDTO(); for (SheetRowData sheetRowData : needowDataList) { //查询数据 Map conditionMap = new HashMap<>(); conditionMap.put("t.id", sheetRowData.getData().get(0)); conditionMap.put("t.lastv", "1"); CodeTemplateAttrSqlBO sqlBO = mdmEngineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, new PageHelper(-1)); //我们使用和业务类型的来查询 List cbosB = commonsMapper.selectBySql(sqlBO.getSqlUnPage()); if (cbosB.size() == 0) { throw new ServiceException("编码:" + sheetRowData.getData().get(0) + ",未能查询到相关数据。"); } excelToCboEdit(fieldIndexMap, sheetRowData, orderDTO, cbosB.get(0)); orderDTO.setCopyFromVersion(orderDTO.getOid()); orderDTO.setOid(null); try { mdmEngineService.upSaveCode(orderDTO); } catch (Throwable e) { log.error("批量产生编码的时候出错了", e); errorMap.put(sheetRowData.getRowIndex(), ";系统错误,存储数据的时候出错了:" + e.getMessage()); } } if (errorMap.size() > 0) { isExport = true; } createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, finalTemplateVO); } String excelFileName = ""; if (isExport && !CollectionUtils.isEmpty(shetNameMap)) { excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls"; WriteExcelOption eo = new WriteExcelOption(); shetNameMap.forEach((shetName, errorDataList) -> { eo.addSheetDataList(shetName, errorDataList); }); try { new File(excelFileName).createNewFile(); } catch (IOException e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e)); } ExcelUtil.writeDataToFile(excelFileName, eo); } CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO(); if (StringUtils.isNotBlank(excelFileName)) { codeImProtRusultVO.setFilePath(excelFileName); codeImProtRusultVO.setFileOid(""); saveLogUtil.operateLog("数据批量更改", true, StringUtil.format("错误信息:{}", JSON.toJSONString(shetNameMap))); } else { saveLogUtil.operateLog("数据批量更改", false, StringUtil.format("导入成功总数为:{}", sheetDataSetList.size() - 1)); } return codeImProtRusultVO; } /*private void converBaseModels(List clientBusinessObjects,ListdataCBOList){ clientBusinessObjects.stream().forEach(clientBusinessObject -> { BaseModel baseModel=new BaseModel(); BeanUtil.convert(clientBusinessObject,baseModel); Map dataMap=new HashMap<>(); clientBusinessObject.getHisAttrValList() baseModel.setData(VciBaseUtil.objectToMapString(baseModel)); AttributeValue[] newAttributeValue= clientBusinessObject.getNewAttrValList(); dataCBOList.add(baseModel); }); }*/ /*** * 从execl里构建对象 * @param rowDataList * @param errorMap * @param needRowIndexList * @param titleRowData * @param shetNameMap * @param templateVO */ private void createWriteExcelData(Collection rowDataList, Map errorMap, List needRowIndexList, List titleRowData, Map> shetNameMap, CodeClassifyTemplateVO templateVO) { List errorDataList = new ArrayList<>(); Map rowIndexDataMap = rowDataList.stream().filter(s -> !needRowIndexList.contains(s.getRowIndex())).collect(Collectors.toMap(s -> s.getRowIndex(), t -> t)); errorDataList.add(new WriteExcelData(0, 0, "错误信息")); for (int i = 0; i < titleRowData.size(); i++) { //错误信息在最后 errorDataList.add(new WriteExcelData(0, i + 1, titleRowData.get(i))); } Integer[] newRowIndex = new Integer[]{1}; errorMap.forEach((index, error) -> { //错误信息全部组合到一起 SheetRowData rowData = rowIndexDataMap.getOrDefault(index, null); if (rowData != null) { errorDataList.add(new WriteExcelData(newRowIndex[0], 0, error)); rowData.getData().forEach((colIndex, value) -> { errorDataList.add(new WriteExcelData(newRowIndex[0], colIndex + 1, value)); }); newRowIndex[0]++; } }); shetNameMap.put(templateVO.getName(), errorDataList); } /*** * * @param currentTemplateVO * @param templateColumnVOMap */ private void createTemplate(CodeClassifyTemplateVO currentTemplateVO, Map> templateColumnVOMap) { List templateAttrVOS = currentTemplateVO.getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) && (VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); if (CollectionUtils.isEmpty(templateAttrVOS)) { throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性"); } List columnVOList = new ArrayList<>(); ColumnVO errorMsgColumnVO = new ColumnVO(); errorMsgColumnVO.setTitle("错误信息"); errorMsgColumnVO.setField("errorMsg"); columnVOList.add(errorMsgColumnVO); ColumnVO pathColumnVO = new ColumnVO(); pathColumnVO.setTitle("分类路径"); pathColumnVO.setField("codeclsfid"); columnVOList.add(pathColumnVO); templateAttrVOS.stream().forEach(codetemplateAttr -> { String field = codetemplateAttr.getId(); String name = codetemplateAttr.getName(); ColumnVO columnVO = new ColumnVO(); columnVO.setTitle(name); columnVO.setField(field); columnVO.setWidth(codetemplateAttr.getAttrTableWidth() == 0 ? columnVO.getWidth() : codetemplateAttr.getAttrTableWidth()); columnVOList.add(columnVO); }); templateColumnVOMap.put(currentTemplateVO.getOid(), columnVOList); log.info("模板" + currentTemplateVO.getName() + "对应的属性" + columnVOList.size()); } /** * 错误信息返回excel * * @param rowDataList 所有的导入数据 * @param errorMap 错误的信息 * @param needRowIndexList 需要写入的数据的行号 * @param titleRowData 标题行 * @return 错误的excel文件,没有错误会返回空 */ private String returnErrorToExcel(Collection rowDataList, Map errorMap, List needRowIndexList, List titleRowData) { if (CollectionUtils.isEmpty(errorMap)) { return ""; } Map rowIndexDataMap = rowDataList.stream().filter(s -> !needRowIndexList.contains(s.getRowIndex())).collect(Collectors.toMap(s -> s.getRowIndex(), t -> t)); List errorDataList = new ArrayList<>(); errorDataList.add(new WriteExcelData(0, 0, "错误信息")); for (int i = 0; i < titleRowData.size(); i++) { //错误信息在最后 errorDataList.add(new WriteExcelData(0, i + 1, titleRowData.get(i))); } Integer[] newRowIndex = new Integer[]{1}; errorMap.forEach((index, error) -> { //错误信息全部组合到一起 SheetRowData rowData = rowIndexDataMap.getOrDefault(index, null); if (rowData != null) { errorDataList.add(new WriteExcelData(newRowIndex[0], 0, error)); rowData.getData().forEach((colIndex, value) -> { errorDataList.add(new WriteExcelData(newRowIndex[0], colIndex + 1, value)); }); newRowIndex[0]++; } }); String excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls"; WriteExcelOption eo = new WriteExcelOption(errorDataList); try { new File(excelFileName).createNewFile(); } catch (IOException e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e)); } ExcelUtil.writeDataToFile(excelFileName, eo); return excelFileName; } /** * 校验模板是否为同步的 * * @param sheetDataSetList excel里的内容 * @param templateVO 模板的信息 */ private void checkTemplateSync(List sheetDataSetList, CodeClassifyTemplateVO templateVO, int i) { String templateOidInExcel = ""; String templateName = ""; if (!CollectionUtils.isEmpty(sheetDataSetList) && sheetDataSetList.size() > 1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size() - 1).getColName())) { List rowData = sheetDataSetList.get(sheetDataSetList.size() - 1).getRowData(); templateName = rowData.get(i).getData().get(2); templateOidInExcel = rowData.get(i).getData().get(0); //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i); } /* if(!CollectionUtils.isEmpty(sheetDataSetList) && sheetDataSetList.size()>1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size()-1).getColName())){ List rowData= sheetDataSetList.get(sheetDataSetList.size()-1).getRowData(); templateOidInExcel=rowData.get(i).getData().get(0); //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i); }*/ if (StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(templateVO.getOid())) { throw new VciBaseException("模板【" + templateName + "】中的数据获取的模版信息与当前模板不匹配,请确保excel文件里有【模板信息-请勿移动或删除】的工作表,且确保每次导入都是先下载的导入模板后添加的数据"); } } /*** * 批量处理申请数据 * @param orderDTO * @param templateVO * @param dataSet * @return */ private String batchImportCodes(CodeOrderDTO orderDTO, CodeClassifyTemplateVO templateVO, SheetDataSet dataSet, Map errorMap, boolean isEnumType) throws Exception { List codeList = new ArrayList<>(); String uuid = ""; try { CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid()); //规则的主键需要去获取 CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo); //1.判断规则中除了流水码段,是否有其他码段 engineService.checkSecValueOnOrder(ruleVO, orderDTO); List rowDataList = dataSet.getRowData(); //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); Map fieldIndexMap = new HashMap<>(); List titleRowData = dataSet.getColName(); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT), (o1, o2) -> o2)); getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap); //需要判断是否所有的属性都在模板上了 List unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT)) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去 ).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(unExistAttrVOs)) { throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在列表中没有找到"); } List cboList = new ArrayList<>(); String fullPath = getFullPath(classifyFullInfo); excelToCbo(classifyFullInfo, fieldIndexMap, rowDataList, templateVO, cboList, fullPath, true); //都转换完了。需要批量检查 //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中 //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则 batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorMap); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) { selfRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前处理的数据文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } //分类注入 batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false); //boolean reSwitchBooleanAttrOnOrder(attrVOS, cboList); //4.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); if (isEnumType) {//是否需要校验枚举/参照 //5.校验枚举是否正确 batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap); //7.处理参照的情况 batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap); } //6.时间格式的验证 //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap); //最后弄组合规则 batchSwitchComponentAttrOnOrder(attrVOS, cboList); uuid = VciBaseUtil.getPk(); Map rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t)); if (errorMap.size() > 0) { createRedisDatas(uuid + "-error", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap, false); } boolean isCreateUUid = false; List needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); //相似校验 Map resembleMap = new HashMap<>(); List dataResembleVOS = new ArrayList<>(); String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); //相似项查询 bathcResembleQuery(orderDTO.getCodeClassifyOid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS); if (resembleMap.size() > 0) { isCreateUUid = true; if (!CollectionUtils.isEmpty(dataResembleVOS)) { bladeRedis.set(uuid + "-resemble-data", dataResembleVOS); createRedisDatas(uuid + "-resemble", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false); } } //排除错误的,剩下正确的 Map newErrorMap = new HashMap<>(); newErrorMap.putAll(resembleMap); newErrorMap.putAll(errorMap); needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !newErrorMap.containsKey(rowIndex); }).collect(Collectors.toList()); if ((errorMap.size() > 0 && needSaveCboList.size() > 0) || resembleMap.size() > 0) { isCreateUUid = true; } createRedisByCodeClassify(uuid + "-class", templateVO, dataSet, fieldIndexMap, false); if (newErrorMap.size() > 0) { createRedisDatas(uuid + "-ok", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap, true); } else { uuid = ""; final BladeUser user = AuthUtil.getUser(); //要把以上的错误的都抛出后,再继续处理时间和组合规则 needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !newErrorMap.containsKey(rowIndex); }).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(needSaveCboList)) { //9.我们处理业务数据 //生成编码的内容 List dataCBOIdList = new ArrayList<>(); List dataCBOList = new ArrayList<>(); cboList.stream().forEach(clientBusinessObject -> { BaseModel baseModel = new BaseModel(); BeanUtil.convert(clientBusinessObject, baseModel); //baseModel.setData(VciBaseUtil.objectToMapString(clientBusinessObject)); dataCBOList.add(baseModel); dataCBOIdList.add(baseModel.getOid()); }); try { codeList = productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList, user); //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面 engineService.batchSaveSelectChar(templateVO, dataCBOList); } catch (Exception e) { e.printStackTrace(); log.error("批量申请时失败"); throw e; } } } if (!isCreateUUid) { return uuid = ""; } saveLogUtil.operateLog("批量申请编码", false, StringUtil.format("批量导入申请成功共{}条数据,生成的码值如下【{}】", codeList.size(), codeList)); } catch (Exception e) { saveLogUtil.operateLog("批量申请编码", true, e.toString()); throw e; } return uuid; } @Override public List gridclassifys(String redisOid) { List codeImportTemplateVOs = new ArrayList<>(); VciBaseUtil.alertNotNull(redisOid, "分类", redisOid, "分类缓存主键"); List redisServiceCacheObjects = bladeRedis.get(redisOid); if (redisServiceCacheObjects != null) { codeImportTemplateVOs = redisServiceCacheObjects; } return codeImportTemplateVOs; } /*** * 从缓存里获取到需要导入的相关数据 * @param codeClssifyOid * @param redisOid * @return */ @Override public DataGrid> gridDatas(String codeClssifyOid, String redisOid) { VciBaseUtil.alertNotNull(redisOid, "导入相似数据", redisOid, "数据缓存主键"); List codeImprotDataVOs = bladeRedis.get(redisOid + "-" + codeClssifyOid); // redisService.getCacheList(redisOid+"-"+codeClssifyOid); CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO(); if (!CollectionUtils.isEmpty(codeImprotDataVOs)) { if (StringUtils.isNotBlank(codeClssifyOid)) { Map codeClassifyDatasMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getCodeClassifyOid(), t -> t, (o1, o2) -> o2)); if (codeClassifyDatasMap.containsKey(codeClssifyOid)) { codeImprotDataVO = codeClassifyDatasMap.get(codeClssifyOid); } else { codeImprotDataVO = codeImprotDataVOs.get(0); } } } DataGrid> dataGrid = new DataGrid<>(); List> dataList = new ArrayList<>(); if (codeImprotDataVO != null) { dataList = codeImprotDataVO.getDatas(); } dataGrid.setData(dataList); if (!CollectionUtils.isEmpty(dataList)) { dataGrid.setTotal(dataList.size()); } return dataGrid; } /** * @param oid * @param redisOid * @return */ @Override public DataGrid> gridRowResemble(String oid, String redisOid) { VciBaseUtil.alertNotNull(redisOid, "导入相似数据", redisOid, "数据缓存主键"); List codeImprotDataVOs = bladeRedis.get(redisOid); ; DataGrid> dataGrid = new DataGrid<>(); List> dataList = new ArrayList<>(); if (!CollectionUtils.isEmpty(codeImprotDataVOs)) { Map rowResembleDataMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getOid(), t -> t, (o1, o2) -> o2)); if (rowResembleDataMap.containsKey(oid)) { DataResembleVO dataResembleVO = rowResembleDataMap.get(oid); dataList = dataResembleVO.getDataList(); } } dataGrid.setData(dataList); if (!CollectionUtils.isEmpty(dataList)) { dataGrid.setTotal(dataList.size()); } return dataGrid; } /** * 导出主题库的数据 * * @param exportAttrDTO 导出相关的配置,必须要有主题库分类的主键 * @return 导出的excel的文件 */ @Override public String exportCode(CodeExportAttrDTO exportAttrDTO) { VciBaseUtil.alertNotNull(exportAttrDTO, "导出的配置", exportAttrDTO.getCodeClassifyOid(), "主题库分类的主键"); CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(exportAttrDTO.getCodeClassifyOid()); //获取最新的模板 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(exportAttrDTO.getCodeClassifyOid()); //先查询数据 String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); Map conditionMap = exportAttrDTO.getConditionMap(); if (conditionMap == null) { conditionMap = new HashMap<>(); } if (conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)) { conditionMap.put(VciQueryWrapperForDO.OID_FIELD, QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")"); } PageHelper pageHelper = new PageHelper(exportAttrDTO.getLimit() == null ? -1 : exportAttrDTO.getLimit()); pageHelper.setPage(exportAttrDTO.getPage() == null ? 1 : exportAttrDTO.getPage()); pageHelper.setSort(exportAttrDTO.getSort()); pageHelper.setOrder(exportAttrDTO.getOrder()); pageHelper.addDefaultDesc("createTime"); conditionMap.put("codeclsfpath", "*" + exportAttrDTO.getCodeClassifyOid() + "*"); conditionMap.put("lastr", "1"); conditionMap.put("lastv", "1"); R> listR = btmTypeClient.selectByIdCollection(Arrays.asList(btmTypeId)); String tableName = ""; if (listR.isSuccess() && !listR.getData().isEmpty()) { tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName() : VciBaseUtil.getTableName(btmTypeId); } else { tableName = VciBaseUtil.getTableName(btmTypeId); } String countSql = "select count(*) from " + tableName + " where 1=1" + " and lastr = '1'" + " and lastv='1'" + " and codeclsfpath like '%" + exportAttrDTO.getCodeClassifyOid() + "%'"; //先查询总数 int total = 0; if (exportAttrDTO.getEndPage() != null && exportAttrDTO.getEndPage() > 0 && exportAttrDTO.getPage() != null && exportAttrDTO.getPage() > 0 && exportAttrDTO.getEndPage() > exportAttrDTO.getPage()) { //从多少页到多少页的查询方式, String countPageSql = "select count(*) from (select * FROM " + tableName + " where 1=1" + " and lastr = '1'" + " and lastv='1'" + " and codeclsfpath like '%" + exportAttrDTO.getCodeClassifyOid() + "%' {}"; for (int i = exportAttrDTO.getPage(); i <= exportAttrDTO.getEndPage(); i++) { PageHelper thisPage = new PageHelper(exportAttrDTO.getLimit() == null ? -1 : exportAttrDTO.getLimit()); thisPage.setPage(exportAttrDTO.getPage() == null ? 1 : exportAttrDTO.getPage()); thisPage.setSort(exportAttrDTO.getSort()); thisPage.setOrder(exportAttrDTO.getOrder()); thisPage.addDefaultDesc("createTime"); total += commonsMapper.queryCountBySql(StringUtil.format(countPageSql, " limit " + exportAttrDTO.getLimit() + " offset " + i + ")subquery;")); } } else { total = commonsMapper.queryCountBySql(countSql); } List selectFieldList = new ArrayList<>(); if (!CollectionUtils.isEmpty(exportAttrDTO.getAttrIdIndexMap())) { selectFieldList = exportAttrDTO.getAttrIdIndexMap().values().stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toList()); } else { selectFieldList = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getFormDisplayFlag()) || VciBaseUtil.getBoolean(s.getTableDisplayFlag())).map(s -> s.getId().toLowerCase(Locale.ROOT)).collect(Collectors.toList()); } //参照让平台直接查询就行 List finalSelectFieldList = selectFieldList; List referAttrVOs = templateVO.getAttributes().stream().filter( s -> StringUtils.isNotBlank(s.getReferBtmId()) && (finalSelectFieldList.size() == 0 || finalSelectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))) ).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(referAttrVOs)) { for (int i = 0; i < referAttrVOs.size(); i++) { selectFieldList.add(referAttrVOs.get(i).getId() + ".name"); } } List excelNameList = new CopyOnWriteArrayList<>(); String tempFolder = LocalFileUtil.getDefaultTempFolder(); if (total > EXPORT_LIMIT) { //分组来执行 int queryCount = (total - total % EXPORT_LIMIT) / EXPORT_LIMIT; if (total % EXPORT_LIMIT > 0) { queryCount = queryCount + 1; } List indexList = new ArrayList<>(); for (int i = 0; i < queryCount; i++) { indexList.add(i); } Map finalConditionMap = conditionMap; //并行查询看看 //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo(); indexList.stream().forEach(index -> { //线程的方式,所以需要设置当前用户 //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo); PageHelper thisPage = new PageHelper(EXPORT_LIMIT); thisPage.setPage(index + 1); thisPage.setSort(exportAttrDTO.getSort()); thisPage.setOrder(exportAttrDTO.getOrder()); thisPage.addDefaultDesc("createTime"); selectDataAndExportExcelName(btmTypeId, finalConditionMap, thisPage, finalSelectFieldList, classifyFullInfo, templateVO, exportAttrDTO, excelNameList, tempFolder, index); }); } else { pageHelper.setLimit(total); pageHelper.setPage(1); selectDataAndExportExcelName(btmTypeId, conditionMap, pageHelper, finalSelectFieldList, classifyFullInfo, templateVO, exportAttrDTO, excelNameList, tempFolder, 1); } if (excelNameList.size() == 0) { throw new VciBaseException("没有数据可以被导出"); } if (excelNameList.size() == 1) { return excelNameList.get(0); } //是多个,我们需要打成压缩包 String zipFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_导出_" + excelNameList.size() + ".zip"; VciZipUtil zipUtil = new VciZipUtil(); File file = new File(tempFolder); zipUtil.addFileToZip(file, zipFileName); File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { LocalFileUtil.deleteTempFile(files[i], false); } LocalFileUtil.deleteTempFile(file, true); return zipFileName; } /** * 查询数据并导出到excel * * @param btmTypeId 业务类型 * @param conditionMap 查询条件 * @param pageHelper 分页 * @param selectFieldList 查询的字段 * @param classifyFullInfo 分类的全部信息 * @param templateVO 模板的信息 * @param exportAttrDTO 导出的属性 * @param excelNameList excel的文件名称 * @param tempFolder 临时文件夹 * @param excelIndex excel的顺序 */ private void selectDataAndExportExcelName(String btmTypeId, Map conditionMap, PageHelper pageHelper, List selectFieldList, CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, CodeExportAttrDTO exportAttrDTO, List excelNameList, String tempFolder, Integer excelIndex) { DataGrid> dataGrid = engineService.queryGrid(btmTypeId, templateVO, conditionMap, pageHelper); if (dataGrid == null || CollectionUtils.isEmpty(dataGrid.getData())) { return; } //转换数据 List> dataMap = dataGrid.getData(); //封装查询出来的数据 engineService.wrapperData(dataMap, templateVO, selectFieldList, false); //modify by weidy@2022-09-27 //因为在列表和表单的显示的时候,我们的开关类型页面会处理,但是在导出的时候,我们需要将true和false都替换成中文 engineService.wrapperBoolean(dataMap, templateVO); Map attrVOMap = templateVO.getAttributes().stream().filter(s -> selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); Map attrIdIndexMap = exportAttrDTO.getAttrIdIndexMap(); if (CollectionUtils.isEmpty(attrIdIndexMap)) { attrIdIndexMap = templateVO.getAttributes().stream().filter(s -> selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getOrderNum(), t -> t.getId())); } List indexList = attrIdIndexMap.keySet().stream().sorted().collect(Collectors.toList()); String excelName = tempFolder + File.separator + classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_导出_" + excelIndex + ".xls"; try { new File(excelName).createNewFile(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e); } excelNameList.add(excelName); List excelDataList = new ArrayList<>(); Workbook workbook = new HSSFWorkbook(); for (int i = 0; i < indexList.size(); i++) { String attrId = attrIdIndexMap.get(indexList.get(i)).toLowerCase(Locale.ROOT); if (attrVOMap.containsKey(attrId)) { CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId); Object text = attrVO.getName(); text = exportKeyAndRequired(workbook, attrVO, text); WriteExcelData excelData = new WriteExcelData(0, i, text); if (text instanceof RichTextString) { excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); } excelDataList.add(excelData); } } final Integer[] rowIndex = {0}; Map finalAttrIdIndexMap = attrIdIndexMap; dataMap.stream().forEach(data -> { rowIndex[0]++; for (int i = 0; i < indexList.size(); i++) { Integer index = indexList.get(i); String attrId = finalAttrIdIndexMap.get(index).toLowerCase(Locale.ROOT); if (attrVOMap.containsKey(attrId)) { CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId); if (StringUtils.isNotBlank(attrVO.getEnumId()) || StringUtils.isNotBlank(attrVO.getEnumString())) { attrId = attrId + "Text"; } if (StringUtils.isNotBlank(attrVO.getReferBtmId()) || StringUtils.isNotBlank(attrVO.getReferConfig())) { attrId = attrId + "name"; } if (VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attrId)) { attrId = VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT); } excelDataList.add(new WriteExcelData(rowIndex[0], i, data.getOrDefault(attrId, ""))); } } }); WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelName, excelOption); } /** * 相似项查询出来之后再点击确认时调用的 * * @param codeImprotSaveDatVOList * @param classifyAttr * @param isImprot * @return */ @Override public R batchImportData(List codeImprotSaveDatVOList, String classifyAttr, boolean isImprot) { WriteExcelOption eo = new WriteExcelOption(); AtomicBoolean success = new AtomicBoolean(true); AtomicReference codeClassifyTemplateVO = new AtomicReference<>(); codeImprotSaveDatVOList.stream().forEach(codeImprotSaveDatVO -> { List rowDataList = new ArrayList<>(); List cboList = new ArrayList<>(); List colList = codeImprotSaveDatVO.getClos(); CodeOrderDTO orderDTO = codeImprotSaveDatVO.getOrderDTO(); List> dataList = codeImprotSaveDatVO.getDataList(); Map fieldIndexMap = new HashMap(); for (int i = 0; i < dataList.size(); i++) { SheetRowData sheetRowData = new SheetRowData(); Map dataMap = dataList.get(i); Map data = new HashMap(); final int[] colIndex = {0}; Map finalFieldIndexMap = new HashMap<>(); dataMap.forEach((field, value) -> { if (!ROW_INDEX.equalsIgnoreCase(field) && !ERROR_MSG.equalsIgnoreCase(field)) { data.put(colIndex[0], value); finalFieldIndexMap.put(colIndex[0]++, field); } }); fieldIndexMap = finalFieldIndexMap; sheetRowData.setData(data); sheetRowData.setRowIndex(i + ""); rowDataList.add(sheetRowData); } CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid()); log.info("分类:" + classifyFullInfo.getCurrentClassifyVO().getName() + "数据:" + codeImprotSaveDatVO.getDataList().size()); // CodeClassifyTemplateVO codeClassifyTemplateVO= engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid()); codeClassifyTemplateVO.set(templateService.getObjectHasAttrByOid(orderDTO.getTemplateOid())); //规则的主键需要去获取 CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo); //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = codeClassifyTemplateVO.get().getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); String fullPath = getFullPath(classifyFullInfo); excelToCbo(classifyFullInfo, fieldIndexMap, rowDataList, codeClassifyTemplateVO.get(), cboList, fullPath, !isImprot); Map errorMap = new ConcurrentHashMap<>(); Map pathMap = new HashMap<>(); //校验编码规则和码段是否正确 Map> ruleRowIndexMap = new ConcurrentHashMap<>(); Map ruleVOMap = new ConcurrentHashMap<>(); if (isImprot) { Map childOidPathMap = getChildClassifyPathMap(classifyFullInfo, fullPath); //都转换完了。需要批量检查 //找所有的分类路径,需要校验路径是否正确,是否都在当前的分类的下级 List childClassifyVOs = classifyService.listChildrenClassify(orderDTO.getCodeClassifyOid(), true, classifyAttr, true); pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t)); Map classifyVOMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getOid(), t -> t)); classifyVOMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO()); pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO()); //我们需要判断这些分类的模板是不是一样的,只需要校验,不用获取 //检查分类的路径 checkClassifyPathInHistory(cboList, errorMap, pathMap, childOidPathMap); //检查规则 Map ruleOidMap = new ConcurrentHashMap(); List unExistRuleClassifyOidList = new CopyOnWriteArrayList<>(); checkRuleOidInHistory(classifyVOMap, ruleOidMap, unExistRuleClassifyOidList); // TODO 改用oid查询的,这儿不该用id ruleVOMap = ruleService.listCodeRuleByOids(ruleOidMap.values()).stream().collect(Collectors.toMap(s -> s.getOid(), t -> t)); checkSecLengthInHistory(cboList, classifyVOMap, ruleVOMap, ruleOidMap, errorMap, ruleRowIndexMap); } //分类注入 batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, isImprot); //boolean reSwitchBooleanAttrOnOrder(attrVOS, cboList); //4.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); //5.校验枚举是否正确 batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap); //7.处理参照的情况 batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap); //6.时间格式的验证 //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap); //设置默认值 batchSwitchAttrDefault(attrVOS, cboList); //最后弄组合规则 batchSwitchComponentAttrOnOrder(attrVOS, cboList); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, codeClassifyTemplateVO.get(), cboList, false, errorMap); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } //4.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); if (isImprot) { List needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); List finalNeedSaveCboList = needSaveCboList; Map finalRuleVOMap = ruleVOMap; // TODO: 多线程流套多线程流,有坑,我把这儿改成单线程了 final BladeUser user = AuthUtil.getUser(); ruleRowIndexMap.keySet().stream().forEach(ruleOid -> { List dataCBOList = new CopyOnWriteArrayList<>(); List rowIndexList = ruleRowIndexMap.get(ruleOid); List thisCbos = needSaveCboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(thisCbos)) { thisCbos.stream().forEach(clientBusinessObject -> { BaseModel baseModel = new BaseModel(); BeanUtil.convert(clientBusinessObject, baseModel); dataCBOList.add(baseModel); }); try { productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), finalRuleVOMap.get(ruleOid), null, dataCBOList, user); } catch (Throwable e) { //success=false; log.error("批量产生编码的时候出错了", e); thisCbos.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage()); }); } } engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList); }); } else { final BladeUser user = AuthUtil.getUser(); List dataCBOList = new ArrayList<>(); List needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); log.info("分类:" + classifyFullInfo.getCurrentClassifyVO().getName() + "数据:" + needSaveCboList.size()); if (!CollectionUtils.isEmpty(needSaveCboList)) { needSaveCboList.stream().forEach(clientBusinessObject -> { BaseModel baseModel = new BaseModel(); BeanUtil.convert(clientBusinessObject, baseModel); dataCBOList.add(baseModel); }); try { productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), ruleVO, orderDTO.getSecDTOList(), dataCBOList, user); } catch (Exception e) { log.error("批量产生编码的时候出错了", e); needSaveCboList.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage()); }); } //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面 engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList); } } if (errorMap.size() > 0) { success.set(false); LinkedList excelDataList = new LinkedList<>(); excelDataList.add(new WriteExcelData(0, 0, "错误信息")); final int[] index = {1}; errorMap.forEach((key, v) -> { excelDataList.add(new WriteExcelData(index[0]++, 0, "第" + (Integer.parseInt(key) + 1) + "行数据:" + v)); }); eo.addSheetDataList(codeClassifyTemplateVO.get().getName() + "导入模板", excelDataList); } }); if (!success.get()) { String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + (isImprot ? "批量历史错误信息.xls" : "批量申请错误信息.xls"); ExcelUtil.writeDataToFile(excelName, eo); saveLogUtil.operateLog("历史数据导入", true, StringUtil.format("错误信息:{}", JSON.toJSONString(eo.getWriteDataMap()))); return R.fail(excelName); } else { saveLogUtil.operateLog("历史数据导入", false, StringUtil.format("导入到分类{}中,导入成功总数为:{}", JSON.toJSONString(codeClassifyTemplateVO), Func.isEmpty(codeImprotSaveDatVOList.get(0).getDataList().size()))); return R.success(isImprot ? "批量历史导入成功" : "批量申请成功"); } } /*** *根据数据oid从缓存中移除数据 * @param redisOid redisid * @param codeClssifyOid 存储规则的oid * @param dataOids 所需删除的数据 * @return */ @Override public R deleteDatas(String redisOid, String codeClssifyOid, String dataOids) { VciBaseUtil.alertNotNull(redisOid, "数据删除", redisOid, "数据缓存主键"); VciBaseUtil.alertNotNull(codeClssifyOid, "数据删除", codeClssifyOid, "编码规则缓存主键"); VciBaseUtil.alertNotNull(dataOids, "数据删除", dataOids, "所需删除的数据主键"); try { List codeImprotDataVOs = bladeRedis.lRange(redisOid + "-" + codeClssifyOid, 0, -1); List dataOidList = new ArrayList<>(); codeImprotDataVOs.stream().forEach(codeImprotDataVO -> { List> newDataList = new ArrayList<>(); List> dataList = codeImprotDataVO.getDatas(); dataList.stream().forEach(dataMap -> { String oid = dataMap.get("oid"); if (!dataOidList.contains(oid)) { newDataList.add(dataMap); } }); codeImprotDataVO.setDatas(newDataList); }); //重新缓存 bladeRedis.del(redisOid + "-" + codeClssifyOid); bladeRedis.set(redisOid + "-" + codeClssifyOid, codeImprotDataVOs); bladeRedis.expire(redisOid + "-" + codeClssifyOid, BATCHADD_REDIS_TIME); return R.success("删除缓存数据成功"); } catch (Throwable e) { return R.fail("删除缓存数据失败!"); } } /** * 集成批量申请数据 * * @param orderDTO 分类的主键 * @param dataObjectVO 数据信息 * @param resultDataObjectDetailDOs 错误信息 * @return 有错误信息的excel */ @Override public void batchSyncApplyCode(CodeOrderDTO orderDTO, DataObjectVO dataObjectVO, LinkedList resultDataObjectDetailDOs, boolean isCodeOrGroupCode) { Map errorMap = new ConcurrentHashMap<>(); VciBaseUtil.alertNotNull(orderDTO, "编码申请相关的数据", orderDTO.getCodeClassifyOid(), "主题库分类主键"); CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid()); //规则的主键需要去获取 CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo); //1.判断规则中除了流水码段,是否有其他码段 //engineService.checkSecValueOnOrder(ruleVO,orderDTO); //查询分类和模板 //先找到每一行的标题,然后根据标题来获取对应的属性 List rowDataList = dataObjectVO.getRowData(); Map rowDataMap = new LinkedHashMap<>(); rowDataList.stream().forEach(rowData -> { rowDataMap.put(rowData.getRowIndex(), rowData); }); //找第一行,为了找标题 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid()); //校验模板是不是最新的 //checkTemplateSync(sheetDataSetList,templateVO); //除去默认的属性.还有只有具有分类注入的才过滤出来 List attrVOS = templateVO.getAttributes().stream().filter( s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); Map fieldIndexMap = new HashMap<>(); List titleRowData = dataObjectVO.getColName(); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT), (o1, o2) -> o2)); getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap); //需要判断是否所有的属性都在模板上了 List unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT)) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getComponentRule()) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去 ).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(unExistAttrVOs)) { String message = unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE)); throw new VciBaseException("【" + message + "】这些属性在excel中没有找到"); } List cboList = new ArrayList<>(); String fullPath = getFullPath(classifyFullInfo); // List codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order"); boolean isProcess = false; //注释掉此处下面所有都按照不判断流程存储状态了 /** if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){ isProcess=true; }***/ Map codeOidToSystemOidMap = new HashMap<>();//存储编码数据和集成系统数据oid对照映射 excelToCbo(classifyFullInfo, titleRowData, fieldIndexMap, rowDataList, templateVO, cboList, fullPath, isProcess, "create", errorMap, codeOidToSystemOidMap); //都转换完了。需要批量检查 //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中 Map errorKeyMap = new ConcurrentHashMap<>(); //1.分类注入 batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false); //boolean reSwitchBooleanAttrOnOrder(attrVOS, cboList); // cboList.stream().forEach(cbo->{ //2.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); //3.校验枚举是否正确 batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap); //4.时间格式的验证 //4.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap); //5.处理参照的情况 batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap); //6设置默认值 batchSwitchAttrDefault(attrVOS, cboList); //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则 batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap); //最后弄组合规则 batchSwitchComponentAttrOnOrder(attrVOS, cboList); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorKeyMap); log.info("================查重后的errorKeyMap错误信息================="+JSON.toJSONString(errorKeyMap)); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); Map> keyAttrOkOidTORepeatOidMap = keyResultVO.getKeyAttrOkOidTORepeatOidMap(); if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) { selfRepeatRowIndexList.stream().forEach(rowIndex -> { /* //传入数据之间关键属性的校验 RowDatas rowData= rowDataMap.get(rowIndex); XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO(); resultDataObjectDetailDO.setCode(""); resultDataObjectDetailDO.setId(rowData.getOid()); resultDataObjectDetailDO.setErrorid("1"); resultDataObjectDetailDO.setMsg(errorMap.getOrDefault(rowIndex,"") + ";关键属性重复"); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); */ errorKeyMap.put(rowIndex, errorKeyMap.getOrDefault(rowIndex, "") + String.format(";传入的数据中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } /**** * 关键属性与系统中重复的判断 */ if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { //传入数据之间关键属性的校验 /* RowDatas rowData= rowDataMap.get(rowIndex); XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO(); resultDataObjectDetailDO.setCode(""); resultDataObjectDetailDO.setId(rowData.getOid()); resultDataObjectDetailDO.setErrorid("1"); resultDataObjectDetailDO.setMsg(errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" ); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); */ Map> indexTODataMap = keyResultVO.getIndexTODataMap(); if (indexTODataMap.containsKey(rowIndex)) { List baseModelList = indexTODataMap.get(rowIndex); } errorKeyMap.put(rowIndex, errorKeyMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); }); } //校验属性是否正确错误信息 if (errorMap.size() > 0) { String[] newMsg = {""}; cboList.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); if (errorMap.containsKey(rowIndex)) { String oid = cbo.getOid(); String sourceOid = oid; if (codeOidToSystemOidMap.containsKey(oid)) { sourceOid = codeOidToSystemOidMap.get(oid); } String code = ""; String groupCode = ""; String errorid = "103"; String mes = errorMap.get(rowIndex); XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); if (isCodeOrGroupCode) { resultDataObjectDetailDO.setCode(groupCode); } else { resultDataObjectDetailDO.setCode(code); } resultDataObjectDetailDO.setId(sourceOid); resultDataObjectDetailDO.setErrorid(errorid); resultDataObjectDetailDO.setMsg(mes); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); } }); } Map newKeyMap = new HashedMap(); if (errorKeyMap.size() > 0) { errorKeyMap.keySet().forEach(key -> { if (!errorMap.containsKey(key)) { newKeyMap.put(key, errorKeyMap.get(key)); } }); if (newKeyMap.size() > 0) { List editBoList = new ArrayList<>(); Map> indexTodataMap = keyResultVO.getIndexTODataMap(); cboList.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); String msg = errorKeyMap.get(rowIndex); if (indexTodataMap.containsKey(rowIndex)) { String oid = cbo.getOid(); String sourceOid = oid; String code = ""; String errorid = "201"; if (codeOidToSystemOidMap.containsKey(oid)) { sourceOid = codeOidToSystemOidMap.get(oid); } List newCboList = indexTodataMap.get(rowIndex); if (!CollectionUtils.isEmpty(newCboList)) { //处理关键属性查出多条的话,根据集成调用的当前分类代号取当前分类的码值。 Map classOidTOBaseModelMap = new HashMap<>(); newCboList.stream().forEach(baseModel -> { String codeclsfid = baseModel.getData().get(CODE_CLASSIFY_OID_FIELD.toLowerCase(Locale.ROOT)); classOidTOBaseModelMap.put(codeclsfid, baseModel); }); String codeclsfid = classifyFullInfo.getCurrentClassifyVO().getOid(); if (classOidTOBaseModelMap.containsKey(codeclsfid)) { BaseModel newCbo = classOidTOBaseModelMap.get(codeclsfid); String lcstatus = newCbo.getLcStatus(); String newOid = newCbo.getOid(); Date ts = newCbo.getTs(); code = StringUtils.isBlank(newCbo.getId()) ? "" : newCbo.getId(); if (isCodeOrGroupCode) { code = newCbo.getData().getOrDefault("GROUPCODE", ""); if (StringUtils.isBlank(code)) { errorid = "1"; msg = ";申请的编码类型为集团码,等待集团编码赋值"; } } String lastmodifier = newCbo.getLastModifier(); if (lcstatus != null && !lcstatus.equals(CodeDefaultLC.RELEASED.getValue())) { newCbo.setOid(newOid); newCbo.setLastModifier(lastmodifier); newCbo.setTs(ts); cbo.setLastModifier(cbo.getLastModifier()); editBoList.add(newCbo); } } else { errorid = "205"; msg += ";编码则属于其他分类。"; } XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); resultDataObjectDetailDO.setCode(code); resultDataObjectDetailDO.setId(sourceOid); resultDataObjectDetailDO.setErrorid(errorid); resultDataObjectDetailDO.setMsg(msg); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); } } }); //关键属性更改 if (!CollectionUtils.isEmpty(editBoList)) { engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), editBoList);//保存数据 } errorMap.putAll(errorKeyMap); } } // }); //要把以上的错误的都抛出后,再继续处理时间和组合规则 List needSaveCboList = cboList.stream().filter(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return !errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); List needRowIndexList = new ArrayList<>(); if (!CollectionUtils.isEmpty(needSaveCboList)) { //9.我们处理业务数据 //生成编码的内容 List allNeedSaveCboList = new ArrayList<>(); List dataCBOList = new ArrayList<>(); final BladeUser user = AuthUtil.getUser(); needSaveCboList.stream().forEach(clientBusinessObject -> { BaseModel baseModel = new BaseModel(); BeanUtil.convert(clientBusinessObject, baseModel); //(VciBaseUtil.objectToMapString(clientBusinessObject)); dataCBOList.add(baseModel); allNeedSaveCboList.add(baseModel.getOid()); }); try { List applyGroupCodeIdList = new ArrayList<>(); productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList, user); //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面 engineService.batchSaveSelectChar(templateVO, dataCBOList); // if(!isProcess){ dataCBOList.stream().forEach(needSaveCbo -> { XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); String code = StringUtils.isBlank(needSaveCbo.getId()) ? " " : needSaveCbo.getId(); String groupCode = needSaveCbo.getData().getOrDefault("GROUPCODE", " "); //resultDataObjectDetailDO.setCode(needSaveCbo.getId()); String msg = "申请编码成功"; String oid = needSaveCbo.getOid(); String sourceOid = oid; applyGroupCodeIdList.add(oid); if (codeOidToSystemOidMap.containsKey(oid)) { sourceOid = codeOidToSystemOidMap.get(oid); } if (isCodeOrGroupCode) { if (StringUtils.isBlank(groupCode)) { resultDataObjectDetailDO.setErrorid("1"); msg = "申请的编码类型为集团码,等待集团编码赋值"; } resultDataObjectDetailDO.setCode(groupCode); } else { resultDataObjectDetailDO.setCode(code); resultDataObjectDetailDO.setErrorid("0"); } resultDataObjectDetailDO.setId(sourceOid); resultDataObjectDetailDO.setMsg(msg); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); //处理传送的数据中关键属性重复的,直接拿到已经申请到编码的数据编码直接将赋给关键属性重复的数据 LinkedList repeatDataObjectDetailDOS = handleApplyDataKeyAttrRepeat(keyAttrOkOidTORepeatOidMap, codeOidToSystemOidMap, needSaveCbo, isCodeOrGroupCode); resultDataObjectDetailDOs.addAll(repeatDataObjectDetailDOS); }); /* }else{ needSaveCboList.stream().forEach(needSaveCbo->{ XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO(); // resultDataObjectDetailDO.setCode(needSaveCbo.getId());//不用返回编码 String oid=needSaveCbo.getOid(); String sourceOid=oid; if(codeOidToSystemOidMap.containsKey(oid)){ sourceOid=codeOidToSystemOidMap.get(oid); } resultDataObjectDetailDO.setId(sourceOid); resultDataObjectDetailDO.setErrorid("204"); resultDataObjectDetailDO.setMsg("申请编码成功,等待编码系统发布!"); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); }); }*/ //是否调用集团接口申请接口 if (isCodeOrGroupCode) { if (!CollectionUtils.isEmpty(applyGroupCodeIdList)) { this.sendApplyGroupcode(applyGroupCodeIdList, classifyFullInfo.getTopClassifyVO().getId(), sysIntegrationPushTypeEnum.ACCPET_APPCODE.getValue()); } } } catch (Throwable e) { e.printStackTrace(); needSaveCboList.stream().forEach(needSaveCbo -> { XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); resultDataObjectDetailDO.setCode(""); String oid = needSaveCbo.getOid(); String sourceOid = oid; if (codeOidToSystemOidMap.containsKey(oid)) { sourceOid = codeOidToSystemOidMap.get(oid); } resultDataObjectDetailDO.setId(sourceOid); resultDataObjectDetailDO.setErrorid("1"); resultDataObjectDetailDO.setMsg("保存出现问题:" + e.getMessage()); resultDataObjectDetailDOs.add(resultDataObjectDetailDO); }); } } } /*** *给同一批申请编码存在关键属性的数据赋上一致编码 * @param keyAttrOkOidTORepeatOidMap 一批申请数据关键属性一致的重复数据映射关系 * @param codeOidToSystemOidMap * @param needSaveCbo * @param isCodeOrGroupCode */ private LinkedList handleApplyDataKeyAttrRepeat(Map> keyAttrOkOidTORepeatOidMap, Map codeOidToSystemOidMap, BaseModel needSaveCbo, boolean isCodeOrGroupCode) { LinkedList resultDataObjectDetailDOs = new LinkedList<>(); String oid = needSaveCbo.getOid(); if (keyAttrOkOidTORepeatOidMap.containsKey(oid)) { List repeatOidList = keyAttrOkOidTORepeatOidMap.get(oid); if (!CollectionUtils.isEmpty(repeatOidList)) { String sourceNewOid = needSaveCbo.getOid(); String sourceOid = sourceNewOid; if (codeOidToSystemOidMap.containsKey(oid)) { sourceOid = codeOidToSystemOidMap.get(oid); } String code = StringUtils.isBlank(needSaveCbo.getId()) ? " " : needSaveCbo.getId(); String groupCode = needSaveCbo.getData().getOrDefault("GROUPCODE", " "); String finalSourceOid = sourceOid; repeatOidList.stream().forEach(repeatOid -> { if (codeOidToSystemOidMap.containsKey(repeatOid)) { XMLResultDataObjectDetailDO repeatresultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); String repeatSourceOid = codeOidToSystemOidMap.get(repeatOid); //String repeatMsg = "此数据与申请的编码数据id为【" + finalSourceOid + "】的关键属性一致,则取相同编码"; String repeatMsg = "此数据与申请的编码数据id为【" + code + "】的关键属性一致,则取相同编码"; if (isCodeOrGroupCode) { if (StringUtils.isBlank(groupCode)) { repeatMsg = "申请的编码类型为集团码,等待集团编码赋值"; } repeatresultDataObjectDetailDO.setCode(groupCode); } else { repeatresultDataObjectDetailDO.setCode(code); } repeatresultDataObjectDetailDO.setId(repeatSourceOid); repeatresultDataObjectDetailDO.setErrorid("0"); repeatresultDataObjectDetailDO.setMsg(repeatMsg); resultDataObjectDetailDOs.add(repeatresultDataObjectDetailDO); } }); } } return resultDataObjectDetailDOs; } /*** * 集成批量同步更新接口 * @param codeClassifyVO; * @param dataObjectVO 数据信息 * @param resultDataObjectDetailDOs 错误信息 * @param isCodeOrGroupCode 是否更集团系统数据 */ @Transactional(rollbackFor = VciBaseException.class) @Override public void batchSyncEditDatas(CodeClassifyVO codeClassifyVO, DataObjectVO dataObjectVO, LinkedList resultDataObjectDetailDOs, boolean isCodeOrGroupCode) { String errorid = ""; String msg = ""; //查询分类和模板 //先找到每一行的标题,然后根据标题来获取对应的属性 List rowDataList = dataObjectVO.getRowData(); Map rowDataMap = new LinkedHashMap<>(); Map codeDataMap = new LinkedHashMap<>(); rowDataList.stream().forEach(rowData -> { rowDataMap.put(rowData.getRowIndex(), rowData); codeDataMap.put(rowData.getCode(), rowData); }); //找第一行,为了找标题 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid()); // 应该都是一个分类下的业务数据,找第一条的就行 CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyVO.getOid()); //校验模板是不是最新的 //checkTemplateSync(sheetDataSetList,templateVO); //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); Map fieldIndexMap = new HashMap<>(); List titleRowData = dataObjectVO.getColName(); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT), (o1, o2) -> o2)); getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap); //Map cboOidMap = new HashMap<>(); //cboOidMap.put("id", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])) + ")"); String tableName = ""; try { R r = btmTypeClient.getAllAttributeByBtmId(classifyFullInfo.getTopClassifyVO().getBtmTypeId()); if (!r.isSuccess()) { throw new Throwable(r.getMsg()); } BtmTypeVO btmTypeVO = r.getData(); if (btmTypeVO == null) { throw new Throwable("根据业务类型未查询到业务类型对象!"); } tableName = btmTypeVO.getTableName(); if (StringUtils.isBlank(tableName)) { throw new Throwable("根据业务类型未查询到业务类型相关联的表"); } } catch (Throwable e) { log.error("查询业务对象表" + e); XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); xmlResultDataObjectDetailDO.setErrorid("103"); xmlResultDataObjectDetailDO.setMsg("查询业务对象表" + e); xmlResultDataObjectDetailDO.setId(""); xmlResultDataObjectDetailDO.setCode(""); resultDataObjectDetailDOs.add(xmlResultDataObjectDetailDO); return; } StringBuffer sb = new StringBuffer(); sb.append(" select * from "); sb.append(tableName); sb.append(" where 1=1 "); sb.append(" and lastr=1 and lastv=1"); if (isCodeOrGroupCode) { sb.append(" and ( groupcode in ("); sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0]))); sb.append(")"); sb.append(" or id in ("); sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0]))); sb.append("))"); } else { sb.append(" and id in ("); sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0]))); sb.append(")"); } List> dataMapList = commonsMapper.queryByOnlySqlForMap(sb.toString()); DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true); List cboList = ChangeMapTOClientBusinessObjects(dataMapList); Map codeSystemObjectMap = cboList.stream().filter(systeDataObject -> systeDataObject != null && StringUtils.isNotBlank(systeDataObject.getId())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getId(), t -> t)); Map errorMap = new HashMap<>(); List codeOrderDTOList = new ArrayList<>(); this.getCodeOrderDTOs(codeClassifyVO, templateVO, codeDataMap, codeSystemObjectMap, codeOrderDTOList, errorMap, isCodeOrGroupCode); // List codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order"); boolean isProcess = false; /** if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){ isProcess=true; }**/ Map orderDTOMap = codeOrderDTOList.stream().filter(orderDTO -> orderDTO != null && StringUtils.isNotBlank(orderDTO.getId())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getId(), t -> t)); List updateList = new ArrayList<>(); List codeAllCodeList = new ArrayList<>(); List deleteList = new ArrayList<>(); // CodeClassifyTemplateVO firstTemplateVO = templateService.getObjectHasAttrByOid(orderDTOMap.values().stream().findFirst().get().getTemplateOid()); Map cboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getId(), t -> t)); // boolean finalIsProcess = isProcess; orderDTOMap.keySet().stream().forEach(code -> { CodeOrderDTO orderDTO = orderDTOMap.get(code); ClientBusinessObject cbo = cboMap.get(code); String dataStatus = cbo.getLcStatus(); RowDatas rowData = codeDataMap.get(code); String status = rowData.getStatus(); String lastModifier = rowData.getEditor(); String operation = rowData.getOperation(); if (cbo.getTs().compareTo(orderDTO.getTs()) == 0 ? false : true) { // throw new VciBaseException("数据不是最新的,可能他人已经修改,请刷新后再试"); errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";数据不是最新的,可能他人已经修改,请刷新后再试"); } /* if (!CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(cbo.getLcStatus()) && !orderDTO.isEditInProcess()) { throw new VciBaseException("数据不是{0}的状态,不允许修改", new String[]{CodeDefaultLC.EDITING.getText()}); }*/ if (operation.equals("update")) { //1.先注入,再组合,最后校验 switchClassifyLevelOnOrder(templateVO, classifyFullInfo, orderDTO, errorMap); //2.处理组合规则。组合规则不能使用编码的属性,因为编码的生成可能是需要属性的 switchComponentAttrOnOrder(templateVO, orderDTO); //3.校验规则 checkVerifyOnOrder(templateVO, orderDTO, errorMap); //4.校验枚举的内容是否正确 checkEnumOnOrder(templateVO, orderDTO, errorMap); //5.处理时间格式,在数据库里面不论是字符串还是日期格式,都使用相同的格式存储 switchDateAttrOnOrder(templateVO, orderDTO); //6. 判断必输项 checkRequiredAttrOnOrder(templateVO, orderDTO, errorMap); //7.判断关键属性 checkKeyAttrOnOrder(classifyFullInfo, templateVO, orderDTO, errorMap); //默认的内容不能变,所以只需要拷贝自定义的相关属性即可 copyValueToCBO(classifyFullInfo, cbo, orderDTO, templateVO, true, errorMap); //企业码和集团码的不修改 cbo.setDescription(StringUtils.isBlank(orderDTO.getDescription()) ? "" : orderDTO.getDescription()); cbo.setName(orderDTO.getName()); try { //主要处理大小写问题,将data里面的数据的key都转为小写 HashMap lowerData = new HashMap<>(); Iterator> iterator = cbo.getData().entrySet().iterator(); while (iterator.hasNext()) { Map.Entry next = iterator.next(); lowerData.put(next.getKey().toLowerCase(Locale.ROOT), next.getValue()); } cbo.getData().clear(); cbo.getData().putAll(lowerData); cbo.setAttributeValueWithNoCheck("description", (StringUtil.isNotBlank(orderDTO.getData() .get("description")) ? orderDTO.getData().get("description") : orderDTO.getDescription())); // cbo.setAttributeValue("name", orderDTO.getName()); // if(finalIsProcess){//在流程中不允许更改 // errorMap.put(code,errorMap.getOrDefault(code, errorMap.getOrDefault(code,"")+";数据"+code+"在流程中,不允许更改!")); // }else{ Date date = new Date(); cbo.setLcStatus(status); cbo.setAttributeValue("lcstatus", status); cbo.setLastModifyTime(date); cbo.setLastModifier(lastModifier); cbo.setLastModifyTime(date); cbo.setAttributeValue("lastmodifier", lastModifier); cbo.setAttributeValue("lastmodifytime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date)); cbo.setTs(date); cbo.setAttributeValue("ts", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date)); // } } catch (VciBaseException e) { e.printStackTrace(); } List newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid())); if (!CollectionUtils.isEmpty(newCodeAllCodeList)) { CodeAllCode codeCbo = newCodeAllCodeList.get(0); log.info("codeCbos code:" + codeCbo.getId()); codeCbo.setLcStatus(status); codeAllCodeList.add(codeCbo); } BaseModel baseModel = new BaseModel(); BeanUtil.convert(cbo, baseModel); //baseModel.setData(VciBaseUtil.objectToMapString(cbo)); updateList.add(baseModel); } else if (operation.equals("delete")) {//如果在流程中不允许删除,不在流程中状态为发布或者停用的数据不允许删除,将其更改为停用,其他的情况直接删除 // if(finalIsProcess){ // errorMap.put(code,errorMap.getOrDefault(code, errorMap.getOrDefault(code,"")+";数据"+code+"在流程中,不允许删除!")); //}else { try { log.info("oid:" + cbo.getOid()); List newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid())); log.info("codeCbos size:" + newCodeAllCodeList.size()); if (!CollectionUtils.isEmpty(newCodeAllCodeList)) { CodeAllCode codeCbo = newCodeAllCodeList.get(0); log.info("codeCbos code:" + codeCbo.getId()); codeCbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue()); codeAllCodeList.add(codeCbo); } deleteList.add(cbo.getOid()); } catch (VciBaseException e) { e.printStackTrace(); } // } } else if (operation.equals("editstatus")) { try { // if (finalIsProcess) { // errorMap.put(code, errorMap.getOrDefault(code, errorMap.getOrDefault(code, "") + ";数据" + code + "在流程中,不允许更改状态!")); // } else { cbo.setLcStatus(status); cbo.setAttributeValue("lcstatus", status); // } List newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid())); if (!CollectionUtils.isEmpty(newCodeAllCodeList)) { CodeAllCode codeCbo = newCodeAllCodeList.get(0); log.info("codeCbos code:" + codeCbo.getId()); codeCbo.setLcStatus(status); codeAllCodeList.add(codeCbo); } BaseModel baseModel = new BaseModel(); BeanUtil.convert(cbo, baseModel); //baseModel.setData(VciBaseUtil.objectToMapString(cbo)); updateList.add(baseModel); } catch (VciBaseException e) { e.printStackTrace(); } } }); /** * 错误信息输出 */ if (errorMap.size() > 0) { errorMap.keySet().forEach(code -> { if (codeDataMap.containsKey(code)) { RowDatas rowDatas = codeDataMap.get(code); String dataMsg = errorMap.get(code); String oid = rowDatas.getOid(); XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); xmlResultDataObjectDetailDO.setErrorid("103"); xmlResultDataObjectDetailDO.setMsg(dataMsg); xmlResultDataObjectDetailDO.setId(oid); xmlResultDataObjectDetailDO.setCode(code); resultDataObjectDetailDOs.add(xmlResultDataObjectDetailDO); } }); } else { //存储数据 try { engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), updateList); codeAllCodeService.saveOrUpdateBatch(codeAllCodeList); if (deleteList.size() > 0) { commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.toInSql(deleteList.toArray(new String[]{}))); } //是否调用集团接口申请接口 if (isCodeOrGroupCode) { List IdList = resultDataObjectDetailDOs.stream().filter(xMLResultDataObjectDetailDO -> com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(xMLResultDataObjectDetailDO.getId())).map(XMLResultDataObjectDetailDO::getId).distinct().collect(Collectors.toList()); if (!CollectionUtils.isEmpty(IdList)) { this.sendApplyGroupcode(IdList, classifyFullInfo.getTopClassifyVO().getBtmTypeId(), sysIntegrationPushTypeEnum.ACCPET_EDITCODE.getValue()); } } errorid = "0"; msg = "更新/状态更改/删除成功!"; } catch (Throwable e) { errorid = "1"; msg = "保存失败:" + e; } finally { String finalMsg = msg; String finalErrorid = errorid; cboList.stream().forEach(cbo -> { String code = cbo.getId(); if (codeDataMap.containsKey(code)) { RowDatas rowDatas = codeDataMap.get(code); String oid = rowDatas.getOid(); XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO(); xmlResultDataObjectDetailDO.setErrorid(finalErrorid); xmlResultDataObjectDetailDO.setMsg(finalMsg); xmlResultDataObjectDetailDO.setId(oid); xmlResultDataObjectDetailDO.setCode(code); resultDataObjectDetailDOs.add(xmlResultDataObjectDetailDO); } }); } } } /** * 校验属性是否为必输 * * @param templateVO 模板的显示对象,需要包含模板属性 * @param orderDTO 编码申请的信息 */ private void checkRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map errorMap) { Map requiredAttrMap = templateVO.getAttributes().stream().filter( s -> VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr())) .collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(requiredAttrMap)) { requiredAttrMap.forEach((attrId, attrVO) -> { //只有企业编码,状态,备注,模板主键,分类主键这几个是固定的,其余都是自行配置的 if (StringUtils.isBlank(getValueFromOrderDTO(orderDTO, attrId))) { errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性【{" + attrVO.getName() + "}】必须要输入(选择)内容"); // throw new VciBaseException("属性【{0}】必须要输入(选择)内容", new String[]{attrVO.getName()}); } }); } } /** * 转换组合规则的值 * * @param templateVO 模板的显示对象,需要包含模板属性 * @param orderDTO 编码申请的信息 */ private void switchComponentAttrOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO) { Map compAttrVOMap = templateVO.getAttributes().stream().filter(s -> StringUtils.isNotBlank(s.getComponentRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(compAttrVOMap)) { Map dataMap = WebUtil.objectToMapString(orderDTO); Map dataLowMap = new HashMap<>(); if (!CollectionUtils.isEmpty(dataMap)) { dataMap.forEach((key, value) -> { dataLowMap.put(key.toLowerCase(Locale.ROOT), value); }); } dataLowMap.putAll(orderDTO.getData()); compAttrVOMap.forEach((attrId, attrVO) -> { dataLowMap.put(attrId, formulaService.getValueByFormula(dataLowMap, attrVO.getComponentRule())); }); dataLowMap.forEach((key, value) -> { setValueToOrderDTO(orderDTO, key, value); }); } } /** * 校验正则表达式是否正确 * * @param templateVO 模板的信息,必须包含属性的内容 * @param orderDTO 编码申请的相关的信息 */ private void checkVerifyOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map errorMap) { Map verifyAttrVOMap = templateVO.getAttributes().stream().filter(s -> StringUtils.isNotBlank(s.getVerifyRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(verifyAttrVOMap)) { verifyAttrVOMap.forEach((attrId, attrVO) -> { String value = getValueFromOrderDTO(orderDTO, attrId); if (StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())) { errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性[" + attrVO.getName() + "]的值不符合校验规则的要求"); //校验正则表达式 // throw new VciBaseException("属性[{0}]的值不符合校验规则的要求", new String[]{attrVO.getName()}); } }); } } /** * 校验关键属性 * * @param classifyFullInfo 分类的全部信息 * @param templateVO 模板的内容,必须包含模板属性 * @param orderDTO 编码申请的相关的信息 */ private void checkKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map errorMap) { //先获取关键属性的规则,也利用继承的方式 CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo); //注意的是keyRuleVO可能为空,表示不使用规则控制 //获取所有的关键属性 Map ketAttrMap = 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 sysonymAttrMaps = templateVO.getAttributes().stream().filter(item -> Func.isNotBlank(item.getSysonymRuleOids())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); // 获取是否有配置近义词查询规则属性 Map> codeSynonymMaps = new HashMap<>(); if (!sysonymAttrMaps.isEmpty()) { // 查询近义词规则,存储方式key:属性id,value近义词查询规则列表 codeSynonymMaps = codeSynonymService.getCodeSynonymByOids(sysonymAttrMaps); } Map conditionMap = new HashMap<>(); boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag()); //全部去空的优先级大于去空 boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag()); boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag()); boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag()); Map> finalCodeSynonymMaps = codeSynonymMaps; ketAttrMap.forEach((attrId, attrVO) -> { String value = getValueFromOrderDTO(orderDTO, attrId); if (value == null) { value = ""; } engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, finalCodeSynonymMaps.get(attrId), attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap); }); //没有限制分类,但是一个模板只可能在一个业务类型里面,所以直接查询这个业务类型即可 if (!CollectionUtils.isEmpty(conditionMap)) { String tableName = ""; R r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId()); if (r.isSuccess()) { BtmTypeVO btmTypeVO = r.getData(); if (btmTypeVO != null) { tableName = btmTypeVO.getTableName(); } } if (StringUtils.isBlank(tableName)) { String errormsg = "根据业务类型未查询到相关业务表"; errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + errormsg); return; } //final String[] sql = {"select count(*) from " + tableName + " t where 1 = 1 "}; final String[] sql = {"select t.id from " + tableName + " t where 1 = 1 "}; conditionMap.forEach((key, value) -> { if (StringUtils.isBlank(value) || value.equals(QueryOptionConstant.ISNULL)) { sql[0] += " and " + key + " is null "; } else { sql[0] += " and " + key + " = " + value; } }); if (StringUtils.isNotBlank(orderDTO.getOid())) { //修改的时候,需要排除自己 sql[0] += " and t.oid != '" + orderDTO.getOid() + "'"; } else if (StringUtils.isNotBlank(orderDTO.getCopyFromVersion())) { sql[0] += " and t.oid != '" + orderDTO.getCopyFromVersion() + "'"; } // 不需要参与校验的规则oid String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid()); if (Func.isNotBlank(isParticipateCheckOids)) { sql[0] += " and codeclsfid not in(" + isParticipateCheckOids + ")"; } sql[0] += " and t.lastR = '1' and t.lastV = '1' "; List repeatData = commonsMapper.selectList(sql[0]); if (!repeatData.isEmpty()) { String ruleInfoMsg = keyRuleVO == null ? "" : "查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}"; String[] objs = new String[]{trim ? "是" : "否", ignoreCase ? "是" : "否", ignoreWidth ? "是" : "否", trimAll ? "是" : "否"}; String defaultValue = ";根据您填写的关键属性的内容,结合关键属性查询规则,发现这个数据已经在系统中存在了,数据的编号如下:" + repeatData.stream().collect(Collectors.joining(",")) + "。请修正!。"; String errormsg = defaultValue + MessageFormat.format(ruleInfoMsg, objs); errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + errormsg); // throw new VciBaseException("根据您填写的关键属性的内容,结合关键属性查询规则,发现这个数据已经在系统中存在了。请修正!。" + ruleInfoMsg, objs); } } } /** * 校验枚举的内容 * * @param templateVO 模板的显示对象,需要包含属性 * @param orderDTO 编码申请的信息 */ private void checkEnumOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map errorMap) { //如果枚举可以修改,则不需要校验是否符合枚举的选项 Map enumAttrVOMap = templateVO.getAttributes().stream().filter(s -> (StringUtils.isNotBlank(s.getEnumString()) || StringUtils.isNotBlank(s.getEnumId())) && !VciBaseUtil.getBoolean(s.getEnumEditFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(enumAttrVOMap)) { enumAttrVOMap.forEach((attrId, attrVO) -> { String value = getValueFromOrderDTO(orderDTO, attrId); if (StringUtils.isNotBlank(value)) { //有值才能校验 List comboboxKVs = this.engineService.listComboboxItems(attrVO); if (!comboboxKVs.stream().anyMatch(s -> value.equalsIgnoreCase(s.getKey()))) { errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性【" + attrVO.getName() + "】的值不符合枚举的要求"); //throw new VciBaseException("属性【{0}】的值不符合枚举的要求", new String[]{attrVO.getName()}); } } }); } } /** * 转换时间的格式 * * @param templateVO 模板的显示对象,需要包含属性 * @param orderDTO 编码申请的信息 */ private void switchDateAttrOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO) { Map dateAttrVOMap = templateVO.getAttributes().stream().filter(s -> StringUtils.isNotBlank(s.getCodeDateFormat())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dateAttrVOMap.forEach((attrId, attrVO) -> { String value = getValueFromOrderDTO(orderDTO, attrId); if (StringUtils.isNotBlank(value)) { DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(value); value = VciDateUtil.date2Str(dateConverter.getValue(), VciDateUtil.DateTimeMillFormat); setValueToOrderDTO(orderDTO, attrId, value); } }); } } /** * 拷贝数据到cbo对象上 * * @param classifyFullInfo 分类的全部信息 * @param cbo 业务数据 * @param orderDTO 编码申请的信息 * @param templateVO 模板的显示对象 * @param edit 是否为修改 */ private void copyValueToCBO(CodeClassifyFullInfoBO classifyFullInfo, ClientBusinessObject cbo, CodeOrderDTO orderDTO, CodeClassifyTemplateVO templateVO, boolean edit, Map errorMap) { String fullPath = ""; if (!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())) { fullPath = classifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o2.getDataLevel().compareTo(o1.getDataLevel()))) .map(CodeClassifyVO::getOid).collect(Collectors.joining("##")); } else { fullPath = classifyFullInfo.getCurrentClassifyVO().getOid(); } orderDTO.getData().forEach((key, value) -> { if (!edit || (!engineService.checkUnAttrUnEdit(key) && !VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(key))) { try { cbo.setAttributeValue(key, value); } catch (VciBaseException e) { log.error("设置属性的值错误", e); } } }); try { cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid()); cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, templateVO.getOid()); cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath); if (!edit && StringUtils.isBlank(orderDTO.getLcStatus())) { //找生命周期的起始状态, if (StringUtils.isNotBlank(cbo.getLctid())) { //OsLifeCycleVO lifeCycleVO = lifeCycleService.getLifeCycleById(cbo.getLctid()); // if (lifeCycleVO != null) { // cbo.setLcStatus(lifeCycleVO.getStartStatus()); // } else { cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); // } } else { cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } } int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD)); if (secret == 0 || !secretService.checkDataSecret(secret).getData()) { Integer userSecret = VciBaseUtil.getCurrentUserSecret(); cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret)); } } catch (Throwable e) { log.error("设置默认的属性的值错误", e); } } /** * 设置新的值到申请对象上 * * @param orderDTO 编码申请对象 * @param attrId 属性的编号 * @param value 值 */ private void setValueToOrderDTO(CodeOrderDTO orderDTO, String attrId, String value) { attrId = attrId.toLowerCase(Locale.ROOT); if (VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(attrId)) { WebUtil.setValueToField(WebUtil.getFieldForObject(attrId, orderDTO.getClass()).getName(), orderDTO, value); } else { orderDTO.getData().put(attrId, value); } } /** * 从编码申请信息对象上获取某个属性的值 * * @param orderDTO 编码申请对象 * @param attrId 属性的编号 * @return 值 */ private String getValueFromOrderDTO(CodeOrderDTO orderDTO, String attrId) { attrId = attrId.toLowerCase(Locale.ROOT); String value = null; if (VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(attrId)) { value = WebUtil.getStringValueFromObject(WebUtil.getValueFromField(WebUtil.getFieldForObject(attrId, orderDTO.getClass()).getName(), orderDTO)); } else { //说明是自行配置的 //前端必须要传递小写的属性 value = orderDTO.getData().getOrDefault(attrId, ""); } return value; } /** * 处理分类注入的信息 * * @param templateVO 模板的显示对象,必须要后模板的属性 * @param classifyFullInfoBO 分类的全路径 * @param orderDTO 编码申请的信息 */ private void switchClassifyLevelOnOrder(CodeClassifyTemplateVO templateVO, CodeClassifyFullInfoBO classifyFullInfoBO, CodeOrderDTO orderDTO, Map errorMap) { Map classifyAttrVOMap = templateVO.getAttributes().stream().filter( s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr()) && StringUtils.isNotBlank(s.getClassifyInvokeLevel()) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (classifyFullInfoBO.getTopClassifyVO() == null) { //需要重新查询一下,因为这个是指定的分类进来的 } if (!CollectionUtils.isEmpty(classifyAttrVOMap)) { classifyAttrVOMap.forEach((attrId, attrVO) -> { //分类注入的编号或者名称, //层级包含指定层和最小层 CodeClassifyVO classifyVO = null; if (!CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(attrVO.getClassifyInvokeLevel()) && !"min".equalsIgnoreCase(attrVO.getClassifyInvokeLevel())) { //指定了层级的 //注意,因为查询上级分类出来的层级是倒序的,即顶层节点是最大的值 List classifyVOS = classifyFullInfoBO.getParentClassifyVOs().stream().sorted(((o1, o2) -> o2.getDataLevel().compareTo(o1.getDataLevel()))).collect(Collectors.toList()); int level = VciBaseUtil.getInt(attrVO.getClassifyInvokeLevel()); if (classifyVOS.size() >= level && level > 0) { classifyVO = classifyVOS.get(level - 1); } } else { //当前的分类 classifyVO = classifyFullInfoBO.getCurrentClassifyVO(); } if (classifyVO == null) { //说明层级有误 errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";分类树上没有层级[" + attrVO.getClassifyInvokeLevel() + "]"); //orderDTO.getData().put(attrId, "分类树上没有层级[" + attrVO.getClassifyinvokelevel() + "]"); // classifyVO = classifyFullInfoBO.getCurrentClassifyVO(); } else { Map classifyDataMap = VciBaseUtil.objectToMapString(classifyVO); String value = classifyDataMap.getOrDefault(attrVO.getClassifyInvokeAttr(), ""); orderDTO.getData().put(attrId, value); } }); } } /*** * * @param codeClassifyVO * @param templateVO * @param codeDataMap * @param codeSystemObjectMap * @param codeOrderDTOList * @param errorMap * @return */ private void getCodeOrderDTOs(CodeClassifyVO codeClassifyVO, CodeClassifyTemplateVO templateVO, Map codeDataMap, Map codeSystemObjectMap, List codeOrderDTOList, Map errorMap, boolean isCodeOrGroupCode) { codeSystemObjectMap.keySet().forEach(code -> { ClientBusinessObject sysDataObject = codeSystemObjectMap.get(code); if (isCodeOrGroupCode) { // code = sysDataObject.getAttributeValue("GROUPCODE"); if (StringUtils.isBlank(code)) { code = sysDataObject.getId(); } } CodeOrderDTO orderDTO = new CodeOrderDTO(); if (codeDataMap.containsKey(code)) { RowDatas rowDatas = codeDataMap.get(code); Map data = rowDatas.getFiledValue(); orderDTO.setCodeClassifyOid(codeClassifyVO.getOid());//分类主键 orderDTO.setOid(sysDataObject.getOid());//数据oid orderDTO.setLcStatus(rowDatas.getStatus());//状态 orderDTO.setId(code); orderDTO.setTs(sysDataObject.getTs()); orderDTO.setBtmname(codeClassifyVO.getBtmname());//业务类型 orderDTO.setDescription("集成调用:更新");//数据描述 if (data.containsKey("name")) { String name = data.get("name"); orderDTO.setName(name);//名称属性值 } orderDTO.setData(data);//设置数据 orderDTO.setSecDTOList(null);//分类码段 orderDTO.setEditInProcess(false);//是否在流程中 orderDTO.setTemplateOid(templateVO.getOid()); } else { errorMap.put("code", "编码为:【" + code + "】的数据在系统中不存在"); } codeOrderDTOList.add(orderDTO); }); } /** * 获取分类的全路径 * * @param classifyFullInfo 分类的全部信息 * @return 全路径 */ private String getFullPath(CodeClassifyFullInfoBO classifyFullInfo) { String fullPath = ""; if (!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())) { fullPath = classifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o1.getDataLevel().compareTo(o2.getDataLevel()))) .map(CodeClassifyVO::getOid).collect(Collectors.joining("##")); } else { fullPath = classifyFullInfo.getCurrentClassifyVO().getOid(); } return fullPath; } /** * 检查码段的长度是否符合要求 * * @param cboList 数据 * @param classifyVOMap 分类映射 * @param ruleVOMap 规则对象 * @param ruleOidMap 分类包含规则 * @param errorMap 错误的信息 * @param ruleRowIndexMap 规则包含的行号,key是规则主键,value是包含的全部行号 */ private void checkSecLengthInHistory(List cboList, Map classifyVOMap, Map ruleVOMap, Map ruleOidMap, Map errorMap, Map> ruleRowIndexMap) { cboList.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); String secLength = cbo.getAttributeValue(CODE_SEC_LENGTH_FIELD); //找分类 String classifyOid = cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD); CodeClassifyVO classifyVO = classifyVOMap.get(classifyOid); if (classifyVO != null) { //2#2#4#1这样的方式 CodeRuleVO ruleVO = ruleVOMap.getOrDefault(ruleOidMap.get(classifyVO.getOid()), null); if (ruleVO != null) { String[] secValues = secLength.split("#"); //总长度和编码的长度 String code = cbo.getAttributeValue(CODE_FIELD); if (code.length() != Arrays.stream(secValues).mapToInt(s -> VciBaseUtil.getInt(s)).sum()) { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同"); } else if (secValues.length != ruleVO.getSecVOList().size()) { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同"); } else { //每一个长度都不能超过码段的 boolean fined = false; for (int j = 0; j < ruleVO.getSecVOList().size(); j++) { CodeBasicSecVO secVO = ruleVO.getSecVOList().get(j); String length = secValues[j]; if (StringUtils.isNotBlank(secVO.getCodeSecLength()) && VciBaseUtil.getInt(length) > (VciBaseUtil.getInt(secVO.getCodeSecLength()) + ((secVO.getPrefixCode() + secVO.getSuffixCode()).length()))) { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同"); fined = true; break; } } /**for (int i = 0; i < secValues.length; i++) { for (int j = 0; j < ruleVO.getSecVOList().size(); j++) { CodeBasicSecVO secVO = ruleVO.getSecVOList().get(j); if (VciBaseUtil.getInt(secValues[i]) > VciBaseUtil.getInt(secVO.getCodeSecLength())) { errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";码段宽度与系统中的编码规则不同" ); fined = true; break; } } if(fined){ break; } }***/ if (!fined) { //暂时不取流水的内容,因为调用produceCode的时候去处理 List rowIndexList = ruleRowIndexMap.getOrDefault(ruleVO.getOid(), new ArrayList<>()); rowIndexList.add(rowIndex); ruleRowIndexMap.put(ruleVO.getOid(), rowIndexList); } } } else { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";分类没有设置编码规则"); } } }); } /** * excel转换为cbo的对象 * * @param classifyFullInfo 分类的全部信息 * @param fieldIndexMap 字段的位置 * @param rowDataList excel里的行数据 * @param templateVO 模板的显示对象 * @param cboList 数据的列表 * @param fullPath 全路径 * @param operation 操作类型 * @param errorMap 错误信息记录 */ private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, List titleRowData, Map fieldIndexMap, List rowDataList, CodeClassifyTemplateVO templateVO, List cboList, String fullPath, boolean isProcess, String operation, Map errorMap, Map codeOidToSystemOidMap) { rowDataList.stream().forEach(rowData -> { String oid = rowData.getOid(); String rowNumber = rowData.getRowIndex(); ClientBusinessObject cbo = new ClientBusinessObject(); DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId()); rowData.getData().forEach((index, value) -> { String field = fieldIndexMap.get(index); if (StringUtils.isBlank(field)) { errorMap.put(rowNumber, "属性:【" + titleRowData.get(index) + "】在系统中不存在"); } try { cbo.setAttributeValueWithNoCheck(field, value); if (WebUtil.isDefaultField(field)) { WebUtil.setValueToField(field, cbo, value); } } catch (VciBaseException e) { log.error("设置属性的值错误", e); errorMap.put(rowNumber, "属性:【" + titleRowData.get(index) + "】在系统中不存在"); } }); try { cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.getRowIndex()); cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, templateVO.getOid()); if (operation.equals("create")) { log.info("分类对象:" + classifyFullInfo.getCurrentClassifyVO()); log.info("codeClassoid:" + classifyFullInfo.getCurrentClassifyVO().getOid()); cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid()); cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath); int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD)); if (secret == 0 || !secretService.checkDataSecret(secret).getData()) { Integer userSecret = VciBaseUtil.getCurrentUserSecret(); String secretValue = String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret); cbo.setAttributeValue(SECRET_FIELD, secretValue); } if (rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())) {//停用 cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())) {//编辑 cbo.setLcStatus(CodeDefaultLC.EDITING.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中 cbo.setLcStatus(CodeDefaultLC.AUDITING.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收 cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue()); } else { cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());//发布 } /** if(!isProcess){ cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); }else { if(rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())){//停用 cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue()); }else if(rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())){//编辑 cbo.setLcStatus(CodeDefaultLC.EDITING.getValue()); }else {//发布 cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } }***/ cbo.setCreator(rowData.getCreator()); cbo.setLastModifier(rowData.getEditor() == null ? "" : rowData.getEditor()); } else if (operation.equals("update")) { //此时还没有转换路径 //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath)); if (rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())) {//停用 cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.RELEASED.getValue())) {//发布 cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())) {//编辑 cbo.setLcStatus(CodeDefaultLC.EDITING.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中 cbo.setLcStatus(CodeDefaultLC.AUDITING.getValue()); } else if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收 cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue()); } cbo.setLastModifier(rowData.getEditor() == null ? "" : rowData.getEditor());//修改者 } else if (operation.equals("delete")) { if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收 cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue()); } else { cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue());//停用 } } } catch (Throwable e) { log.error("设置默认的属性的值错误", e); if (e instanceof VciBaseException) { errorMap.put(rowNumber, "设置默认的属性的值错误" + ((VciBaseException) e).getMessage()); } else { errorMap.put(rowNumber, "设置默认的属性的值错误" + e.getMessage()); } } finally { codeOidToSystemOidMap.put(cbo.getOid(), oid); } cbo.setDescription(""); cboList.add(cbo); }); } /** * excel转换为cbo的对象 * * @param classifyFullInfo 分类的全部信息 * @param codeImprotDataVO: 分类对应的数据 * @param cboList 数据的列表 * @param newCode 是否为批量申请 */ private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, CodeImprotDataVO codeImprotDataVO, List cboList, boolean newCode) { String fullPath = getFullPath(classifyFullInfo); codeImprotDataVO.getDatas().stream().forEach(rowData -> { ClientBusinessObject cbo = new ClientBusinessObject(); DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId()); rowData.forEach((field, value) -> { try { cbo.setAttributeValueWithNoCheck(field, value); if (WebUtil.isDefaultField(field)) { WebUtil.setValueToField(field, cbo, value); } } catch (VciBaseException e) { log.error("设置属性的值错误", e); } }); try { cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, codeImprotDataVO.getTemplateOid()); cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.get(IMPORT_ROW_INDEX)); if (newCode) { cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid()); cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath); //cbo.setLcStatus(CodeDefaultLC.EDITING.getValue()); int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD)); if (secret == 0 || !secretService.checkDataSecret(secret).getData()) { Integer userSecret = VciBaseUtil.getCurrentUserSecret(); cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret)); } cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } else { //此时还没有转换路径 //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath)); cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } rowData.put("oid", cbo.getOid()); } catch (Throwable e) { log.error("设置默认的属性的值错误", e); } cboList.add(cbo); }); } /** * excel转换为cbo的对象 * * @param classifyFullInfo 分类的全部信息 * @param fieldIndexMap 字段的位置 * @param rowDataList excel里的行数据 * @param templateVO 模板的显示对象 * @param cboList 数据的列表 * @param fullPath 全路径 * @param newCode 是否为批量申请 */ private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, Map fieldIndexMap, List rowDataList, CodeClassifyTemplateVO templateVO, List cboList, String fullPath, boolean newCode) { rowDataList.stream().forEach(rowData -> { ClientBusinessObject cbo = new ClientBusinessObject(); DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId()); R> listR = btmTypeClient.selectByIdCollection(Collections.singletonList(classifyFullInfo.getTopClassifyVO().getBtmTypeId())); if (!listR.isSuccess() || listR.getData().size() == 0) { throw new VciBaseException("传入业务类型未查询到相应表单,请检查!"); } cbo.setRevisionRule("".equals(listR.getData().get(0).getVersionRule()) ? "1" : listR.getData().get(0).getVersionRule()); rowData.getData().forEach((index, value) -> { String field = fieldIndexMap.get(index); if (StringUtils.isBlank(field)) { throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在"); } try { cbo.setAttributeValueWithNoCheck(field, value); if (WebUtil.isDefaultField(field)) { WebUtil.setValueToField(field, cbo, value); } } catch (VciBaseException e) { log.error("设置属性的值错误", e); } }); try { cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, templateVO.getOid()); cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.getRowIndex()); if (newCode) { cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid()); cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath); //cbo.setLcStatus(CodeDefaultLC.EDITING.getValue()); int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD)); if (secret == 0 || !secretService.checkDataSecret(secret).getData()) { Integer userSecret = VciBaseUtil.getCurrentUserSecret(); cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret)); } cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } else { //此时还没有转换路径 //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath)); cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue()); } } catch (Throwable e) { log.error("设置默认的属性的值错误", e); } cboList.add(cbo); }); } /** * excel转换为cbo的对象 * * @param fieldIndexMap 字段的位置 * @param rowDataList excel里的行数据 * @param orderDTO 整理的数据 * @param map 数据的列表 */ private void excelToCboEdit(Map fieldIndexMap, SheetRowData rowDataList, CodeOrderDTO orderDTO, Map map) { rowDataList.getData().forEach((index, value) -> { String field = fieldIndexMap.get(index); if (StringUtils.isBlank(field)) { throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在"); } map.put(field.toUpperCase(), value); }); try { // for (Map map : cbos) { // Object obj = CodeOrderDTO.class.newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(orderDTO.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor property : propertyDescriptors) { Method setter = property.getWriteMethod(); if (setter != null) { //oracle的时间为TIMESTAMP的,需要进行转换成data,否则将报错 if (map.get(property.getName().toUpperCase()) instanceof TIMESTAMP) { LocalDateTime localDateTime = ((TIMESTAMP) map.get(property.getName().toUpperCase())).toLocalDateTime(); ZoneId zoneId = ZoneId.systemDefault(); ZonedDateTime zdt = localDateTime.atZone(zoneId); Date date = Date.from(zdt.toInstant()); setter.invoke(orderDTO, date); map.remove(property.getName().toUpperCase()); } //oracle的数字为BigDecimal的,需要进行转换成Integer,否则将报错 else if (map.get(property.getName().toUpperCase()) instanceof BigDecimal && ("Integer").equals(setter.getParameterTypes()[0].getSimpleName())) { setter.invoke(orderDTO, ((BigDecimal) map.get(property.getName().toUpperCase())).intValue()); map.remove(property.getName().toUpperCase()); } else if (map.containsKey(property.getName().toUpperCase())) { if (setter.getParameterTypes()[0].getSimpleName().equals("String")) { setter.invoke(orderDTO, map.get(property.getName().toUpperCase()) == null ? null : String.valueOf(map.get(property.getName().toUpperCase()))); } else { setter.invoke(orderDTO, map.get(property.getName().toUpperCase())); } map.remove(property.getName().toUpperCase()); } } } for (Object key : map.keySet()) { map.put(key, map.get(key) == null ? null : String.valueOf(map.get(key))); } } catch (Exception e) { throw new VciBaseException("查询失败:" + e.getMessage()); } // Iterator> iterator = cbos.entrySet().iterator(); // // Map.Entry entry; // while (iterator.hasNext()) { // entry = iterator.next(); //// if (WebUtil.isDefaultField(entry.getKey())) { // Object obj = BaseModel.class.newInstance(); // BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); // for (PropertyDescriptor property : propertyDescriptors) { // Method setter = property.getWriteMethod(); // if (setter != null) { // //oracle的时间为TIMESTAMP的,需要进行转换成data,否则将报错 // if (map.get(property.getName().toUpperCase()) instanceof TIMESTAMP) { // LocalDateTime localDateTime = ((TIMESTAMP) map.get(property.getName().toUpperCase())).toLocalDateTime(); // ZoneId zoneId = ZoneId.systemDefault(); // ZonedDateTime zdt = localDateTime.atZone(zoneId); // Date date = Date.from(zdt.toInstant()); // setter.invoke(obj, date); // map.remove(property.getName().toUpperCase()); // } //oracle的数字为BigDecimal的,需要进行转换成Integer,否则将报错 // else if (map.get(property.getName().toUpperCase()) instanceof BigDecimal // && ("Integer").equals(setter.getParameterTypes()[0].getSimpleName())) { // setter.invoke(obj, ((BigDecimal) map.get(property.getName().toUpperCase())).intValue()); // map.remove(property.getName().toUpperCase()); // } else if (map.containsKey(property.getName().toUpperCase())) { // if(setter.getParameterTypes()[0].getSimpleName().equals("String")){ // setter.invoke(obj, map.get(property.getName().toUpperCase()) == null ? null:String.valueOf(map.get(property.getName().toUpperCase()))); // }else{ // setter.invoke(obj, map.get(property.getName().toUpperCase())); // } // map.remove(property.getName().toUpperCase()); // } // } // } // WebUtil.setValueToField(entry.getKey(), orderDTO, entry.getValue()); // iterator.remove(); //// } // } orderDTO.setData(map); } /** * 检查校验规则没有通过的内容 * * @param attrVOS 需要校验的属性 * @param dataList 数据的列表 * @param errorMap 错误的信息映射 * @return 校验不通过的行数 */ private void batchCheckVerifyOnOrder(Collection attrVOS, List dataList, Map errorMap) { Map verifyAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getVerifyRule()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(verifyAttrVOMap)) { Map/**校验不通过的属性**/> unPassCheckMap = new HashMap<>(); verifyAttrVOMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { String value = cbo.getAttributeValue(attrId); if (StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); List unPassAttrs = unPassCheckMap.getOrDefault(rowIndex, new ArrayList<>()); unPassAttrs.add(attrVO.getName()); unPassCheckMap.put(rowIndex, unPassAttrs); } }); }); if (!CollectionUtils.isEmpty(unPassCheckMap)) { unPassCheckMap.forEach((rowIndex, unPassAttrs) -> { errorMap.put(rowIndex, ";属性[" + unPassAttrs.stream().collect(Collectors.joining(",")) + "]内容不符合校验规则的要求"); }); } } } /** * 批量转换时间都为指定的格式 * * @param attrVOS 模板属性 * @param cboList 数据的列表 * @param errorMap 错误的信息 */ private void batchSwitchDateAttrOnOrder(Collection attrVOS, List cboList, Map errorMap) { Map dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getCodeDateFormat()) && VciBaseUtil.getBoolean(s.getCodeDateFormat()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr()) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dateAttrVOMap.forEach((attrId, attrVO) -> { cboList.stream().forEach(cbo -> { String value = cbo.getAttributeValue(attrId); if (value == null) { value = ""; } if (StringUtils.isNotBlank(value)) { boolean formated = false; if (StringUtils.isNotBlank(attrVO.getCodeDateFormat())) { try { Date date = VciDateUtil.str2Date(value, attrVO.getCodeDateFormat()); if (date != null) { cbo.setAttributeValue(attrId, value); formated = true; } } catch (Exception e) { //说明不是这个格式 } } if (!formated) { try { DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(value); value = VciDateUtil.date2Str(dateConverter.getValue(), VciDateUtil.DateTimeMillFormat); cbo.setAttributeValue(attrId, value); } catch (Throwable e) { //转换不了 String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";属性[" + attrVO.getName() + "]时间格式不正确"); } } } }); }); } } /** * 系统模板中默认值设置 * * @param attrVOS 模板属性 * @param dataList excel的数据内容 */ private void batchSwitchAttrDefault(Collection attrVOS, List dataList) { Map dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getDefaultValue())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dateAttrVOMap.forEach((attrId, attrVO) -> { String defaultValue = attrVO.getDefaultValue(); dataList.stream().forEach(cbo -> { String dataValue = cbo.getAttributeValue(attrId); if (StringUtils.isBlank(dataValue)) { dataValue = defaultValue; } try { cbo.setAttributeValue(attrId, dataValue); } catch (Throwable e) { log.error("设置属性的错误", e); } }); }); } } /** * 转移boolean型的属性 * * @param attrVOS 属性的对象 * @param dataList 数据 */ private void reSwitchBooleanAttrOnOrder(Collection attrVOS, List dataList) { Map booleanAttrMap = attrVOS.stream().filter( s -> VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(s.getAttributeDataType()) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(booleanAttrMap)) { booleanAttrMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { String text = cbo.getAttributeValue(attrId); try { if (BooleanEnum.TRUE.getValue().equalsIgnoreCase(text) || "是".equalsIgnoreCase(text)) { cbo.setAttributeValue(attrId, BooleanEnum.TRUE.getValue()); } else { cbo.setAttributeValue(attrId, BooleanEnum.FASLE.getValue()); } } catch (Throwable e) { } }); }); } } /** * 处理组合规则 * * @param attrVOS 模板属性 * @param dataList excel的数据内容 */ private void batchSwitchComponentAttrOnOrder(Collection attrVOS, List dataList) { Map dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getComponentRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dateAttrVOMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { //从excel上把属性转换为map Map thisRowDataMap = new HashMap<>(); copyValueToMapFromCbos(cbo, thisRowDataMap); //组合内容 String value = formulaService.getValueByFormula(thisRowDataMap, attrVO.getComponentRule()); if (value == null) { value = ""; } try { cbo.setAttributeValue(attrId, value); } catch (Throwable e) { log.error("设置属性的错误", e); } }); }); } } /** * 转换参照的值 * * @param attrVOS 属性的显示对象 * @param dataList 数据列表 * @param errorMap 错误的信息 */ private void batchSwitchReferAttrOnOrder(Collection attrVOS, List dataList, Map errorMap) { Map referAttrVOMap = attrVOS.stream().filter( s -> (StringUtils.isNotBlank(s.getReferBtmId()) || StringUtils.isNotBlank(s.getReferConfig())) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(referAttrVOMap)) { Map/**表格里的值**/>> linkValueMap = new HashMap<>(); referAttrVOMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { String text = cbo.getAttributeValue(attrId); if (StringUtils.isNotBlank(text)) { UIFormReferVO referVO = getReferVO(attrVO); String valueField = getValueField(referVO); String showText = getTextField(referVO); String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField; Map> showTextMap = linkValueMap.getOrDefault(tableAndAttr, new HashMap<>()); List textList = showTextMap.getOrDefault(showText, new ArrayList<>()); if (!textList.contains(text)) { textList.add(text); } showTextMap.put(showText, textList); linkValueMap.put(tableAndAttr, showTextMap); } }); }); if (!CollectionUtils.isEmpty(linkValueMap)) { //需要逐个表的值字段,逐个查询 Map>> linkCboMap = new HashMap<>(); linkValueMap.forEach((tableAndAttr, showValueMap) -> { String[] split = tableAndAttr.split("#"); String table = split[0]; String valueField = split[1].toLowerCase(Locale.ROOT); Map> dataMap = new HashMap<>(); showValueMap.forEach((showText, valueList) -> { Map valueOidTextMap = new HashMap<>(); List> valueCollections = VciBaseUtil.switchListForOracleIn(valueList); String sql = "select " + valueField + "," + showText.toLowerCase(Locale.ROOT) + " from " + table + " where " + showText + " in (%s)"; valueCollections.stream().forEach(values -> { List> dataMapList = commonsMapper.queryByOnlySqlForMap(String.format(sql, VciBaseUtil.toInSql(values.toArray(new String[0])))); DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true); List cbos = ChangeMapTOClientBusinessObjects(dataMapList); if (!CollectionUtils.isEmpty(cbos)) { valueOidTextMap.putAll(cbos.stream().collect(Collectors.toMap(s -> s.getAttributeValue(valueField), t -> t.getAttributeValue(showText)))); } }); dataMap.put(showText, valueOidTextMap); }); linkCboMap.put(tableAndAttr, dataMap); }); referAttrVOMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { String text = cbo.getAttributeValue(attrId); if (StringUtils.isNotBlank(text)) { UIFormReferVO referVO = getReferVO(attrVO); String valueField = getValueField(referVO); String showText = getTextField(referVO); String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField; if (!linkCboMap.containsKey(tableAndAttr)) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在"); } else { Map> dataMap = linkCboMap.get(tableAndAttr); if (!dataMap.containsKey(showText)) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在"); } else { Map data = dataMap.get(showText); final boolean[] fined = {false}; data.forEach((key, value) -> { if (value.equalsIgnoreCase(text)) { fined[0] = true; try { cbo.setAttributeValue(attrId, key); } catch (Throwable e) { } } }); if (!fined[0]) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在"); } } } } }); }); } } } /** * 批量检查企业编码是否存在 * * @param templateVO 模板的显示对象 * @param cboList 数据的列表 * @param errorMap 错误的信息 */ private void batchCheckIdExistOnOrder(CodeClassifyTemplateVO templateVO, List cboList, Map errorMap) throws Throwable { List existIds = new ArrayList<>(); String tableName = ""; try { R r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId()); if (!r.isSuccess()) { throw new Throwable(r.getMsg()); } BtmTypeVO btmTypeVO = r.getData(); if (btmTypeVO == null) { throw new Throwable("根据业务类型未查询到业务类型对象!"); } tableName = btmTypeVO.getTableName(); if (StringUtils.isBlank(tableName)) { throw new Throwable("根据业务类型未查询到业务类型相关联的表"); } } catch (Throwable e) { throw e; } String finalTableName = tableName; VciBaseUtil.switchCollectionForOracleIn(cboList).stream().forEach(cbos -> { Map conditionMap = new HashMap<>(); conditionMap.put("id", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0])) + ")"); StringBuffer sb = new StringBuffer(); sb.append(" select id from "); sb.append(finalTableName); //sb.append(" where 1 = 1"); sb.append(" where lastr = 1 and lastv = 1"); //TODO:涉及到已升版的数据也应该排除掉,否则会报重 sb.append(" and id in ("); sb.append(VciBaseUtil.toInSql(cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0]))); sb.append(")"); List idList = commonsMapper.selectById(sb.toString()); //业务数据如果码值回收会直接删除数据,所以这里直接判断是否存在即可 existIds.addAll(Optional.ofNullable(idList).orElseGet(() -> new ArrayList<>()).stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toList())); }); if (!CollectionUtils.isEmpty(existIds)) { String idFieldName = templateVO.getAttributes().stream().filter(s -> VciQueryWrapperForDO.ID_FIELD.equalsIgnoreCase(s.getId())).findFirst().orElseGet(() -> new CodeClassifyTemplateAttrVO()).getName(); if (StringUtils.isBlank(idFieldName)) { idFieldName = "企业编码"; } String finalIdFieldName = idFieldName; cboList.stream().forEach(cbo -> { String id = cbo.getId(); if (StringUtils.isBlank(id)) { id = cbo.getAttributeValue("id"); } if (existIds.contains(id)) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); String msg = errorMap.getOrDefault(rowIndex, ""); msg += ";" + finalIdFieldName + "的值在系统中已经存在"; errorMap.put(rowIndex, msg); } }); } } /*** * 校验分类对应的模板信息 * @param titleRowData * @param sheetDataSetList * @param shetNumber * @param pathMap * @param errorMap * @return * @throws Throwable */ private LinkedList checkSamesTemplate(List titleRowData, List sheetDataSetList, int shetNumber, Map pathMap, Map errorMap) throws Throwable { Map pathOidMap = new HashMap<>(); Map templateIdRowIndex = new HashedMap(); SheetDataSet dataSet = sheetDataSetList.get(shetNumber); LinkedHashMap codeClassifyTemplateVOMap = new LinkedHashMap(); for (int i = 0; i < titleRowData.size(); i++) { String title = titleRowData.get(i); if (title.equals("分类路径")) { int finalI = i; dataSet.getRowData().stream().forEach(sheetRowData -> { String Path = sheetRowData.getData().get(finalI); String rowIndex = sheetRowData.getRowIndex(); if (StringUtils.isBlank(Path)) { Path = "#current#"; } CodeClassifyTemplateVO newTemplateVO = new CodeClassifyTemplateVO(); String templateOid = ""; if (pathOidMap.containsKey(Path)) { templateOid = pathOidMap.get(Path); newTemplateVO = codeClassifyTemplateVOMap.get(templateOid); } else { if (pathMap.containsKey(Path)) { CodeClassifyVO codeClassifyVO = pathMap.get(Path); newTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid()); if (newTemplateVO != null) { templateOid = newTemplateVO.getOid(); } else { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类模板"); } } else { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类"); } } pathOidMap.put(Path, templateOid); codeClassifyTemplateVOMap.put(templateOid, newTemplateVO); templateIdRowIndex.put(templateOid, templateIdRowIndex.getOrDefault(templateOid, "") + "," + rowIndex); }); break; } } LinkedList codeClassifyTemplateVOList = new LinkedList<>(); StringBuffer sb = new StringBuffer(); codeClassifyTemplateVOMap.keySet().forEach(tempateOid -> { String templateOidInExcel = ""; String tempateName = ""; CodeClassifyTemplateVO t = codeClassifyTemplateVOMap.get(tempateOid); codeClassifyTemplateVOList.add(t); if (!CollectionUtils.isEmpty(sheetDataSetList) && sheetDataSetList.size() > 1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size() - 1).getColName())) { List rowData = sheetDataSetList.get(sheetDataSetList.size() - 1).getRowData(); templateOidInExcel = rowData.get(shetNumber).getData().get(0); tempateName = rowData.get(shetNumber).getData().get(2); //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i); } if (StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(tempateOid)) { sb.append("模板【" + tempateName + "】中第" + templateIdRowIndex.get(tempateOid) + "行数据不属于当前模板的数据,请核对!"); } }); if (StringUtils.isNotBlank(sb.toString())) { throw new Throwable(sb.toString()); } if (codeClassifyTemplateVOList.size() > 1) { String message = "模板【" + dataSet.getSheetName() + "】根据分类路径判断,分类存在多个模板"; throw new Throwable(message); } if (codeClassifyTemplateVOList.size() == 0) { String message = "模板【" + dataSet.getSheetName() + "】根据数据分类路径判断,未匹配到对应模板"; throw new Throwable(message); } return codeClassifyTemplateVOList; } /** * 从属性上获取参照的内容 * * @param attrVO 属性的信息 * @return 参照的内容 */ private UIFormReferVO getReferVO(CodeClassifyTemplateAttrVO attrVO) { UIFormReferVO referVO = null; if (StringUtils.isNotBlank(attrVO.getReferConfig())) { referVO = JSONObject.parseObject(attrVO.getReferConfig(), UIFormReferVO.class); } else { referVO = new UIFormReferVO(); referVO.setReferType(attrVO.getReferBtmId()); referVO.setValueField(VciQueryWrapperForDO.OID_FIELD); referVO.setTextField("name"); } return referVO; } /** * 获取参照中的值的字段 * * @param referVO 参照的对象 * @return 默认为Oid,有多个的时候,获取第一个 */ private String getValueField(UIFormReferVO referVO) { String showText = referVO.getValueField(); if (StringUtils.isBlank(showText)) { return "oid"; } if (showText.contains(",")) { //防止万一有多个,看看有没有oid List strings = VciBaseUtil.str2List(showText); if (strings.contains("oid")) { showText = "oid"; } else { showText = strings.get(0); } } return showText; } /** * 获取参照中的显示内容的字段 * * @param referVO 参照的对象 * @return 默认为name,有多个的时候,获取第一个 */ private String getTextField(UIFormReferVO referVO) { String showText = referVO.getTextField(); if (StringUtils.isBlank(showText)) { return "name"; } if (showText.contains(",")) { //防止万一有多个,看看有没有name List strings = VciBaseUtil.str2List(showText); if (strings.contains("name")) { showText = "name"; } else { showText = strings.get(0); } } return showText; } /** * 处理枚举的显示对象 * * @param attrVOS 模板属性 * @param dataList excel的数据内容 * @param errorMap 错误信息的映射 */ private void batchSwitchEnumAttrOnOrder(Collection attrVOS, List dataList, Map errorMap) { Map dateAttrVOMap = attrVOS.stream().filter( s -> (StringUtils.isNotBlank(s.getEnumString()) || StringUtils.isNotBlank(s.getEnumId())) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dateAttrVOMap.forEach((attrId, attrVO) -> { dataList.stream().forEach(cbo -> { String text = cbo.getAttributeValue(attrId); if (StringUtils.isNotBlank(text)) { List valueList = engineService.listComboboxItems(attrVO); boolean fined = false; for (int i = 0; i < valueList.size(); i++) { KeyValue keyValue = valueList.get(i); //if(keyValue.getValue().equalsIgnoreCase(text)){ if (keyValue.getValue().equalsIgnoreCase(text) || keyValue.getKey().equalsIgnoreCase(text)) { try { cbo.setAttributeValue(attrId, keyValue.getKey()); } catch (Throwable e) { log.error("设置属性出错"); } fined = true; break; } } if (!fined) { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";属性[" + attrVO.getName() + "]的值不符合下拉的要求"); } } }); }); } } /** * 批量校验数据的信息 * * @param templateVO 模板的显示对象 * @param cboList 数据的内容 */ private void batchCheckRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO, List cboList, Map errorMap) { Map requiredAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && (StringUtils.isBlank(s.getClassifyInvokeLevel()) || s.getClassifyInvokeLevel().equals("none"))//不能是组合的和分类注入的 ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); //与MdmEngineServiceImpl里面的checkRequiredAttrOnOrder 逻辑应该相似 if (!CollectionUtils.isEmpty(requiredAttrMap)) { Set nullRowIndex = cboList.stream().filter(cbo -> requiredAttrMap.keySet().stream().anyMatch(attrId -> StringUtils.isBlank(cbo.getAttributeValue(attrId)))).map(cbo -> cbo.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet()); if (!CollectionUtils.isEmpty(nullRowIndex)) { String checkAttr = requiredAttrMap.values().stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(",")); nullRowIndex.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";校验规则必填项不通过,如果有必填属性为空,则填【/】代替,有校验的属性为" + checkAttr); }); } } } /** * 处理分类注入 * * @param attrVOS 模板属性 * @param dataList excel的数据内容 * @param classifyFullInfo 分类的全路径 */ private void batchSwitchClassifyAttrOnOrder(Collection attrVOS, List dataList, CodeClassifyFullInfoBO classifyFullInfo, boolean isImPort) { Map dateAttrVOMap = attrVOS.stream().filter( s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr()) ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); Map classifyFullInfoMap = new HashMap<>(); classifyFullInfoMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), classifyFullInfo); if (!CollectionUtils.isEmpty(dateAttrVOMap)) { dataList.stream().forEach(cbo -> { dateAttrVOMap.forEach((attrId, attrVO) -> { //分类注入的编号或者名称, //层级包含指定层和最小层 CodeClassifyVO classifyVO = null; if (!CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(attrVO.getClassifyInvokeLevel()) && !"min".equalsIgnoreCase(attrVO.getClassifyInvokeLevel())) { //指定了层级的 //注意,因为查询上级分类出来的层级是倒序的,即顶层节点是最大的值 if (isImPort) { if (!classifyFullInfoMap.containsKey(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD))) { CodeClassifyFullInfoBO currentClassifyFullInfo = classifyService.getClassifyFullInfo(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD)); classifyFullInfoMap.put(currentClassifyFullInfo.getCurrentClassifyVO().getOid(), currentClassifyFullInfo); } } CodeClassifyFullInfoBO newClassifyFullInfo = classifyFullInfoMap.get(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD)); List classifyVOS = newClassifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o2.getDataLevel().compareTo(o1.getDataLevel()))).collect(Collectors.toList()); int level = VciBaseUtil.getInt(attrVO.getClassifyInvokeLevel()); if (classifyVOS.size() >= level && level > 0) { classifyVO = classifyVOS.get(level - 1); } } else { //当前的分类 classifyVO = classifyFullInfo.getCurrentClassifyVO(); } try { if (classifyVO == null) { //说明层级有误 cbo.setAttributeValue(attrId, "分类树上没有层级[" + attrVO.getClassifyInvokeLevel() + "]"); } else { Map classifyDataMap = VciBaseUtil.objectToMapString(classifyVO); String value = classifyDataMap.getOrDefault(attrVO.getClassifyInvokeAttr(), ""); // log.error("================================当前分类注入的value值为:==========================",value); cbo.setAttributeValue(attrId, value); } } catch (Throwable e) { log.error("设置属性错误", e); } }); }); } } /** * 校验关键属性,和近义词查询规则 * * @param classifyFullInfo 分类的全部信息 * @param templateVO 模板的内容,必须包含模板属性 * @param cboList 批量的数据 * @param isEdit 是否是修改 * @param errorMap 必须必须必须是线程安全的集合 * */ private CodeImportResultVO batchCheckKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, List cboList, boolean isEdit, Map errorMap/*必须要是线程安全的集合*/) { //与MdmEngineServiceImpl里的checkKeyAttrOnOrder相似 //先获取关键属性的规则,也利用继承的方式 CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo); //注意的是keyRuleVO可能为空,表示不使用规则控制 //获取所有的关键属性 Map 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 sysonymAttrMaps = templateVO.getAttributes().stream().filter(item -> Func.isNotBlank(item.getSysonymRuleOids())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); // 获取是否有配置近义词查询规则属性 Map> codeSynonymMaps = new HashMap<>(); if (!sysonymAttrMaps.isEmpty()) { // 查询近义词规则,存储方式key:属性id,value近义词查询规则列表 codeSynonymMaps = codeSynonymService.getCodeSynonymByOids(sysonymAttrMaps); } boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag()); //全部去空的优先级大于去空 boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag()); boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag()); boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag()); //1. 我们需要先判断excel导入的内容是否正确 CodeImportResultVO resultVO = new CodeImportResultVO(); StringBuilder synonymResString = new StringBuilder(); if (Func.isNotEmpty(codeSynonymMaps)) { codeSynonymMaps.keySet().stream().forEach(item -> { synonymResString.append(item); synonymResString.append(","); }); } resultVO.setSynonymRuleInfo(Func.isEmpty(codeSynonymMaps) ? "" : String.format("以下[%s]被设置了近义词查询规则的关键属性,中出现了重复:", synonymResString)); resultVO.setKeyAttrRuleInfo(keyRuleVO == null ? "" : String.format("查询规则:去除空格--{%s},忽略大小写--{%s},忽略全半角--{%s},忽略全部空格--{%s}" , trim ? "是" : "否", ignoreCase ? "是" : "否", ignoreWidth ? "是" : "否", trimAll ? "是" : "否")); //resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(keyAttrMap,cboList,keyRuleVO)); // 先在表格中查询关键属性和近义词转换后重复的列 getSelfRepeatRowIndex(keyAttrMap, cboList, keyRuleVO, codeSynonymMaps, 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.判断关键属性在系统里是否重复 Map> indexTODataMap = new ConcurrentHashMap<>(); // 查询不需要参与关键属性校验的除自己以外的所有分类oid final String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid()); final BladeUser user = AuthUtil.getUser(); // TODO:Thread limit exceeded replacing blocked 异常是这部分代码抛出的 // ,所以暂时将parallelStream改成了stream,改成了stream之后发现巨慢 // customForkJoinPool控制并发度 final List finalCboList = cboList; final Map> finalCodeSynonymMaps = codeSynonymMaps; List repeatDataMap = (List) customForkJoinPool.submit(() -> { finalCboList.parallelStream().filter(cbo -> { //每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示 //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo); Map conditionMap = new HashMap<>(); 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, finalCodeSynonymMaps.get(attrId), attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap); }); if (!CollectionUtils.isEmpty(keyAttrMap)) { // 添加不参与关键属性校验的分类oid判断 if (Func.isNotBlank(isParticipateCheckOids)) { conditionMap.put("t.codeclsfid", QueryOptionConstant.NOTIN + isParticipateCheckOids); } //如果是更改则需排除系统本身 if (isEdit) { conditionMap.put("t.id", QueryOptionConstant.NOTEQUAL + cbo.getId()); } conditionMap.put("t.lastr", "1"); conditionMap.put("t.lastv", "1"); CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, null); List repeatData = commonsMapper.selectList(sqlBO.getSqlId()); if (!repeatData.isEmpty()) { final List> newDataList = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage()); DefaultAttrAssimtUtil.mapToLowerCase(newDataList, true); //List newCboList=ChangeMapTOClientBusinessObjects(newDataList); List newCboList = new ArrayList<>(); newDataList.stream().forEach(stringStringMap -> { BaseModel baseModel = new BaseModel(); DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(stringStringMap, baseModel, false, user); baseModel.setData(stringStringMap); newCboList.add(baseModel); }); // 添加错误值 String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); log.info("=============关键属性查询重复的============="+JSON.toJSONString(repeatData)); errorMap.put(rowIndex, "重复的记录编号为:" + repeatData.stream().collect(Collectors.joining(","))); if (!CollectionUtils.isEmpty(newCboList)) { indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX), newCboList); } } return !repeatData.isEmpty(); } else { return false; } }).collect(Collectors.toList()); }).join(); if (!CollectionUtils.isEmpty(repeatDataMap)) { resultVO.setKeyAttrRepeatRowIndexList(repeatDataMap.stream().map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet())); } resultVO.setIndexTODataMap(indexTODataMap); //resultVO.setSuccess(true); return resultVO; } /** * 检查分类的路径是否存在 * * @param cboList 业务数据 * @param errorMap 错误信息 * @param pathMap 路径和分类的映射 */ private void checkClassifyPathInHistory(List cboList, Map errorMap, Map pathMap, Map childOidPathMap) { cboList.parallelStream().forEach(cbo -> { String classifyPath = cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD); //如果path为空,则表示是导入当前分类 if (StringUtils.isBlank(classifyPath)) { classifyPath = "#current#"; } if (!pathMap.containsKey(classifyPath)) { String row_index = cbo.getAttributeValue(IMPORT_ROW_INDEX); errorMap.put(row_index, errorMap.getOrDefault(row_index, "") + ";分类路径不存在"); } else { //转一下分类的主键 try { String classifyOid = pathMap.get(classifyPath).getOid(); cbo.setAttributeValueWithNoCheck(CODE_CLASSIFY_OID_FIELD, classifyOid); cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(classifyOid, classifyPath)); } catch (VciBaseException e) { log.error("设置属性的错误", e); } } }); } /** * 检查分类以及子分类是否都有编码规则 * * @param classifyVOMap 分类的显示对象映射 * @param ruleOidMap 规则的主键映射 * @param unExistRuleClassifyOidList 不存在编码规则的分类的主键 */ private void checkRuleOidInHistory(Map classifyVOMap, Map ruleOidMap, List unExistRuleClassifyOidList) { if (!CollectionUtils.isEmpty(classifyVOMap)) { classifyVOMap.values().parallelStream().forEach(classifyVO -> { if (StringUtils.isNotBlank(classifyVO.getCodeRuleOid())) { ruleOidMap.put(classifyVO.getOid(), classifyVO.getCodeRuleOid()); } else { //递归找上级 List ruleOidList = new ArrayList<>(); recursionRule(classifyVOMap, classifyVO.getParentCodeClassifyOid(), ruleOidList); if (!CollectionUtils.isEmpty(ruleOidList)) { ruleOidMap.put(classifyVO.getOid(), ruleOidList.get(0)); } else { unExistRuleClassifyOidList.add(classifyVO.getOid()); } } }); } log.info(";;;;"); } /** * 递归找编码规则 * * @param classifyVOMap 分类的显示对象映射 * @param classifyOid 分类的主键 * @param ruleOidList 规则的主键list */ private void recursionRule(Map classifyVOMap, String classifyOid, List ruleOidList) { if (classifyVOMap.containsKey(classifyOid)) { CodeClassifyVO classifyVO = classifyVOMap.get(classifyOid); if (StringUtils.isNotBlank(classifyVO.getCodeRuleOid())) { ruleOidList.add(classifyVO.getCodeRuleOid()); return; } else { recursionRule(classifyVOMap, classifyVO.getParentCodeClassifyOid(), ruleOidList); } } else { Map parentClassifyVOMap = new HashMap<>(); CodeClassifyVO codeClassifyVO = this.classifyService.getObjectByOid(classifyOid); parentClassifyVOMap.put(codeClassifyVO.getOid(), codeClassifyVO); recursionRule(parentClassifyVOMap, codeClassifyVO.getOid(), ruleOidList); } } /** * 获取子分类的路径 * * @param classifyFullInfo 分类全部信息 * @param fullPath 分类的全路径 * @return 子分类的路径,key是分类的主键 */ private Map getChildClassifyPathMap(CodeClassifyFullInfoBO classifyFullInfo, String fullPath) { List childPathVOs = classifyService.listChildrenClassify(classifyFullInfo.getCurrentClassifyVO().getOid(), true, VciQueryWrapperForDO.OID_FIELD, true); Map childOidPathMap = new ConcurrentHashMap<>(); if (!CollectionUtils.isEmpty(childPathVOs)) { childPathVOs.parallelStream().forEach(childPath -> { // String thisClassifyPath = fullPath + "##" + childPath.getPath().replace("#" + classifyFullInfo.getCurrentClassifyVO().getOid() + "#","").replace("#","##"); List list = Arrays.asList(childPath.getPath().split("#")); List newPahtList = list.stream().sorted(Comparator.comparing(s -> s, Comparator.reverseOrder())).collect(Collectors.toList()); String thisClassifyPath = StringUtils.join(newPahtList, "##") + fullPath; childOidPathMap.put(childPath.getOid(), thisClassifyPath); }); } String path = classifyFullInfo.getCurrentClassifyVO().getId(); //根据客户选择的分类路径未id,还是name确定路径拼接 childOidPathMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), fullPath); return childOidPathMap; } /** * 获取导入的内容中关键属性近义词转换后重复的行号 * * @param ketAttrMap 关键属性的映射 * @param dataList 导入的数据 * @param keyRuleVO 关键属性控制规则 * @return 重复的行号 */ private void getSelfRepeatRowIndex(Map ketAttrMap, List dataList, CodeKeyAttrRepeatVO keyRuleVO,/*近义词查询规则*/Map> codeSynonymMaps, CodeImportResultVO resultVO) { Set selfRepeatRowIndexList = new CopyOnWriteArraySet<>(); Map> keyAttrOkOidTORepeatOidMap = new ConcurrentHashMap<>(); boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag()); //全部去空的优先级大于去空 boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag()); boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag()); boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag()); //必须将属性按照顺序排序好 List attrVOList = ketAttrMap.values().stream().sorted(((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()))).collect(Collectors.toList()); Map rowIndexKeyStringMap = new ConcurrentHashMap<>(); Map okOidKeyStringMap = new ConcurrentHashMap<>(); dataList.stream().forEach(cbo -> { String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); String oid = cbo.getOid(); StringBuilder sb = new StringBuilder(); // TODO: 2024-02-25改造实现近义词查询规则功能;关键属性重复校验值处理 attrVOList.stream().forEach(item -> { String attrId = item.getId().toLowerCase(Locale.ROOT); String value = cbo.getAttributeValue(attrId); if (value == null) { value = ""; } if (trim) { value = value.trim(); } if (trimAll) { value = value.replace(" ", ""); } if (ignoreCase) { value = value.toLowerCase(Locale.ROOT); } if (ignoreWidth) { value = VciBaseUtil.toDBC(value); } value = mdmEngineService.getValueToSynony(codeSynonymMaps.get(attrId), value); sb.append(value).append("${ks}"); }); String keyString = sb.toString(); if (rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)) { selfRepeatRowIndexList.add(rowIndex); String okOid = okOidKeyStringMap.getOrDefault(keyString, ""); if (StringUtils.isNotBlank(okOid)) { List newOidList = new ArrayList<>(); newOidList.add(oid); if (keyAttrOkOidTORepeatOidMap.containsKey(okOid)) { List oldOidList = keyAttrOkOidTORepeatOidMap.get(okOid); newOidList.addAll(oldOidList); } keyAttrOkOidTORepeatOidMap.put(okOid, newOidList); } } else { okOidKeyStringMap.put(sb.toString(), oid); rowIndexKeyStringMap.put(rowIndex, keyString); } }); //因为只是关键属性重复,所以我们不能重复的多条选一条来报错 // resultVO.setKeyAttrRepeatRowIndexList(selfRepeatRowIndexList); resultVO.setSelfRepeatRowIndexList(selfRepeatRowIndexList); resultVO.setKeyAttrOkOidTORepeatOidMap(keyAttrOkOidTORepeatOidMap); } /** * excel的标题上获取字段所在的位置 * * @param titleRowData 标题的内容 * @param attrNameIdMap 模板中属性名称和英文的映射 * @param fieldIndexMap 位置和英文字段的映射 */ private void getFieldIndexMap(List titleRowData, Map attrNameIdMap, Map fieldIndexMap) { for (int i = 0; i < titleRowData.size(); i++) { String title = titleRowData.get(i); String id = attrNameIdMap.getOrDefault(title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR , ""), ""); if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)) { id = CODE_CLASSIFY_OID_FIELD; } if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)) { id = CODE_SEC_LENGTH_FIELD; } if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)) { id = CODE_FIELD; } if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)) { fieldIndexMap.put(i, id); } } } private List ChangeMapTOClientBusinessObjects(List> oldDataMap) { List clientBusinessObjectList = new ArrayList<>(); DefaultAttrAssimtUtil.mapToLowerCase(oldDataMap, true); final BladeUser user = AuthUtil.getUser(); oldDataMap.stream().forEach(dataMap -> { ClientBusinessObject clientBusinessObject = new ClientBusinessObject(); DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap, clientBusinessObject, false, user); for (String key : dataMap.keySet()) { Object value = dataMap.getOrDefault(key, ""); clientBusinessObject.setAttributeValue(key.toLowerCase(Locale.ROOT), value == null ? "" : value.toString()); } clientBusinessObjectList.add(clientBusinessObject); }); return clientBusinessObjectList; } /*** * 根据不同模板组织execl数据 * @param dataSet * @param pathMap * @param errorMap */ private void createExeclClassData(SheetDataSet dataSet, Map pathMap, Map errorMap, List codeClassifyDatas) { Map pathDatas = new HashMap<>(); List titleRowData = dataSet.getColName(); List rowDataList = dataSet.getRowData(); LinkedHashMap codeClassifyTemplateVOMap = new LinkedHashMap(); LinkedHashMap codeRuleVOVOMap = new LinkedHashMap(); for (int i = 0; i < titleRowData.size(); i++) { String title = titleRowData.get(i); if (title.equals("分类路径")) { int finalI = i; rowDataList.stream().forEach(sheetRowData -> { CodeImprotDataVO dataVO = new CodeImprotDataVO(); String Path = sheetRowData.getData().get(finalI); String rowIndex = sheetRowData.getRowIndex(); Map execlData = sheetRowData.getData(); CodeClassifyTemplateVO newTemplateVO = new CodeClassifyTemplateVO(); CodeRuleVO codeRuleVO = new CodeRuleVO(); if (StringUtils.isEmpty(Path)) { Path = "#current#"; } if (pathMap.containsKey(Path)) { CodeClassifyVO codeClassifyVO = pathMap.get(Path); if (codeClassifyTemplateVOMap.containsKey(Path)) { newTemplateVO = codeClassifyTemplateVOMap.get(Path); codeRuleVO = codeRuleVOVOMap.get(Path); if (newTemplateVO == null || StringUtils.isBlank(newTemplateVO.getOid())) { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类模板"); } if (codeRuleVO == null || StringUtils.isBlank(codeRuleVO.getOid())) { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类规则"); } } else { newTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid()); if (newTemplateVO == null || StringUtils.isBlank(newTemplateVO.getOid())) { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类模板"); } codeRuleVO = engineService.getCodeRuleByClassifyOid(codeClassifyVO.getOid()); if (codeRuleVO == null || StringUtils.isBlank(codeRuleVO.getOid())) { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类规则"); } } if (pathMap.containsKey(Path)) { dataVO = pathDatas.getOrDefault(Path, dataVO); } dataVO.setTemplateOid(newTemplateVO == null ? "" : newTemplateVO.getOid()); dataVO.setCodeClassifyTemplateVO(newTemplateVO); dataVO.setCodeClassifyVO(codeClassifyVO); dataVO.setCodeRuleVO(codeRuleVO); dataVO.setRowIndex(rowIndex); dataVO.setCodeClassifyOid(codeClassifyVO.getOid());//设置分类oid dataVO.setCodeRuleOid(codeRuleVO == null ? "" : codeRuleVO.getOid()); createExeclClassData(titleRowData, newTemplateVO, execlData, dataVO); pathDatas.put(Path, dataVO); codeClassifyTemplateVOMap.put(Path, newTemplateVO); codeRuleVOVOMap.put(Path, codeRuleVO); } else { errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类"); } }); break; } } List newCodeImprotDataVO = pathDatas.values().stream().collect(Collectors.toList()); codeClassifyDatas.addAll(newCodeImprotDataVO); log.info("222"); } /*** * @param titleRowData * @param newTemplateVO * @param execlData * @param codeImprotDataVO */ private void createExeclClassData(List titleRowData, CodeClassifyTemplateVO newTemplateVO, Map execlData, CodeImprotDataVO codeImprotDataVO) { //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = newTemplateVO.getAttributes().stream().filter(s -> !DEFAULT_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); Map attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId())); List fields = new ArrayList<>(); Map filedValueMap = new HashMap<>(); List colNames = new ArrayList<>(); for (int i = 0; i < titleRowData.size(); i++) { String title = titleRowData.get(i); title = title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR, ""); String id = attrNameIdMap.getOrDefault(title, ""); if (StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)) { id = CODE_CLASSIFY_OID_FIELD; } if (StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)) { id = CODE_SEC_LENGTH_FIELD; } if (StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)) { id = CODE_FIELD; } if (StringUtils.isNotBlank(id)) { // fieldIndexMap.put(i,id);id fields.add(id); colNames.add(title); String value = StringUtils.isNotBlank(execlData.get(i)) ? execlData.get(i) : ""; filedValueMap.put(id, value); } } // filedValueMap.put(CODE_CLASSIFY_OID_FIELD,codeImprotDataVO.getCodeClassifyOid());//将当前分类oid存入字段中 filedValueMap.put("codeclassifyid", codeImprotDataVO.getCodeClassifyOid()); filedValueMap.put(IMPORT_ROW_INDEX, codeImprotDataVO.getRowIndex()); filedValueMap.put("codetemplateoid", newTemplateVO.getOid()); codeImprotDataVO.setFields(fields); codeImprotDataVO.setColNames(colNames); codeImprotDataVO.getDatas().add(filedValueMap); } /** * 正确错误数据redis缓存 * * @param uuid * @param templateVO * @param rowIndexCbo * @param dataSet * @param fieldIndexMap * @param errorMap * @param isok */ private void createRedisDatas(String uuid, CodeClassifyTemplateVO templateVO, Map rowIndexCbo, SheetDataSet dataSet, Map fieldIndexMap, Map errorMap, boolean isok) { List needsheetRowDataList = new ArrayList<>(); if (errorMap.size() > 0) { //要把以上的错误的都抛出后,再继续处理时间和组合规则 needsheetRowDataList = dataSet.getRowData().stream().filter(cbo -> { String rowIndex = cbo.getRowIndex(); return isok ? !errorMap.containsKey(rowIndex) : errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); } else { needsheetRowDataList = dataSet.getRowData(); } Map rowIdexDataMap = needsheetRowDataList.stream().collect(Collectors.toMap(s -> s.getRowIndex(), t -> t, (o1, o2) -> o2)); Map clsfDataMap = new HashMap<>(); rowIndexCbo.forEach((rowIndex, cbo) -> { CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO(); codeImprotDataVO.setTemplateOid(templateVO.getOid()); List> dataList = new ArrayList<>(); if (rowIdexDataMap.containsKey(rowIndex)) { SheetRowData sheetRowData = rowIdexDataMap.get(rowIndex); Map dataMap = new HashMap<>(); Map data = sheetRowData.getData(); fieldIndexMap.forEach((integer, s) -> { String field = fieldIndexMap.get(integer); if (data.containsKey(integer)) { String vlues = data.get(integer); dataMap.put(field, vlues); } }); dataMap.put("oid", cbo.getOid()); dataList.add(dataMap); } if (clsfDataMap.containsKey(templateVO.getOid())) { codeImprotDataVO = clsfDataMap.get(templateVO.getOid()); dataList.addAll(codeImprotDataVO.getDatas()); } codeImprotDataVO.setColNames(dataSet.getColName()); codeImprotDataVO.setDatas(dataList); clsfDataMap.put(templateVO.getOid(), codeImprotDataVO); }); if (!CollectionUtils.isEmpty(clsfDataMap)) { Collection codeImprotDataVOS = clsfDataMap.values(); List codeImprotDataVOList = new ArrayList<>(); codeImprotDataVOList.addAll(codeImprotDataVOS); bladeRedis.set(uuid + "-" + templateVO.getOid(), codeImprotDataVOList); bladeRedis.expire(uuid + "-" + templateVO.getOid(), BATCHADD_REDIS_TIME);//redis过期时间 } } /** * 根据编码规则缓存数据 * @param uuid * @param codeImprotDataVOs * @param errorMap * @param isok */ private void createRedisDatas(String uuid, List codeImprotDataVOs, Map errorMap, boolean isok) { codeImprotDataVOs.stream().forEach(codeImprotDataVO -> { List> dataLists = new ArrayList<>(); CodeImprotDataVO newCodeImprotDataVO = new CodeImprotDataVO(); if (errorMap.size() > 0) { //要把以上的错误的都抛出后,再继续处理时间和组合规则 dataLists = codeImprotDataVO.getDatas().stream().filter(cbo -> { String rowIndex = cbo.get(IMPORT_ROW_INDEX); String msg = StringUtils.isBlank(errorMap.get(rowIndex)) ? "" : errorMap.get(rowIndex); cbo.put("errorMsg", msg); return isok ? !errorMap.containsKey(rowIndex) : errorMap.containsKey(rowIndex); }).collect(Collectors.toList()); } else { dataLists = codeImprotDataVO.getDatas(); } BeanUtilForVCI.copyPropertiesIgnoreCase(codeImprotDataVO, newCodeImprotDataVO); newCodeImprotDataVO.setDatas(dataLists); List codeImprotDataVOList = new ArrayList<>(); codeImprotDataVOList.add(newCodeImprotDataVO); /***update 更改成以规则分组*****/ String codeRuleOid = codeImprotDataVO.getCodeRuleOid(); log.info(uuid + "-" + codeRuleOid + ":条目数" + codeImprotDataVOList.size()); if (codeImprotDataVOList.size() > 0) { bladeRedis.set(uuid + "-" + codeRuleOid, codeImprotDataVOList); bladeRedis.expire(uuid + "-" + codeRuleOid, BATCHADD_REDIS_TIME);//redis过期时间 } /*** String codeClassifyOid=codeImprotDataVO.getCodeClassifyOid(); redisService.setCacheList(uuid+"-"+codeClassifyOid,codeImprotDataVOList); logger.info(uuid+"-"+codeClassifyOid+":条目数"+codeImprotDataVOList.size()); redisService.expire(uuid+"-"+codeClassifyOid,BATCHADD_REDIS_TIME);//redis过期时间***/ }); } /** * 数据相似项数据校验redis缓存 * @param codeClassifyOid * @param templateVO * @param cboList * @param resembleMap * @param btmtypeid * @param dataResembleVOS */ private void bathcResembleQuery(String codeClassifyOid, CodeClassifyTemplateVO templateVO, List cboList, Map resembleMap, String btmtypeid, List dataResembleVOS) { CodeClassifyFullInfoBO fullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid); Map conditionMap = new HashMap<>(); CodeResembleRuleVO resembleRuleVO = Optional.ofNullable(engineService.getUseResembleRule(fullInfoBO, fullInfoBO.getCurrentClassifyVO())).orElseGet(() -> new CodeResembleRuleVO()); //需要获取是否有相似查询属性 Map attrVOs = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getSameRepeatAttrFlag())).collect(Collectors.toMap(s -> s.getId(), t -> t)); if (CollectionUtils.isEmpty(attrVOs)) { return; } Map codeImprotResembleVOMap = new HashMap<>(); List codeImprotResembleVOList = new ArrayList<>(); Map rowIndePathMap = new HashMap<>(); cboList.stream().forEach(clientBusinessObject -> { CodeImprotResembleVO codeImprotResembleVO = new CodeImprotResembleVO(); final String[] path = {""}; List fieldList = new ArrayList<>(); List rowIndeList = new ArrayList<>(); String rowIndex = clientBusinessObject.getAttributeValue(IMPORT_ROW_INDEX); attrVOs.forEach((attrId, attrVO) -> { String value = ""; /*if (VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(attrId)) { value = WebUtil.getStringValueFromObject(WebUtil.getValueFromField(WebUtil.getFieldForObject(attrId, orderDTO.getClass()).getName(), orderDTO)); }else {*/ value = clientBusinessObject.getAttributeValue(attrId); // } fieldList.add(attrId); value = StringUtils.isBlank(value) ? "" : value; path[0] += value + "#"; engineService.wrapperResembleConditionMap(value, resembleRuleVO, attrId, conditionMap); }); List> dataMap = new ArrayList<>(); if (codeImprotResembleVOMap.containsKey(path[0])) { codeImprotResembleVO = codeImprotResembleVOMap.get(path[0]); rowIndeList = codeImprotResembleVO.getRownIndex(); dataMap = codeImprotResembleVO.getDataList(); resembleMap.put(rowIndex, "存在相似数据"); } else { if (!CollectionUtils.isEmpty(conditionMap)) { Map andConditionMap = new HashMap<>(); andConditionMap.put("lastr", "1"); andConditionMap.put("lastv", "1"); conditionMap.putAll(andConditionMap); PageHelper pageHelper = new PageHelper(-1); pageHelper.addDefaultDesc("id"); CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(btmtypeid, templateVO, conditionMap, pageHelper); List> dataMapList = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage()); DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true); List resembleCboList = ChangeMapTOClientBusinessObjects(dataMapList); if (!CollectionUtils.isEmpty(resembleCboList)) { List> finalDataMap = dataMap; resembleCboList.stream().forEach(cbo -> { Map resembDataMap = new HashMap<>(); fieldList.stream().forEach(field -> { String value = cbo.getAttributeValue(field); value = StringUtils.isBlank(value) ? "" : value; resembDataMap.put(field, value); }); resembDataMap.put("codetemplateoid", templateVO.getOid()); resembDataMap.put("id", StringUtils.isBlank(cbo.getAttributeValue("id")) ? "" : cbo.getAttributeValue("id")); resembDataMap.put("rowIndex", ""); resembDataMap.put("oid", cbo.getOid()); finalDataMap.add(resembDataMap); }); resembleMap.put(rowIndex, "存在相似数据"); } } } rowIndePathMap.put(rowIndex, path[0]); rowIndeList.add(rowIndex); codeImprotResembleVO.setPath(path[0]); codeImprotResembleVO.setRownIndex(rowIndeList); codeImprotResembleVO.setConditionMap(conditionMap); codeImprotResembleVO.setFields(fieldList); codeImprotResembleVO.setDataList(dataMap); codeImprotResembleVOMap.put(path[0], codeImprotResembleVO); }); Map cboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t)); if (!CollectionUtils.isEmpty(rowIndePathMap)) { rowIndePathMap.forEach((rowIndex, path) -> { if (codeImprotResembleVOMap.containsKey(path)) { CodeImprotResembleVO codeImprotResembleVO = codeImprotResembleVOMap.get(path); List fieldList = codeImprotResembleVO.getFields(); List rownIndexList = codeImprotResembleVO.getRownIndex(); List newRownIndexList = rownIndexList.stream().filter(cbo -> { return rowIndex != cbo; }).collect(Collectors.toList()); newRownIndexList.stream().forEach(s -> { resembleMap.put(s, "存在相似数据"); }); List> newDataList = new ArrayList<>(); DataResembleVO dataResembleVO = new DataResembleVO(); dataResembleVO.setOid(cboMap.get(rowIndex).getOid()); List needSaveCboList = cboList.stream().filter(cbo -> { String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); return rownIndexList.contains(newRowIndex) && (!newRowIndex.equalsIgnoreCase(rowIndex)); }).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(needSaveCboList)) { needSaveCboList.stream().forEach(cbo -> { String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX); Map resembDataMap = new HashMap<>(); fieldList.stream().forEach(field -> { String value = cbo.getAttributeValue(field); value = StringUtils.isBlank(value) ? "" : value; resembDataMap.put(field, value); }); resembDataMap.put("codetemplateoid", templateVO.getOid()); resembDataMap.put("id", StringUtils.isBlank(cbo.getAttributeValue("id")) ? "" : cbo.getAttributeValue("id")); resembDataMap.put("rowIndex", newRowIndex); resembDataMap.put("oid", cbo.getOid()); newDataList.add(resembDataMap); }); } List> dataList = codeImprotResembleVO.getDataList(); newDataList.addAll(dataList); dataResembleVO.setDataList(newDataList); dataResembleVOS.add(dataResembleVO); } }); } } /*** * 存储分类对象及其列名 * @param uuid * @param templateVOList * @param dataSet * @param fieldIndexMap * @param iscContain */ private void createRedisByCodeClassify(String uuid, CodeClassifyTemplateVO templateVOList, SheetDataSet dataSet, Map fieldIndexMap, boolean iscContain) { List columnVOList = new ArrayList<>(); List outNameList = dataSet.getColName(); fieldIndexMap.forEach((integer, s) -> { ColumnVO columnVOS = new ColumnVO(); String field = fieldIndexMap.get(integer); String outName = outNameList.get(integer); columnVOS.setField(field); columnVOS.setTitle(outName); columnVOList.add(columnVOS); }); CodeImportTemplateVO codeImportTemplateVO = new CodeImportTemplateVO(); codeImportTemplateVO.setCodeClassifyTemplateVO(templateVOList); codeImportTemplateVO.setCloNamesList(columnVOList); List codeImportTemplateVOs = new ArrayList<>(); codeImportTemplateVOs.add(codeImportTemplateVO); if (codeImportTemplateVOs.size() > 0) { bladeRedis.set(uuid, codeImportTemplateVOs); bladeRedis.expire(uuid, BATCHADD_REDIS_TIME);//redis过期时间 } } /** * 拷贝业务类型到map * * @param cbo 业务数据 * @param map map */ public static void copyValueToMapFromCbos(ClientBusinessObject cbo, Map map) { if (cbo != null) { copyValueToMapFromBos(cbo, map); } } /** * 拷贝业务类型到map * * @param bo 业务数据 * @param map map */ public static void copyValueToMapFromBos(ClientBusinessObject bo, Map map) { if (bo != null) { //先把所有的字段映射找到 AttributeValue[] newAList = bo.newAttrValList; AttributeValue[] hisAList = bo.hisAttrValList; if (hisAList != null && hisAList.length > 0) {// for (int i = 0; i < hisAList.length; i++) { AttributeValue av = hisAList[i]; String attrName = av.attrName.toLowerCase(); map.put(attrName, av.attrVal); } } if (newAList != null && newAList.length > 0) {//NEW的优先级高些 for (int i = 0; i < newAList.length; i++) { AttributeValue av = newAList[i]; String attrName = av.attrName.toLowerCase(); map.put(attrName, av.attrVal); } } } } /*** * 申请集团编码 * @param idList * @param btmName */ public void sendApplyGroupcode(List idList, String btmName, String operationType) { String oids = VciBaseUtil.array2String(idList.toArray(new String[]{})); if (operationType.equals(sysIntegrationPushTypeEnum.ACCPET_APPCODE.getValue())) { mdmInterJtClient.applyGroupCode(oids, btmName); } else if (operationType.equals(sysIntegrationPushTypeEnum.ACCPET_EDITCODE)) { mdmInterJtClient.receiveEditApply(oids, btmName); } } /*** * @param codeClassifyOid * @return */ @Override public String exportGroupCodeExcel(String codeClassifyOid) throws VciBaseException { VciBaseUtil.alertNotNull(codeClassifyOid, "主题库分类的主键"); CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid); CodeClassifyVO codeClassifyVO = classifyFullInfo.getCurrentClassifyVO(); //获取最新的模板 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid); LinkedList colName = new LinkedList<>();//列头 LinkedList fieldList = new LinkedList<>();//列字段 ExecGroupCodePortDataDTO execGroupCodePortDataDTO = new ExecGroupCodePortDataDTO(); createExportGroupCodeMapConfig(templateVO, execGroupCodePortDataDTO);//组织数据 if (CollectionUtils.isEmpty(execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS())) { throw new VciBaseException("集团属性映射未配置"); } fieldList = execGroupCodePortDataDTO.getFieldList(); List> dataList = new ArrayList<>(); getDatas(classifyFullInfo, templateVO, fieldList, dataList, null); execGroupCodePortDataDTO.setDataList(dataList);//放数据 execGroupCodePortDataDTO.setSheetName(codeClassifyVO.getName() + "集团码导入模板"); String tempFolder = LocalFileUtil.getDefaultTempFolder(); String excelName = tempFolder + File.separator + classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_集团码导出模板.xls"; try { new File(excelName).createNewFile(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e); } LinkedList finalFieldList = fieldList; Map attrVOMap = templateVO.getAttributes().stream().filter(s -> finalFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); List excelDataList = new ArrayList<>(); Workbook workbook = new HSSFWorkbook(); List codeAndGroupCodeAttrMappingDTOList = execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS(); Map jAttrVOMap = codeAndGroupCodeAttrMappingDTOList.stream().filter(s -> finalFieldList.contains(s.getTargetAttrKey().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getTargetAttrKey().toLowerCase(Locale.ROOT), t -> t)); WriteExcelData codeExcelData = new WriteExcelData(0, 0, "企业编码"); WriteExcelData groupExcelData = new WriteExcelData(0, 1, "集团码"); excelDataList.add(codeExcelData); excelDataList.add(groupExcelData); for (int i = 0; i < fieldList.size(); i++) { String attrId = fieldList.get(i); if (attrId.equals(CODE_FIELD) || attrId.equals(CODE_GROUP_FIELD)) { continue; } if (attrVOMap.containsKey(attrId)) { CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId); //Object text = attrVO.getName(); CodeAndGroupCodeAttrMappingDTO codeAttrMappingDTO = jAttrVOMap.get(attrId); Object text = codeAttrMappingDTO.getSourceAttrName(); text = exportKeyAndRequired(workbook, attrVO, text); WriteExcelData excelData = new WriteExcelData(0, i, text); if (text instanceof RichTextString) { excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); } excelDataList.add(excelData); } } final Integer[] rowIndex = {0}; dataList.stream().forEach(data -> { rowIndex[0]++; String id = data.getOrDefault("id", ""); excelDataList.add(new WriteExcelData(rowIndex[0], 0, id)); String groupCode = data.getOrDefault("groupcode", ""); excelDataList.add(new WriteExcelData(rowIndex[0], 1, groupCode)); List newFieldList = finalFieldList.stream().filter(e -> !e.equals("id") && !e.equals("groupcode")).collect(Collectors.toList()); for (int i = 0; i < newFieldList.size(); i++) { String attrId = newFieldList.get(i).toLowerCase(Locale.ROOT); if (attrId.equals("id")) { } else if (attrId.equals("groupcode")) { } else { if (attrVOMap.containsKey(attrId)) { CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId); if (StringUtils.isNotBlank(attrVO.getEnumId()) || StringUtils.isNotBlank(attrVO.getEnumString())) { attrId = attrId + "Text"; } if (StringUtils.isNotBlank(attrVO.getReferBtmId()) || StringUtils.isNotBlank(attrVO.getReferConfig())) { attrId = attrId + "name"; } if (VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attrId)) { attrId = VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT); } excelDataList.add(new WriteExcelData(rowIndex[0], i + 2, data.getOrDefault(attrId, ""))); } } } }); WriteExcelOption excelOption = new WriteExcelOption(); excelOption.addSheetDataList(execGroupCodePortDataDTO.getSheetName(), excelDataList); //增加模板的信息导入 LinkedList tempEDList = new LinkedList<>(); tempEDList.add(new WriteExcelData(0, 0, "模板主键")); tempEDList.add(new WriteExcelData(0, 1, "模板代号")); tempEDList.add(new WriteExcelData(0, 2, "模板名称")); tempEDList.add(new WriteExcelData(1, 0, templateVO.getOid())); tempEDList.add(new WriteExcelData(1, 1, templateVO.getId())); tempEDList.add(new WriteExcelData(1, 2, templateVO.getName())); excelOption.addSheetDataList("模板信息【请勿删除或移动】", tempEDList); ExcelUtil.writeDataToFile(excelName, excelOption); log.info("文件路径" + excelName); return excelName; } /*** * 导入集团码 * @param codeClassifyOid * @param file * @return */ @Override @Transactional(rollbackFor = Exception.class) public String importGroupCode(String codeClassifyOid, File file) throws Throwable { VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键"); ReadExcelOption reo = new ReadExcelOption(); reo.setReadAllSheet(true); List sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo); if (sheetDataSetList.size() > LIMIT + 1) { throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过1万条的数据"); } CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid); //获取最新的模板 CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid); //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); ExecGroupCodePortDataDTO execGroupCodePortDataDTO = new ExecGroupCodePortDataDTO(); createExportGroupCodeMapConfig(templateVO, execGroupCodePortDataDTO);//组织数据 List codeAttrMapGroupAttrDTOS = execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS(); if (CollectionUtils.isEmpty(codeAttrMapGroupAttrDTOS)) { throw new ServiceException("集团属性映射未配置"); } Map codeSystemObjectMap = codeAttrMapGroupAttrDTOS.stream().filter(codeAttrMappingDTO -> codeAttrMappingDTO != null && StringUtils.isNotBlank(codeAttrMappingDTO.getSourceAttrName())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getSourceAttrName(), t -> t)); SheetDataSet dataSet = sheetDataSetList.get(0); List titleRowData = dataSet.getColName(); Map fieldIndexMap = new HashMap<>(); getGroupCodeFieldIndexMap(titleRowData, codeAttrMapGroupAttrDTOS, fieldIndexMap); //需要判断是否所有的属性都在模板上了 /** List unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT)) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getComponentRule()) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去 ).collect(Collectors.toList()); if(!CollectionUtils.isEmpty(unExistAttrVOs)){ String message=unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE)); throw new VciBaseException("【" + message + "】这些属性在excel中没有找到"); }**/ List cboList = new ArrayList<>(); List rowDataList = dataSet.getRowData(); getExportGroupCodeDatas(fieldIndexMap, rowDataList, cboList);//构建数据对象 List codeList = cboList.stream().map(ClientBusinessObject::getId).collect(Collectors.toList()); List> dataList = new ArrayList<>(); Map errorMap = new ConcurrentHashMap<>(); batchSwitchCheckExist(errorMap, cboList, classifyFullInfo, templateVO, execGroupCodePortDataDTO, fieldIndexMap); //判断必输项 batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap); // //优先校验编码是否存在 // batchCheckIdExistOnOrder(templateVO, cboList, errorMap); //boolean reSwitchBooleanAttrOnOrder(attrVOS, cboList); // 枚举的内容需要根据名称转换为枚举的值 batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap); batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap); //6.处理分类注入 batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false); //设置默认值 batchSwitchAttrDefault(attrVOS, cboList); //7.处理组合规则 batchSwitchComponentAttrOnOrder(attrVOS, cboList); //4.校验规则 batchCheckVerifyOnOrder(attrVOS, cboList, errorMap); //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap); //3.判断关键属性 CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, true, errorMap); Set selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList(); Set keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList(); if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) { selfRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";传入的数据中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); // errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";在当前excel文件中关键属性重复"); }); } if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) { keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> { errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo())); // errorMap.put(rowIndex, "关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex, "")); }); } Map> shetNameMap = new HashMap<>(); createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, templateVO); String excelFileName = ""; if (errorMap.size() == 0) { try { String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); List oldCbos = execGroupCodePortDataDTO.getOldList(); List newCbos = new ArrayList<>(); // 修改版次号 engineService.updateBatchByBaseModel(btmTypeId, oldCbos); List codeAllCodeList = new ArrayList<>(); final BladeUser user = AuthUtil.getUser(); cboList.stream().forEach(clientBusinessObject -> { BaseModel newBaseModel = new BaseModel(); DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(clientBusinessObject.getData(), newBaseModel, false, user); newCbos.add(newBaseModel); }); // 插入新的数据 engineService.insertBatchByType(btmTypeId, newCbos); codeAllCodeService.saveOrUpdateBatch(execGroupCodePortDataDTO.getCodeAllCodeList()); engineService.batchSaveSelectChar(templateVO, newCbos); // 记录数据更改日志 saveLogUtil.operateLog("数据更改", false, StringUtil.format("{}\n修改为:\n{}", JSON.toJSONString(oldCbos), JSON.toJSONString(newCbos))); } catch (Exception vciError) { // 记录数据更改报错时的日志 saveLogUtil.operateLog("数据更改", true, vciError.toString()); throw new VciBaseException("数据更改保存出错了", new String[0], vciError); } } else { excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls"; WriteExcelOption eo = new WriteExcelOption(); shetNameMap.forEach((shetName, errorDataList) -> { eo.addSheetDataList(shetName, errorDataList); }); try { new File(excelFileName).createNewFile(); } catch (IOException e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e)); } ExcelUtil.writeDataToFile(excelFileName, eo); } return excelFileName; } public void batchSwitchCheckExist(Map errorMap, List cboList, CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, ExecGroupCodePortDataDTO execGroupCodePortDataDTO, Map fieldIndexMap) { List oldBaseModelList = new ArrayList<>(); List codeAllCodeList = new ArrayList<>(); final BladeUser user = AuthUtil.getUser(); cboList.stream().forEach(clientBusinessObject -> { String code = clientBusinessObject.getId(); String rowIndex = clientBusinessObject.getAttributeValue(IMPORT_ROW_INDEX); List> dataList = new ArrayList<>(); List fieldList = execGroupCodePortDataDTO.getFieldList(); getDatas(classifyFullInfo, templateVO, execGroupCodePortDataDTO.getFieldList(), dataList, Arrays.asList(code)); DefaultAttrAssimtUtil.mapToLowerCase(dataList, true); if (!CollectionUtils.isEmpty(dataList)) { Map newDataMap = new HashMap<>();//将新对象属性暂时存储在Map<> newDataMap.putAll(clientBusinessObject.getData()); Map dataMap = dataList.get(0); BaseModel oldBaseModel = new BaseModel(); DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap, oldBaseModel, false, user); String oldOid = oldBaseModel.getOid(); clientBusinessObject.setCopyFromVersion(oldOid); clientBusinessObject.setAttributeValueWithNoCheck("copyfromversion", oldOid); String oid = VciBaseUtil.getPk(); clientBusinessObject.setOid(oid); clientBusinessObject.setAttributeValueWithNoCheck("oid", oid); clientBusinessObject.setBtmname(oldBaseModel.getBtmname()); clientBusinessObject.setAttributeValueWithNoCheck("btmname", oldBaseModel.getBtmname()); clientBusinessObject.setLastR("1"); clientBusinessObject.setAttributeValueWithNoCheck("lastr", "1"); clientBusinessObject.setFirstR("1"); clientBusinessObject.setAttributeValueWithNoCheck("firstr", "1"); clientBusinessObject.setFirstV("1"); clientBusinessObject.setAttributeValueWithNoCheck("firstv", "1"); clientBusinessObject.setLastV("1"); clientBusinessObject.setAttributeValueWithNoCheck("lastv", "1"); clientBusinessObject.setRevisionSeq(1); clientBusinessObject.setAttributeValueWithNoCheck("revisionseq", "1"); clientBusinessObject.setVersionSeq(1); clientBusinessObject.setAttributeValueWithNoCheck("versionseq", "1"); clientBusinessObject.setRevisionRule(oldBaseModel.getRevisionRule()); clientBusinessObject.setAttributeValueWithNoCheck("revisionrule", oldBaseModel.getRevisionRule()); clientBusinessObject.setVersionRule(oldBaseModel.getRevisionRule()); clientBusinessObject.setAttributeValueWithNoCheck("versionrule", oldBaseModel.getVersionRule()); clientBusinessObject.setVersionValue(oldBaseModel.getVersionValue()); clientBusinessObject.setAttributeValueWithNoCheck("versionvalue", oldBaseModel.getVersionValue()); clientBusinessObject.setLctid(oldBaseModel.getLctid()); clientBusinessObject.setAttributeValueWithNoCheck("lctid", oldBaseModel.getLctid()); clientBusinessObject.setId(oldBaseModel.getId()); clientBusinessObject.setAttributeValueWithNoCheck("id", oldBaseModel.getId()); clientBusinessObject.setName(oldBaseModel.getName()); clientBusinessObject.setAttributeValueWithNoCheck("name", oldBaseModel.getName()); clientBusinessObject.setLcStatus(CodeDefaultLC.RELEASED.getValue()); clientBusinessObject.setAttributeValueWithNoCheck("lcstatus", CodeDefaultLC.RELEASED.getValue()); clientBusinessObject.setDescription("导入集团码"); clientBusinessObject.setAttributeValueWithNoCheck("description", "导入集团码"); clientBusinessObject.setOwner("1"); clientBusinessObject.setAttributeValueWithNoCheck("owner", "1"); clientBusinessObject.setTenantId(AuthUtil.getTenantId()); clientBusinessObject.setAttributeValueWithNoCheck("tenant_id", AuthUtil.getTenantId()); clientBusinessObject.setCreator(oldBaseModel.getCreator()); clientBusinessObject.setAttributeValueWithNoCheck("creator", oldBaseModel.getCreator()); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); clientBusinessObject.setCreateTime(oldBaseModel.getCreateTime()); clientBusinessObject.setAttributeValueWithNoCheck("createtime", formatter.format(oldBaseModel.getCreateTime())); clientBusinessObject.setLastModifier(AuthUtil.getUserAccount()); clientBusinessObject.setAttributeValueWithNoCheck("lastmodifier", AuthUtil.getUserAccount()); clientBusinessObject.setCreateTime(new Date()); clientBusinessObject.setAttributeValueWithNoCheck("lastmodifytime", formatter.format(new Date())); clientBusinessObject.setRevisionValue(String.valueOf(Integer.parseInt(oldBaseModel.getRevisionValue()) + 1)); clientBusinessObject.setRevisionOid(oldBaseModel.getRevisionOid()); clientBusinessObject.setAttributeValueWithNoCheck("revisionoid", oldBaseModel.getRevisionOid()); clientBusinessObject.setAttributeValueWithNoCheck("revisionvalue", String.valueOf(Integer.parseInt(oldBaseModel.getRevisionValue()) + 1)); clientBusinessObject.setNameOid(oldBaseModel.getNameOid()); clientBusinessObject.setAttributeValueWithNoCheck("nameoid", oldBaseModel.getNameOid()); clientBusinessObject.setAttributeValueWithNoCheck(CODE_CLASSIFY_OID_FIELD, oldBaseModel.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD, "")); clientBusinessObject.setAttributeValueWithNoCheck(CODE_FULL_PATH_FILED, oldBaseModel.getData().getOrDefault(CODE_FULL_PATH_FILED, "")); clientBusinessObject.setAttributeValueWithNoCheck(CODE_TEMPLATE_OID_FIELD, oldBaseModel.getData().getOrDefault(CODE_TEMPLATE_OID_FIELD, "")); clientBusinessObject.setTs(new Date()); clientBusinessObject.setAttributeValueWithNoCheck("ts", formatter.format(new Date())); oldBaseModel.setLastV("0"); oldBaseModel.getData().put("lastv", "0"); oldBaseModelList.add(oldBaseModel); List oldCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.query().lambda().eq(CodeAllCode::getId, code)); CodeAllCode codeAllCode = new CodeAllCode(); if (!CollectionUtils.isEmpty(oldCodeAllCodeList)) { codeAllCode = oldCodeAllCodeList.get(0); codeAllCode.setId(code); codeAllCode.setLcStatus(CodeDefaultLC.RELEASED.getValue()); codeAllCode.setCreateCodeOid(clientBusinessObject.getOid()); codeAllCode.setCreateCodeBtm(clientBusinessObject.getBtmname()); codeAllCode.setLastModifyTime(new Date()); codeAllCode.setLastModifier(AuthUtil.getUserAccount()); codeAllCodeList.add(codeAllCode); if (!oldBaseModel.getLcStatus().equals(CodeDefaultLC.RELEASED.getValue()) || !codeAllCode.getLcStatus().equals(CodeDefaultLC.RELEASED.getValue())) { errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中数据不是发布状态"); } } else { errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中未查询到相应的码值数据"); } //除去默认的属性.还有只有表单显示的字段才导入 List attrVOS = templateVO.getAttributes().stream().filter(s -> !fieldIndexMap.containsValue(s.getId()) && ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag())) ).collect(Collectors.toList()); attrVOS.stream().forEach(codeClassifyTemplateAttrVO -> {//将不需要更改的默认字段或者不更改的属性复制到新的版本上 String arrtibuteKey = codeClassifyTemplateAttrVO.getId(); Map attrDataMap = oldBaseModel.getData(); if (attrDataMap.containsKey(arrtibuteKey)) { String arrtibuteValue = attrDataMap.get(arrtibuteKey); clientBusinessObject.setAttributeValueWithNoCheck(arrtibuteKey, arrtibuteValue); } }); } else { errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中未查询到相应的最新版数据"); } }); execGroupCodePortDataDTO.setOldList(oldBaseModelList); execGroupCodePortDataDTO.setCodeAllCodeList(codeAllCodeList); } /** * @param fieldIndexMap * @param rowDataList * @param cboList */ private void getExportGroupCodeDatas(Map fieldIndexMap, List rowDataList, List cboList) { rowDataList.stream().forEach(sheetRowData -> { String rowIndex = sheetRowData.getRowIndex(); ClientBusinessObject cbo = new ClientBusinessObject(); cbo.setAttributeValue(IMPORT_ROW_INDEX, rowIndex); sheetRowData.getData().forEach((index, value) -> { String field = fieldIndexMap.get(index); if (StringUtils.isBlank(field)) { throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在"); } try { cbo.setAttributeValueWithNoCheck(field, value); if (WebUtil.isDefaultField(field)) { WebUtil.setValueToField(field, cbo, value); } } catch (VciBaseException e) { log.error("设置属性的值错误", e); } }); cboList.add(cbo); }); } /*** * 集团导出模板属性映射信息获取 * @param templateVO * @param execGroupCodePortDataDTO */ private void createExportGroupCodeMapConfig(CodeClassifyTemplateVO templateVO, ExecGroupCodePortDataDTO execGroupCodePortDataDTO) { String classOid = templateVO.getCodeclassifyoid(); String templateOid = templateVO.getOid(); R r = mdmInterJtClient.list_mapping(classOid); if (r.isSuccess()) { List dockingPreAttrMappingVOList = (List) r.getData(); List codeAttrMapGroupAttrDTOS = new ArrayList<>(); LinkedList fieldList = new LinkedList<>(); LinkedList colNameList = new LinkedList<>(); dockingPreAttrMappingVOList.stream().forEach(dockingPreAttrMappingVO -> { CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO = new CodeAndGroupCodeAttrMappingDTO(); // TODO:2024/4/16改成用key值判断 if (StringUtils.isNotBlank(dockingPreAttrMappingVO.getTargetAttrKey())) { codeAndGroupCodeAttrMappingDTO.setDefaultValue(dockingPreAttrMappingVO.getDefaultValue()); codeAndGroupCodeAttrMappingDTO.setMetaListId(dockingPreAttrMappingVO.getMetaListId()); codeAndGroupCodeAttrMappingDTO.setSourceAttrKey(dockingPreAttrMappingVO.getSourceAttrKey()); codeAndGroupCodeAttrMappingDTO.setSourceAttrName(dockingPreAttrMappingVO.getSourceAttrName()); codeAndGroupCodeAttrMappingDTO.setTargetAttrId(dockingPreAttrMappingVO.getTargetAttrId()); codeAndGroupCodeAttrMappingDTO.setTargetAttrKey(dockingPreAttrMappingVO.getTargetAttrKey()); codeAndGroupCodeAttrMappingDTO.setTargetAttrName(dockingPreAttrMappingVO.getTargetAttrName()); fieldList.add(dockingPreAttrMappingVO.getTargetAttrKey()); colNameList.add(dockingPreAttrMappingVO.getSourceAttrName()); } codeAttrMapGroupAttrDTOS.add(codeAndGroupCodeAttrMappingDTO); }); execGroupCodePortDataDTO.setCodeAttrMapGroupAttrDTOS(codeAttrMapGroupAttrDTOS); execGroupCodePortDataDTO.setFieldList(fieldList); execGroupCodePortDataDTO.setColName(colNameList); } } /*** * 集团码属性转换 * @param titleRowData * @param codeAttrMapGroupAttrDTOS * @param fieldIndexMap */ private void getGroupCodeFieldIndexMap(List titleRowData, List codeAttrMapGroupAttrDTOS, Map fieldIndexMap) { Map codeSystemObjectMap = codeAttrMapGroupAttrDTOS.stream().filter(codeAttrMappingDTO -> codeAttrMappingDTO != null && StringUtils.isNotBlank(codeAttrMappingDTO.getSourceAttrName())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getSourceAttrName(), t -> t)); for (int i = 0; i < titleRowData.size(); i++) { String title = titleRowData.get(i); String id = ""; if ("集团码".equalsIgnoreCase(title)) { id = CODE_GROUP_FIELD; } if ("企业编码".equalsIgnoreCase(title)) { id = CODE_FIELD; } if (codeSystemObjectMap.containsKey(title)) { CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO = codeSystemObjectMap.get(title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR, "")); id = codeAndGroupCodeAttrMappingDTO.getTargetAttrKey(); } if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)) { fieldIndexMap.put(i, id); } } } /*** * 查询未有集团码的数据 * @param classifyFullInfo * @param templateVO * @param selectFieldList * @param dataList */ private void getDatas(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, LinkedList selectFieldList, List> dataList, List codeList) { //先查询数据 String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId(); String codeClassifyOid = classifyFullInfo.getCurrentClassifyVO().getOid(); Map conditionMap = new HashMap<>(); if (conditionMap == null) { conditionMap = new HashMap<>(); } if (conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)) { conditionMap.put(VciQueryWrapperForDO.OID_FIELD, QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")"); } if (!CollectionUtils.isEmpty(codeList)) { conditionMap.put("id_in", VciBaseUtil.array2String(codeList.toArray(new String[]{}))); } conditionMap.put("codeclsfpath", "*" + codeClassifyOid + "*"); conditionMap.put("groupcode_null", "null"); conditionMap.put("lastr", "1"); conditionMap.put("lastv", "1"); R> listR = btmTypeClient.selectByIdCollection(Arrays.asList(btmTypeId)); String tableName = ""; if (listR.isSuccess() && !listR.getData().isEmpty()) { tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName() : VciBaseUtil.getTableName(btmTypeId); } else { tableName = VciBaseUtil.getTableName(btmTypeId); } PageHelper pageHelper = new PageHelper(); pageHelper.setLimit(1000000); pageHelper.setPage(1); pageHelper.addDefaultDesc("createTime"); DataGrid> dataGrid = engineService.queryGrid(btmTypeId, templateVO, conditionMap, pageHelper); //转换数据 if (!CollectionUtils.isEmpty(dataGrid.getData())) { dataList.addAll(dataGrid.getData()); } //封装查询出来的数据 engineService.wrapperData(dataList, templateVO, selectFieldList, false); //modify by weidy@2022-09-27 //因为在列表和表单的显示的时候,我们的开关类型页面会处理,但是在导出的时候,我们需要将true和false都替换成中文 engineService.wrapperBoolean(dataList, templateVO); log.info("导出模板的数据条目数:" + dataList.size()); } }