package com.vci.ubcs.code.service.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
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.CodeOrderDTO;
|
import com.vci.ubcs.code.enumpack.CodeDefaultLC;
|
import com.vci.ubcs.code.enumpack.CodeLevelTypeEnum;
|
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.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.web.enumpck.BooleanEnum;
|
import com.vci.ubcs.starter.web.enumpck.VciFieldTypeEnum;
|
import com.vci.ubcs.starter.web.pagemodel.DataGrid;
|
import com.vci.ubcs.starter.web.pagemodel.KeyValue;
|
import com.vci.ubcs.starter.web.pagemodel.PageHelper;
|
import com.vci.ubcs.starter.web.pagemodel.UIFormReferVO;
|
import com.vci.ubcs.starter.web.toolmodel.DateConverter;
|
import com.vci.ubcs.starter.web.util.*;
|
import lombok.AllArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
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.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
|
import javax.annotation.Resource;
|
import java.io.File;
|
import java.io.IOException;
|
import java.util.*;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
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.*;
|
|
@AllArgsConstructor
|
@Service
|
@Slf4j
|
public class MdmIOServiceImpl implements MdmIOService {
|
@Value("${batchadd.redis.time:6000000}")
|
public int BATCHADD_REDIS_TIME;
|
/**
|
* 主题库分类的服务
|
*/
|
@Resource
|
private ICodeClassifyService classifyService;
|
|
/**
|
* 通用查询
|
*/
|
@Resource
|
CommonsMapper commonsMapper;
|
|
/**
|
* 模板的服务
|
*/
|
@Resource
|
private CodeClstemplateServiceImpl templateService;
|
|
/**
|
* 主数据引擎的服务
|
*/
|
@Resource
|
private MdmEngineService engineService;
|
/***
|
* resdis缓存服务
|
*/
|
private final BladeRedis bladeRedis;
|
/**
|
* 生成编码的服务
|
*/
|
@Resource
|
private MdmProductCodeService productCodeService;
|
/**
|
* 关键属性的配置
|
*/
|
@Autowired
|
private ICodeKeyAttrRepeatService keyRuleService;
|
|
/**
|
* 公式的服务
|
*/
|
@Autowired
|
private FormulaServiceImpl formulaService;
|
/**
|
* 生成导入的文件
|
*
|
* @param codeClassifyOid 分类的主键
|
* @param isHistory 是否历史数据导入
|
* @return excel的文件地址
|
*/
|
@Override
|
public String createImportExcel(String codeClassifyOid, boolean isHistory) {
|
List<CodeClassifyTemplateVO> templateVOList=new ArrayList<>();
|
|
VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
|
|
CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
|
|
if(isHistory){
|
templateVOList= templateService.childTemplates(codeClassifyOid);
|
}else{
|
//找模板
|
CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
|
templateVOList.add(templateVO);
|
}
|
|
WriteExcelOption eo = new WriteExcelOption();
|
eo.setAppend(true);
|
//增加模板的信息导入
|
LinkedList<WriteExcelData> 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<CodeClassifyTemplateAttrVO> templateAttrVOS = codeClassifyTemplateVO.getAttributes().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<CodeClassifyTemplateAttrVO> idAttrVOList = codeClassifyTemplateVO.getAttributes().stream().filter(s -> s.getId().equalsIgnoreCase(CODE_FIELD)).collect(Collectors.toList());
|
LinkedList<WriteExcelData> 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():"企业编码"));
|
}
|
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);
|
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<String> enumValueList = new ArrayList<>();
|
enumValueList.add("");
|
List<KeyValue> 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<String> 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 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) {
|
VciBaseUtil.alertNotNull(orderDTO,"编码申请相关的数据",orderDTO.getCodeClassifyOid(),"主题库分类主键");
|
ReadExcelOption reo = new ReadExcelOption();
|
reo.setReadAllSheet(true);
|
List<SheetDataSet> 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<String,String> errorMap = new HashMap<>();
|
String redisUUid=batchImportCodes(orderDTO,templateVO,dataSet,errorMap,true);
|
CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
|
List<String> 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;
|
}
|
|
/**
|
* 错误信息返回excel
|
* @param rowDataList 所有的导入数据
|
* @param errorMap 错误的信息
|
* @param needRowIndexList 需要写入的数据的行号
|
* @param titleRowData 标题行
|
*
|
* @return 错误的excel文件,没有错误会返回空
|
*/
|
private String returnErrorToExcel(Collection<SheetRowData> rowDataList,
|
Map<String,String> errorMap,
|
List<String> needRowIndexList,List<String> titleRowData){
|
if(CollectionUtils.isEmpty(errorMap)){
|
return "";
|
}
|
Map<String, SheetRowData> rowIndexDataMap = rowDataList.stream().filter(s -> !needRowIndexList.contains(s.getRowIndex())).collect(Collectors.toMap(s -> s.getRowIndex(), t -> t));
|
List<WriteExcelData> 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<SheetDataSet> 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<SheetRowData> 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<SheetRowData> 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<String,String> errorMap,boolean isEnumType){
|
List<String> codeList=new ArrayList<>();
|
CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
|
//规则的主键需要去获取
|
CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
|
//1.判断规则中除了流水码段,是否有其他码段
|
engineService.checkSecValueOnOrder(ruleVO,orderDTO);
|
List<SheetRowData> rowDataList = dataSet.getRowData();
|
|
//除去默认的属性.还有只有表单显示的字段才导入
|
List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
|
!DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
|
).collect(Collectors.toList());
|
Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
|
List<String> titleRowData = dataSet.getColName();
|
Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
|
getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
|
|
//需要判断是否所有的属性都在模板上了
|
List<CodeClassifyTemplateAttrVO> 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<ClientBusinessObject> 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);
|
Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
|
Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
|
if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
|
selfRepeatRowIndexList.stream().forEach(rowIndex->{
|
errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";在当前处理的数据文件中关键属性重复" );
|
});
|
}
|
if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
|
keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
|
errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
|
});
|
}
|
//分类注入
|
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);
|
String uuid=VciBaseUtil.getPk();
|
Map<String, ClientBusinessObject> 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<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
|
String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
|
return !errorMap.containsKey(rowIndex);
|
}).collect(Collectors.toList());
|
//相似校验
|
Map<String,String>resembleMap=new HashMap<>();
|
List<DataResembleVO> dataResembleVOS=new ArrayList<>();
|
String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmtypeid();
|
bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
|
if(resembleMap.size()>0) {
|
isCreateUUid=true;
|
if(!CollectionUtils.isEmpty(dataResembleVOS)) {
|
bladeRedis.set(uuid + "-resemble-data", dataResembleVOS);
|
createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
|
}
|
}
|
//排除错误的,剩下正确的
|
Map<String,String> 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="";
|
|
//要把以上的错误的都抛出后,再继续处理时间和组合规则
|
/*dataCBOList = cboList.stream().filter(cbo -> {
|
String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
|
return !newErrorMap.containsKey(rowIndex);
|
}).collect(Collectors.toList());
|
*/ List<String> dataCBOIdList=new ArrayList<>();
|
List<BaseModel> 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());
|
});
|
|
if (!CollectionUtils.isEmpty(needSaveCboList)) {
|
//9.我们处理业务数据
|
//生成编码的内容
|
try {
|
codeList = productCodeService.productCodeAndSaveData(classifyFullInfo,templateVO,ruleVO, orderDTO.getSecDTOList(),dataCBOList);
|
//如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
|
engineService.batchSaveSelectChar(templateVO, dataCBOIdList);
|
} catch (Exception e) {
|
e.printStackTrace();
|
log.error("批了申请时失败");
|
}
|
}
|
}
|
if(!isCreateUUid){
|
return uuid="";
|
}
|
return uuid;
|
}
|
|
@Override
|
public List<CodeImportTemplateVO> gridclassifys(String redisOid) {
|
List<CodeImportTemplateVO> codeImportTemplateVOs=new ArrayList<>();
|
VciBaseUtil.alertNotNull(redisOid,"分类",redisOid,"分类缓存主键");
|
|
List<CodeImportTemplateVO> redisServiceCacheObjects=bladeRedis.lRange(redisOid,0,-1);
|
if(redisServiceCacheObjects!=null){
|
codeImportTemplateVOs= redisServiceCacheObjects;
|
}
|
return codeImportTemplateVOs;
|
}
|
|
/***
|
* 从缓存里获取到需要导入的相关数据
|
* @param codeClssifyOid
|
* @param redisOid
|
* @return
|
*/
|
@Override
|
public DataGrid<Map<String, String>> gridDatas(String codeClssifyOid, String redisOid) {
|
VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
|
List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.lRange(redisOid+"-"+codeClssifyOid,0,-1);
|
// redisService.getCacheList(redisOid+"-"+codeClssifyOid);
|
CodeImprotDataVO codeImprotDataVO=new CodeImprotDataVO();
|
if(!CollectionUtils.isEmpty(codeImprotDataVOs)){
|
if(StringUtils.isNotBlank(codeClssifyOid)){
|
Map<String/**分类名称**/, CodeImprotDataVO/**英文名称**/> 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<Map<String, String>> dataGrid = new DataGrid<>();
|
List<Map<String, String>> 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<Map<String,String>> gridRowResemble(String oid,String redisOid){
|
VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
|
List<DataResembleVO> codeImprotDataVOs = bladeRedis.lRange(redisOid,0,-1);;
|
DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
|
List<Map<String, String>> dataList = new ArrayList<>();
|
|
if(!CollectionUtils.isEmpty(codeImprotDataVOs)){
|
Map<String/**分类名称**/, DataResembleVO/**数据对象**/> 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 orderDTO 分类的主键
|
* @param dataObjectVO 数据信息
|
* @param resultDataObjectDetailDOs 错误信息
|
* @return 有错误信息的excel
|
*/
|
@Override
|
public void batchSyncApplyCode(CodeOrderDTO orderDTO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs) {
|
Map<String,String> errorMap=new HashMap<>();
|
VciBaseUtil.alertNotNull(orderDTO,"编码申请相关的数据",orderDTO.getCodeClassifyOid(),"主题库分类主键");
|
CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
|
//规则的主键需要去获取
|
CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
|
//1.判断规则中除了流水码段,是否有其他码段
|
//engineService.checkSecValueOnOrder(ruleVO,orderDTO);
|
//查询分类和模板
|
//先找到每一行的标题,然后根据标题来获取对应的属性
|
List<RowDatas> rowDataList = dataObjectVO.getRowData();
|
Map<String , RowDatas>rowDataMap=new LinkedHashMap<>();
|
rowDataList.stream().forEach(rowData->{
|
rowDataMap.put(rowData.getRowIndex(),rowData);
|
});
|
//找第一行,为了找标题
|
CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
|
|
//校验模板是不是最新的
|
//checkTemplateSync(sheetDataSetList,templateVO);
|
//除去默认的属性.还有只有表单显示的字段才导入
|
List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->!DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
|
).collect(Collectors.toList());
|
Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
|
List<String> titleRowData = dataObjectVO.getColName();
|
Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
|
getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
|
|
//需要判断是否所有的属性都在模板上了
|
List<CodeClassifyTemplateAttrVO> 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)){
|
throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在excel中没有找到");
|
}
|
|
String fullPath = getFullPath(classifyFullInfo);
|
|
// List<CodeClassifyProcessTempVO> codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order");
|
boolean isProcess=false;
|
//注释掉此处下面所有都按照不判断流程存储状态了
|
/** if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){
|
isProcess=true;
|
}***/
|
//List<ClientBusinessObject> cboList = new ArrayList<>();
|
//Map<String,String> codeOidToSystemOidMap=new HashMap<>();//存储编码数据和集成系统数据oid对照映射
|
//excelToCbo(classifyFullInfo,titleRowData,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,isProcess,"create",errorMap,codeOidToSystemOidMap);
|
|
//都转换完了。需要批量检查
|
//如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
|
//2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
|
|
}
|
|
@Override
|
public void batchSyncEditDatas(CodeClassifyVO codeClassifyVO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs) {
|
|
}
|
|
/**
|
* 获取分类的全路径
|
* @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;
|
}
|
|
/**
|
* excel转换为cbo的对象
|
* @param classifyFullInfo 分类的全部信息
|
* @param fieldIndexMap 字段的位置
|
* @param rowDataList excel里的行数据
|
* @param templateVO 模板的显示对象
|
* @param cboList 数据的列表
|
* @param fullPath 全路径
|
* @param newCode 是否为批量申请
|
*/
|
private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo,Map<Integer,String> fieldIndexMap,List<SheetRowData> rowDataList,
|
CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,
|
String fullPath,boolean newCode){
|
rowDataList.stream().forEach(rowData -> {
|
ClientBusinessObject cbo=new ClientBusinessObject();
|
DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmtypeid());
|
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) ){
|
Integer userSecret = VciBaseUtil.getCurrentUserSecret();
|
cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
|
}*/
|
}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);
|
});
|
|
}
|
|
/**
|
* 检查校验规则没有通过的内容
|
* @param attrVOS 需要校验的属性
|
* @param dataList 数据的列表
|
* @param errorMap 错误的信息映射
|
* @return 校验不通过的行数
|
*/
|
private void batchCheckVerifyOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList,Map<String,String> errorMap) {
|
Map<String, CodeClassifyTemplateAttrVO> 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<String/**行号**/,List<String>/**校验不通过的属性**/> 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<String> 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<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
|
Map<String, CodeClassifyTemplateAttrVO> 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() + "]时间格式不正确" );
|
}
|
}
|
}
|
});
|
});
|
}
|
}
|
/**
|
* 转移boolean型的属性
|
* @param attrVOS 属性的对象
|
* @param dataList 数据
|
*/
|
private void reSwitchBooleanAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList){
|
Map<String, CodeClassifyTemplateAttrVO> 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<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList) {
|
Map<String, CodeClassifyTemplateAttrVO> 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<String,String> 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<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,Map<String,String> errorMap){
|
Map<String, CodeClassifyTemplateAttrVO> 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<String/**表格和值的属性**/,Map<String/**显示属性的值**/,List<String>/**表格里的值**/>> 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<String, List<String>> showTextMap = linkValueMap.getOrDefault(tableAndAttr, new HashMap<>());
|
List<String> 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<String/**表格和值属性**/,Map<String/**显示属性**/, Map<String/**值**/,String/**显示的值**/>>> linkCboMap = new HashMap<>();
|
linkValueMap.forEach((tableAndAttr,showValueMap)->{
|
String[] split = tableAndAttr.split("#");
|
String table = split[0];
|
String valueField = split[1].toLowerCase(Locale.ROOT);
|
Map<String,Map<String,String>> dataMap = new HashMap<>();
|
showValueMap.forEach((showText,valueList)->{
|
Map<String,String> valueOidTextMap = new HashMap<>();
|
List<List<String>> valueCollections = VciBaseUtil.switchListForOracleIn(valueList);
|
String sql = "select " + valueField + "," + showText.toLowerCase(Locale.ROOT) +" from " + table + " where " + showText + " in (%s)";
|
valueCollections.stream().forEach(values->{
|
List<Map<String,String>> dataMapList = commonsMapper.queryByOnlySqlForMap(String.format(sql, VciBaseUtil.toInSql(values.toArray(new String[0]))));
|
List<ClientBusinessObject> 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<String, Map<String, String>> 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<String, String> 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 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<String> 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<String> 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<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
|
Map<String,String> errorMap ) {
|
Map<String, CodeClassifyTemplateAttrVO> 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<KeyValue> 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<ClientBusinessObject> cboList,Map<String,String> errorMap){
|
Map<String, CodeClassifyTemplateAttrVO> requiredAttrMap = templateVO.getAttributes().stream().filter(s ->
|
VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeLevel())//不能是组合的和分类注入的
|
).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
|
//与MdmEngineServiceImpl里面的checkRequiredAttrOnOrder 逻辑应该相似
|
if(!CollectionUtils.isEmpty(requiredAttrMap)) {
|
Set<String> 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<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
|
CodeClassifyFullInfoBO classifyFullInfo,boolean isImPort) {
|
Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(
|
s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr()) && StringUtils.isNotBlank(s.getClassifyInvokeAttr())
|
).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
|
Map<String,CodeClassifyFullInfoBO> 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<CodeClassifyVO> 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<String, String> classifyDataMap = VciBaseUtil.objectToMapString(classifyVO);
|
String value = classifyDataMap.getOrDefault(attrVO.getClassifyInvokeAttr(), "");
|
cbo.setAttributeValue(attrId, value);
|
}
|
} catch (Throwable e) {
|
log.error("设置属性错误", e);
|
}
|
});
|
});
|
}
|
}
|
/**
|
* 校验关键属性
|
* @param classifyFullInfo 分类的全部信息
|
* @param templateVO 模板的内容,必须包含模板属性
|
* @param cboList 批量的数据
|
*/
|
private CodeImportResultVO batchCheckKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO,
|
List<ClientBusinessObject> cboList) {
|
//与MdmEngineServiceImpl里的checkKeyAttrOnOrder相似
|
//先获取关键属性的规则,也利用继承的方式
|
CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo);
|
//注意的是keyRuleVO可能为空,表示不使用规则控制
|
//获取所有的关键属性
|
Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
|
|
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();
|
resultVO.setKeyAttrRuleInfo(String.format(keyRuleVO ==null?"":"查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}",
|
new String[]{trim?"是":"否",ignoreCase?"是":"否",ignoreWidth?"是":"否",trimAll?"是":"否"}));
|
resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO));
|
if(!CollectionUtils.isEmpty(resultVO.getSelfRepeatRowIndexList())){
|
//我们移除本身重复的数据
|
cboList = cboList.stream().filter(s->!resultVO.getSelfRepeatRowIndexList().contains(s.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
|
}
|
//2.判断关键属性在系统里是否重复
|
//因为数据量很大,所以得想办法并行
|
//SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
|
Map<String,List<ClientBusinessObject>> indexTODataMap=new HashMap<>();
|
List<ClientBusinessObject> repeatDataMap = cboList.parallelStream().filter(cbo -> {
|
//每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示
|
//VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
|
Map<String, String> conditionMap = new HashMap<>();
|
ketAttrMap.forEach((attrId, attrVO) -> {
|
String value =cbo.getAttributeValue(attrId.toLowerCase(Locale.ROOT));
|
if (value == null) {
|
value = "";
|
}
|
value= value.replace(REQUIRED_CHAR,SPECIAL_CHAR);
|
engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
|
});
|
if (!CollectionUtils.isEmpty(ketAttrMap)) {
|
CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmtypeid(), templateVO, conditionMap, null);
|
boolean isKeyCheck= commonsMapper.queryCountBySql(sqlBO.getSqlCount()) > 0;
|
if(isKeyCheck){
|
List<Map<String,String>> newDataList= commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
|
List<ClientBusinessObject> newCboList= ChangeMapTOClientBusinessObjects(newDataList);
|
indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX),newCboList);
|
}
|
return isKeyCheck;
|
}else{
|
return false;
|
}
|
}).collect(Collectors.toList());
|
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 ketAttrMap 关键属性的映射
|
* @param dataList 导入的数据
|
* @param keyRuleVO 关键属性控制规则
|
* @return 重复的行号
|
*/
|
private Set<String> getSelfRepeatRowIndex(Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap,
|
List<ClientBusinessObject> dataList,CodeKeyAttrRepeatVO keyRuleVO){
|
Set<String> selfRepeatRowIndexList = new CopyOnWriteArraySet<>();
|
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<CodeClassifyTemplateAttrVO> attrVOList = ketAttrMap.values().stream().sorted(((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()))).collect(Collectors.toList());
|
Map<String/**行号**/,String/**关键属性的组合内容**/> rowIndexKeyStringMap = new HashMap<>();
|
dataList.parallelStream().forEach(cbo-> {
|
String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
|
StringBuilder sb = new StringBuilder();
|
for (int i = 0; i < attrVOList.size(); i++) {
|
CodeClassifyTemplateAttrVO attrVO = attrVOList.get(i);
|
String attrId = attrVO.getId().toLowerCase(Locale.ROOT);
|
String value = cbo.getAttributeValue( attrId);
|
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);
|
}
|
sb.append(value).append("${ks}");
|
}
|
String keyString = sb.toString();
|
if(rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)){
|
selfRepeatRowIndexList.add(rowIndex);
|
}else {
|
rowIndexKeyStringMap.put(rowIndex, sb.toString());
|
}
|
});
|
//因为只是关键属性重复,所以我们不能重复的多条选一条来报错
|
return selfRepeatRowIndexList;
|
}
|
/**
|
* excel的标题上获取字段所在的位置
|
* @param titleRowData 标题的内容
|
* @param attrNameIdMap 模板中属性名称和英文的映射
|
* @param fieldIndexMap 位置和英文字段的映射
|
*/
|
private void getFieldIndexMap(List<String> titleRowData,Map<String/**名称**/,String/**字段名**/> attrNameIdMap,Map<Integer/**位置**/,String/**英文名字**/> 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<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String,String>> oldDataMap){
|
List<ClientBusinessObject> clientBusinessObjectList=new CopyOnWriteArrayList<>();
|
oldDataMap.parallelStream().forEach(dataMap->{
|
ClientBusinessObject clientBusinessObject=new ClientBusinessObject();
|
DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap,clientBusinessObject);
|
dataMap.forEach((key,value)->{
|
clientBusinessObject.setAttributeValue(key,value);
|
});
|
});
|
return clientBusinessObjectList;
|
}
|
|
/***
|
* 正确错误数据redis缓存
|
* @param uuid
|
* @param templateVO
|
* @param rowIndexCbo
|
* @param dataSet
|
* @param fieldIndexMap
|
* @param errorMap
|
* @param isok
|
*/
|
private void createRedisDatas(String uuid,CodeClassifyTemplateVO templateVO,Map<String,ClientBusinessObject> rowIndexCbo, SheetDataSet dataSet, Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,Map<String,String> errorMap,boolean isok){
|
List<SheetRowData> 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<String/**中文名称**/, SheetRowData/**英文名称**/> rowIdexDataMap = needsheetRowDataList.stream().collect(Collectors.toMap(s -> s.getRowIndex(), t -> t,(o1, o2)->o2));
|
Map<String,CodeImprotDataVO> clsfDataMap=new HashMap<>();
|
rowIndexCbo .forEach((rowIndex, cbo) -> {
|
CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO();
|
codeImprotDataVO.setTemplateOid(templateVO.getOid());
|
List<Map<String, String>> dataList = new ArrayList<>();
|
if(rowIdexDataMap.containsKey(rowIndex)){
|
SheetRowData sheetRowData=rowIdexDataMap.get(rowIndex);
|
Map<String, String> dataMap = new HashMap<>();
|
Map<Integer, String> 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<CodeImprotDataVO> codeImprotDataVOList=new ArrayList<>();
|
codeImprotDataVOList.addAll(codeImprotDataVOS);
|
bladeRedis.set(uuid+"-"+templateVO.getOid(), codeImprotDataVOList);
|
bladeRedis.expire(uuid+"-"+templateVO.getOid(),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<ClientBusinessObject> cboList,Map<String,String>resembleMap,String btmtypeid,List<DataResembleVO> dataResembleVOS){
|
CodeClassifyFullInfoBO fullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid);
|
Map<String, String> conditionMap = new HashMap<>();
|
CodeResembleRuleVO resembleRuleVO = Optional.ofNullable(engineService.getUseResembleRule(fullInfoBO, fullInfoBO.getCurrentClassifyVO())).orElseGet(() -> new CodeResembleRuleVO());
|
//需要获取是否有相似查询属性
|
Map<String, CodeClassifyTemplateAttrVO> attrVOs = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getSameRepeatAttrFlag())).collect(Collectors.toMap(s -> s.getId(), t -> t));
|
if (CollectionUtils.isEmpty(attrVOs)) {
|
return;
|
}
|
Map<String,CodeImprotResembleVO> codeImprotResembleVOMap=new HashMap<>();
|
List<CodeImprotResembleVO> codeImprotResembleVOList=new ArrayList<>();
|
Map<String,String> rowIndePathMap=new HashMap<>();
|
cboList.stream().forEach(clientBusinessObject -> {
|
CodeImprotResembleVO codeImprotResembleVO=new CodeImprotResembleVO();
|
final String[] path = {""};
|
List<String> fieldList=new ArrayList<>();
|
List<String> 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<Map<String,String>> 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<String, String> andConditionMap = new HashMap<>();
|
andConditionMap.put("islastr", "1");
|
andConditionMap.put("islastv", "1");
|
conditionMap.putAll(andConditionMap);
|
PageHelper pageHelper = new PageHelper(-1);
|
pageHelper.addDefaultDesc("id");
|
CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(btmtypeid, templateVO, conditionMap, pageHelper);
|
List<Map<String,String>> dataMapList=commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
|
List<ClientBusinessObject> resembleCboList= ChangeMapTOClientBusinessObjects(dataMapList);
|
if(!CollectionUtils.isEmpty(resembleCboList)) {
|
List<Map<String, String>> finalDataMap = dataMap;
|
resembleCboList.stream().forEach(cbo->{
|
Map<String,String> 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<String, ClientBusinessObject> 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<String> fieldList=codeImprotResembleVO.getFields();
|
List<String> rownIndexList= codeImprotResembleVO.getRownIndex();
|
List<String> newRownIndexList = rownIndexList.stream().filter(cbo -> {
|
return rowIndex!=cbo;
|
}).collect(Collectors.toList());
|
newRownIndexList.stream().forEach(s -> {
|
resembleMap.put(s, "存在相似数据");
|
});
|
List<Map<String, String>>newDataList=new ArrayList<>();
|
DataResembleVO dataResembleVO=new DataResembleVO();
|
dataResembleVO.setOid(cboMap.get(rowIndex).getOid());
|
List<ClientBusinessObject> 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<String, String> 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<Map<String, String>>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<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,boolean iscContain){
|
List<ColumnVO> columnVOList = new ArrayList<>();
|
List<String> 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<CodeImportTemplateVO> 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<String,String> map){
|
if(cbo!=null){
|
copyValueToMapFromBos(cbo,map);
|
}
|
}
|
|
/**
|
* 拷贝业务类型到map
|
* @param bo 业务数据
|
* @param map map
|
*/
|
public static void copyValueToMapFromBos(ClientBusinessObject bo,Map<String,String> 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);
|
}
|
}
|
}
|
}
|
}
|