Commit 369779a7 authored by wangqiang's avatar wangqiang

功能开发:ICM导入前数据校验

parent 01b18cac
......@@ -71,6 +71,22 @@ public class ExtICMExternalInterfacePlanController<V extends ExtICMExternalInter
return ApiResult.ok(extICMExternalInterfacePlanService.autoImportICMPlan(id),"ICM计划自动导入成功");
}
/**
* 导入ICM计划校验
*
* @param fileId
* @param projectId
* @return
* @throws IOException
*/
@ApiOperation("校验上传的excel中的ICM计划列表是否合法")
@PostMapping(value = "/verifyExcelDataIsValid")
public ApiResult verifyExcelDataIsValid(@RequestParam(value = "fileId",required = true)Long fileId,
@RequestParam(value ="projectId",required = true) String projectId)
throws IOException {
return ApiResult.ok(extICMExternalInterfacePlanService.verifyExcelDataIsValid(fileId,projectId),"校验成功!");
}
}
package com.yonde.dcs.plan.core.listener;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StringUtils;
import com.google.common.collect.Lists;
import com.yonde.dcs.plan.common.constants.Constants;
import com.yonde.dcs.plan.common.vo.ExtICMExternalInterfacePlanVO;
import com.yonde.dcs.plan.common.vo.ExtICMPlanExcelVO;
import com.yonde.dcs.plan.core.service.ExtICMExternalInterfacePlanService;
import com.yonde.dcs.plan.core.util.CommonUtils;
import com.yonde.dex.basedata.data.search.SearchItem;
import com.yonde.dex.basedata.data.search.SearchItems;
import com.yonde.dex.basedata.data.search.SearchQueryCondition;
import com.yonde.dex.basedata.data.search.SortItem;
import com.yonde.dex.basedata.entity.data.DxPageImpl;
import com.yonde.dex.basedata.entity.data.OperatorType;
import com.yonde.dex.basedata.exception.DxBusinessException;
import com.yonde.dex.dao.service.util.ApplicationContextUtil;
import com.yonde.dex.dao.service.util.DxPageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
@Slf4j
public class ICMPlanExcelDataVerifyListenner extends AnalysisEventListener<ExtICMPlanExcelVO> {
private ExtICMExternalInterfacePlanService extICMExternalInterfacePlanService;
/**
* 每隔100条处理下,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<ExtICMPlanExcelVO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
* excel数据行数
*/
private Integer excelDataRow = 2;
/**
* 校验数据的错误信息
*/
List<StringBuffer> errorList = new ArrayList<>();
/**
* 项目id
*/
private String projectId;
/**
* excel操作符集合
*/
List<String> operationList = Arrays.asList(Constants.EXCEL_ADD, Constants.EXCEL_UPDATE, Constants.EXCEL_DELETE);
public ICMPlanExcelDataVerifyListenner() {}
public ICMPlanExcelDataVerifyListenner(String projectId) {
this.extICMExternalInterfacePlanService = ApplicationContextUtil.getBean(ExtICMExternalInterfacePlanService.class);
this.projectId = projectId;
}
@Override
public void invoke(ExtICMPlanExcelVO extICMPlanExcelVO, AnalysisContext analysisContext) {
//判断是否是空数据行
if(!CommonUtils.checkAllPropertiesIsEmpty(extICMPlanExcelVO)){
excelDataRow++;
log.info("解析到一条数据:{}", extICMPlanExcelVO);
//检查excel数据合法性
checkDataForExcel(extICMPlanExcelVO);
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 收尾工作,处理剩下的缓存数据。。。
log.info("sheet={} 所有数据解析完成!", analysisContext.readSheetHolder().getSheetName());
if (errorList.size() > 0) {
throw new DxBusinessException("-1", "ICM计划数据有误!!" + errorList.toString());
}
//数据处理完之后,进行初始化
errorList.clear();
cachedDataList.clear();
excelDataRow = 0;
}
/**
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
log.error("======>>>解析异常:", exception);
throw exception;
}
/**
* 校验excel中的数据是否合法
*
* @param extICMPlanExcelVO excel表格内容对象
*/
public void checkDataForExcel(ExtICMPlanExcelVO extICMPlanExcelVO) {
StringBuffer errorString = new StringBuffer();
//校验数据
if (!StringUtils.isEmpty(extICMPlanExcelVO.getOperation()) && !StringUtils.isEmpty(extICMPlanExcelVO.getPlanNumber())) {
if (!operationList.contains(extICMPlanExcelVO.getOperation())) {
errorString.append("解析到数据第"+excelDataRow+"行文件编号为:" + extICMPlanExcelVO.getPlanNumber() + "的操作符无法识别!!");
errorList.add(errorString);
}
//如果是新增,查看一下数据库中是不是已经存在
if (Constants.EXCEL_ADD.equals(extICMPlanExcelVO.getOperation())) {
ExtICMExternalInterfacePlanVO extICMPlanVO = getICMPlanByPlanNumber(extICMPlanExcelVO.getPlanNumber());
if (!ObjectUtils.isEmpty(extICMPlanVO)) {
errorString.append("解析到数据第"+excelDataRow+"行,新增ICM计划编号:" + extICMPlanExcelVO.getPlanNumber() + "已存在,不能重复添加!");
errorList.add(errorString);
}
} else if (Constants.EXCEL_UPDATE.equals(extICMPlanExcelVO.getOperation())) {
ExtICMExternalInterfacePlanVO extICMPlanForDB = getICMPlanByPlanNumber(extICMPlanExcelVO.getPlanNumber());
String icmState = extICMPlanForDB.getState();
//如果计划不是已发布不能进行升版本 -->release已发布
if(!icmState.equals(Constants.RELEASE)){
errorString.append("解析到数据第"+excelDataRow+"行,更新ICM计划编号:" + extICMPlanExcelVO.getPlanNumber() + "的状态是"+ icmState +",不能进行更新操作!");
errorList.add(errorString);
}
} else {
ExtICMExternalInterfacePlanVO extICMPlanVO = getICMPlanByFileNumberAndDeleted(extICMPlanExcelVO.getPlanNumber());
if (!ObjectUtils.isEmpty(extICMPlanVO) && 1 == extICMPlanVO.getDeleted()) {
errorString.append("解析到数据第"+excelDataRow+"行,ICM计划编号:" + extICMPlanExcelVO.getPlanNumber() + "已被删除,更新或删除失败!");
errorList.add(errorString);
}
}
} else {
errorString.append("解析到数据第"+excelDataRow+",文件编号、操作符均不能为空!!");
errorList.add(errorString);
}
cachedDataList.add(extICMPlanExcelVO);
}
public ExtICMExternalInterfacePlanVO getICMPlanByPlanNumber(String planNumber) {
SortItem sortByModifyTime = new SortItem("createTime", "desc");
SearchItems icmPlanSearch = new SearchItems();
SearchItem numberFilter = new SearchItem("planNumber", SearchItem.Operator.EQ, planNumber, (Object)null);
SearchItem latestFilter = new SearchItem("latest", SearchItem.Operator.EQ, true, (Object)null);
SearchItem projectIdFilter = new SearchItem("dxContextId", SearchItem.Operator.EQ, projectId, (Object)null);
icmPlanSearch.addItem(numberFilter);
icmPlanSearch.addItem(latestFilter);
icmPlanSearch.addItem(projectIdFilter);
SearchQueryCondition searchQuery = SearchQueryCondition.builder().searchItems(icmPlanSearch).sortItem(Lists.newArrayList(new SortItem[]{sortByModifyTime})).build();
//根据计划编码查询出最新版本的计划
DxPageImpl<ExtICMExternalInterfacePlanVO> ICMPlanPage = extICMExternalInterfacePlanService.findRecursion(searchQuery);
if (!CollectionUtils.isEmpty(ICMPlanPage.getContent())) {
ExtICMExternalInterfacePlanVO extICMPlanVOForDB = DxPageUtils.getFirst(ICMPlanPage);
return extICMPlanVOForDB;
} else {
log.info("根据计划的计划编码:{},未查到相关计划", planNumber);
}
return null;
}
/**
* 根据planNumber查询已经删除的计划
* @param planNumber
* @return
*/
private ExtICMExternalInterfacePlanVO getICMPlanByFileNumberAndDeleted(String planNumber) {
SearchQueryCondition condition = SearchQueryCondition.builder()
.searchItems(SearchItems.builder()
.item(new SearchItem("planNumber", SearchItem.Operator.EQ, planNumber, null))
.item(new SearchItem("deleted", SearchItem.Operator.EQ, 1, null))
.build())
.build();
//根据文件编号查询ICM计划
DxPageImpl<ExtICMExternalInterfacePlanVO> ICMPlanPage = extICMExternalInterfacePlanService.findRecursion(condition);
if (!CollectionUtils.isEmpty(ICMPlanPage.getContent())) {
ExtICMExternalInterfacePlanVO extICMPlanVOForDB = DxPageUtils.getFirst(ICMPlanPage);
return extICMPlanVOForDB;
} else {
log.info("根据计划编码:{},未查到已删除的相关计划", planNumber);
}
return null;
}
/**
* 转换数据,将EXCEL对象转换为PO对象
*/
private void transitionObject(ExtICMExternalInterfacePlanVO extICMExternalInterfacePlanVO, ExtICMPlanExcelVO extICMPlanExcelVO) {
extICMExternalInterfacePlanVO.setPlanNumber(extICMPlanExcelVO.getPlanNumber());
extICMExternalInterfacePlanVO.setPublisher(extICMPlanExcelVO.getPublisher());
extICMExternalInterfacePlanVO.setAcceptor(extICMPlanExcelVO.getAcceptor());
extICMExternalInterfacePlanVO.setKeyInterface(extICMPlanExcelVO.getKeyInterface());
extICMExternalInterfacePlanVO.setMilestoneInterface(extICMPlanExcelVO.getMilestoneInterface());
extICMExternalInterfacePlanVO.setInterfaceType(extICMPlanExcelVO.getInterfaceType());
extICMExternalInterfacePlanVO.setPlanOpenDate(extICMPlanExcelVO.getPlanOpenDate());
extICMExternalInterfacePlanVO.setPlanCloseDate(extICMPlanExcelVO.getPlanCloseDate());
extICMExternalInterfacePlanVO.setResponsibilityPerson(extICMPlanExcelVO.getResponsibilityPerson());
extICMExternalInterfacePlanVO.setResponsibilityUnit(extICMPlanExcelVO.getResponsibilityUnit());
extICMExternalInterfacePlanVO.setInterfaceNote(extICMPlanExcelVO.getInterfaceNote());
}
}
......@@ -51,7 +51,7 @@ public class ICMPlanExcelListenner extends AnalysisEventListener<ExtICMPlanExcel
/**
* excel数据行数
*/
private Integer excelDataRow = 0;
private Integer excelDataRow = 2;
/**
......@@ -78,9 +78,10 @@ public class ICMPlanExcelListenner extends AnalysisEventListener<ExtICMPlanExcel
@Override
public void invoke(ExtICMPlanExcelVO extICMPlanExcelVO, AnalysisContext analysisContext) {
excelDataRow++;
//判断是否是空数据行
if(!CommonUtils.checkAllPropertiesIsEmpty(extICMPlanExcelVO)){
excelDataRow++;
log.info("解析到一条数据:{}", extICMPlanExcelVO);
//检查excel数据合法性
checkDataForExcel(extICMPlanExcelVO);
......
......@@ -22,4 +22,6 @@ public interface ExtICMExternalInterfacePlanService<V extends ExtICMExternalInte
String exportICMPlan(HttpServletResponse response, List<String> ids) throws IOException;
String autoImportICMPlan(long id);
public String verifyExcelDataIsValid(Long fileId,String projectId);
}
......@@ -9,7 +9,10 @@ import com.yonde.dcs.document.common.entity.vo.DxDocumentVO;
import com.yonde.dcs.plan.common.constants.Constants;
import com.yonde.dcs.plan.common.vo.ExtICMExternalInterfacePlanVO;
import com.yonde.dcs.plan.common.vo.ExtICMPlanExcelVO;
import com.yonde.dcs.plan.common.vo.ExtPuchasePlanExcelVO;
import com.yonde.dcs.plan.core.listener.ICMPlanExcelDataVerifyListenner;
import com.yonde.dcs.plan.core.listener.ICMPlanExcelListenner;
import com.yonde.dcs.plan.core.listener.PurchasePlanExcelDataVerifyListenner;
import com.yonde.dcs.plan.core.repository.ExtICMExternalInterfacePlanRepository;
import com.yonde.dcs.plan.core.service.ExtICMExternalInterfacePlanService;
import com.yonde.dcs.plan.core.util.FileUtils;
......@@ -29,6 +32,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
......@@ -164,6 +168,25 @@ public class ExtICMExternalInterfacePlanServiceImpl<V extends ExtICMExternalInte
return ApiResult.SUCCESS;
}
@Override
public String verifyExcelDataIsValid(Long fileId, String projectId) {
MultipartFile multipartFile = null;
InputStream inputStream = null;
try {
multipartFile = fileManagerFeignService.feignDownloadIO(fileId);
inputStream = new ByteArrayInputStream(multipartFile.getBytes());
} catch (IOException e) {
throw new DxBusinessException("-1","文件id:"+fileId+"在系统中未找到!");
}
EasyExcel.read(inputStream, ExtPuchasePlanExcelVO.class,
new ICMPlanExcelDataVerifyListenner(projectId))
.sheet()
.doRead();
return ApiResult.SUCCESS;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment