Browse Source

工单批量上传优化

ops-management-platform-backend-dev
gjh 4 days ago
parent
commit
ff1d0328c4
  1. 31
      ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/controller/ExcelController.java
  2. 97
      ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/listener/WorkOrderInfoListener.java

31
ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/controller/ExcelController.java

@ -5,6 +5,7 @@ import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.platform.domain.bo.PointInfoBo; import org.dromara.platform.domain.bo.PointInfoBo;
import org.dromara.platform.domain.bo.WorkOrderInfoBo; import org.dromara.platform.domain.bo.WorkOrderInfoBo;
import org.dromara.platform.domain.vo.PointInfoVo; import org.dromara.platform.domain.vo.PointInfoVo;
@ -100,11 +101,33 @@ public class ExcelController {
@PostMapping("/uploadWorkOrderInfo") @PostMapping("/uploadWorkOrderInfo")
public void uploadWorkOrderInfo(MultipartFile file, HttpServletResponse response) throws IOException { public void uploadWorkOrderInfo(MultipartFile file, HttpServletResponse response) throws IOException {
long t1 = System.currentTimeMillis(); long t1 = System.currentTimeMillis();
// 业务层
EasyExcel.read(file.getInputStream(), WorkOrderInfoVo.class, new WorkOrderInfoListener(workOrderInfoService,contractInfoService)).sheet().doRead(); WorkOrderInfoListener listener = new WorkOrderInfoListener(workOrderInfoService, contractInfoService);
response.setContentType("text/html;charset=utf8");
try {
// 开始读取 Excel 文件
EasyExcel.read(file.getInputStream(), WorkOrderInfoVo.class, listener)
.sheet()
.doRead();
// ✅ 提前检查错误信息,若有则直接抛出异常
if (!listener.getErrorMessages().isEmpty()) {
throw new ServiceException("部分数据导入失败:" + listener.getErrorMessages());
}
// ⬇️ 只有在没有错误的情况下才执行以下内容
long t2 = System.currentTimeMillis(); long t2 = System.currentTimeMillis();
response.setContentType("text/html;charset=utf8");
response.getWriter().println("导入数据成功!,共用时:" + (t2 - t1) + "ms"); response.getWriter().println("导入数据成功!,共用时:" + (t2 - t1) + "ms");
log.info("批量点位上报成功! 共用时:{}ms",(t2-t1)); log.info("工单数据导入完成,共用时:{}ms", (t2 - t1));
} catch (Exception e) {
log.error("导入失败", e);
// 系统异常:部分数据导入失败:[第 19 行数据导入失败:合同名称不存在:2023年江北区1812路公共视频监控服务项目(盈力222)]
throw new ServiceException("导入失败:" + e.getMessage());
} finally {
// 清空错误信息
listener.clearErrors();
}
} }
} }

97
ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/listener/WorkOrderInfoListener.java

@ -19,6 +19,7 @@ import org.springframework.context.annotation.Bean;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,30 +31,26 @@ import java.util.stream.Collectors;
*/ */
@Slf4j @Slf4j
public class WorkOrderInfoListener implements ReadListener<WorkOrderInfoVo> { public class WorkOrderInfoListener implements ReadListener<WorkOrderInfoVo> {
private List<WorkOrderInfo> list = new ArrayList<>(); // 错误信息收集
@Resource private final List<String> errorMessages = new ArrayList<>();
private IWorkOrderInfoService workOrderInfoService;
@Resource // 合同名称列表
private IContractInfoService contractInfoService; private final List<String> contractNames;
// 为什么会失效
private List<String> contractNames;
// 服务依赖由外部传入
private final IWorkOrderInfoService workOrderInfoService;
private final IContractInfoService contractInfoService;
/** /**
* 自己定义一个缓冲量 * 构造函数传入 service并初始化合同名称
*/ */
private static final int BATCH_COUNT = 10;
public WorkOrderInfoListener(IWorkOrderInfoService workOrderInfoService, public WorkOrderInfoListener(IWorkOrderInfoService workOrderInfoService,
IContractInfoService contractInfoService) { IContractInfoService contractInfoService) {
this.workOrderInfoService = workOrderInfoService; this.workOrderInfoService = workOrderInfoService;
this.contractInfoService = contractInfoService; this.contractInfoService = contractInfoService;
contractNames = loadContractNames(); this.contractNames = loadContractNames();
} }
// 获取系统中全部合同名称
private List<String> loadContractNames() { private List<String> loadContractNames() {
List<ContractSelectVo> contractSelectVoList = contractInfoService.getNames(); List<ContractSelectVo> contractSelectVoList = contractInfoService.getNames();
return contractSelectVoList.stream() return contractSelectVoList.stream()
@ -61,52 +58,64 @@ public class WorkOrderInfoListener implements ReadListener<WorkOrderInfoVo> {
.toList(); .toList();
} }
/**
* 每读一行数据都会调用这个方法
*
* @param workOrderInfoVo
* @param analysisContext
*/
@Override @Override
public void invoke(WorkOrderInfoVo workOrderInfoVo, AnalysisContext analysisContext) { public void invoke(WorkOrderInfoVo workOrderInfoVo, AnalysisContext analysisContext) {
try {
WorkOrderInfo info = new WorkOrderInfo(); WorkOrderInfo info = new WorkOrderInfo();
BeanUtils.copyProperties(workOrderInfoVo, info, "id"); BeanUtils.copyProperties(workOrderInfoVo, info, "id");
String unit = contractInfoService.getIoCompany(info.getContractName());
String contractName = info.getContractName();
if (contractName == null || contractName.trim().isEmpty()) {
throw new IllegalArgumentException("合同名称为空");
}
if (contractNames.contains(contractName)) {
String unit = contractInfoService.getIoCompany(contractName);
if (unit != null) { if (unit != null) {
info.setMaintenanceUnit(unit); info.setMaintenanceUnit(unit);
} }
info.setRepairTime(new Date()); info.setRepairTime(new Date());
// 创建工单
// 如果用户填写的合同名称与系统中的合同名称匹配则进行派遣操作 WorkOrderInfoBo convert = BeanUtil.copyProperties(info, WorkOrderInfoBo.class);
if (contractNames.contains(info.getContractName())){
list.add(info);
// 判断是否到达缓存量了
if (list.size() >= BATCH_COUNT){
// 操作数据库
list.forEach(item -> {
WorkOrderInfoBo convert = BeanUtil.copyProperties(item, WorkOrderInfoBo.class);
workOrderInfoService.insertByBo(convert); workOrderInfoService.insertByBo(convert);
});
// 清空集合,并准备下一批数据的批量插入
list = new ArrayList<>(BATCH_COUNT);
}
} else { } else {
log.error("点位:{} 上报失败--->合同名称不存在:{}",info.getFaultLocation(),info.getContractName()); throw new IllegalArgumentException("合同名称不存在:" + contractName);
}
} catch (Exception e) {
int rowNum = analysisContext.readRowHolder().getRowIndex();
String errorMsg = String.format("第 %d 行数据导入失败:%s", rowNum, e.getMessage());
log.error(errorMsg, e);
errorMessages.add(errorMsg);
} }
} }
/**
* 读完整个excel之后再调用这个方法
*
* @param analysisContext
*/
@Override @Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) { public void doAfterAllAnalysed(AnalysisContext analysisContext) {
if (list.size()>0){ // 所有数据处理完成,无需特殊操作
list.forEach(item -> { }
WorkOrderInfoBo convert = BeanUtil.copyProperties(item, WorkOrderInfoBo.class);
workOrderInfoService.insertByBo(convert); /**
}); * 获取所有错误信息
*/
public List<String> getErrorMessages() {
return Collections.unmodifiableList(errorMessages);
} }
/**
* 是否存在错误
*/
public boolean hasErrors() {
return !errorMessages.isEmpty();
}
/**
* 清空错误信息
*/
public void clearErrors() {
errorMessages.clear();
} }
} }

Loading…
Cancel
Save