diff --git a/nflg_project_dev/material/src/main/java/com/nflg/product/material/api/user/material/MaterialUpdateBillApi.java b/nflg_project_dev/material/src/main/java/com/nflg/product/material/api/user/material/MaterialUpdateBillApi.java index 69c391a8..244adbae 100644 --- a/nflg_project_dev/material/src/main/java/com/nflg/product/material/api/user/material/MaterialUpdateBillApi.java +++ b/nflg_project_dev/material/src/main/java/com/nflg/product/material/api/user/material/MaterialUpdateBillApi.java @@ -4,9 +4,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.product.base.core.api.BaseApi; import com.nflg.product.base.core.exception.NflgBusinessException; import com.nflg.product.material.pojo.dto.MaterialStateUpExcelDTO; -import com.nflg.product.material.pojo.dto.TwentyMaterialTemplateExcelDTO; import com.nflg.product.material.pojo.dto.MaterialUpdateBillDTO; +import com.nflg.product.material.pojo.dto.TwentyMaterialTemplateExcelDTO; import com.nflg.product.material.pojo.entity.MaterialUpdateBillEntity; +import com.nflg.product.material.pojo.entity.MaterialUpdateImportTaskEntity; import com.nflg.product.material.pojo.query.MaterialUpdateBillQuery; import com.nflg.product.material.pojo.vo.MaterialBatchImportVO; import com.nflg.product.material.pojo.vo.MaterialMainVO; @@ -191,4 +192,10 @@ public class MaterialUpdateBillApi extends BaseApi { public void doCalcRecommend() { materialUpdateToOAService.doFreezeState(); } + + @GetMapping("getMaterialUpdateImportTaskList") + @ApiOperation("获取物料变更批量导入任务表") + public ResultVO> getMaterialUpdateImportTaskList() { + return ResultVO.success(materialUpdateBillService.getMaterialUpdateImportTaskList()); + } } diff --git a/nflg_project_dev/material/src/main/java/com/nflg/product/material/mapper/master/MaterialUpdateImportTaskMapper.java b/nflg_project_dev/material/src/main/java/com/nflg/product/material/mapper/master/MaterialUpdateImportTaskMapper.java new file mode 100644 index 00000000..35f6b42d --- /dev/null +++ b/nflg_project_dev/material/src/main/java/com/nflg/product/material/mapper/master/MaterialUpdateImportTaskMapper.java @@ -0,0 +1,11 @@ +package com.nflg.product.material.mapper.master; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.product.material.pojo.entity.MaterialUpdateImportTaskEntity; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface MaterialUpdateImportTaskMapper extends BaseMapper { + List getMaterialUpdateImportTaskList(@Param("userCode") String userCode); +} diff --git a/nflg_project_dev/material/src/main/java/com/nflg/product/material/pojo/entity/MaterialUpdateImportTaskEntity.java b/nflg_project_dev/material/src/main/java/com/nflg/product/material/pojo/entity/MaterialUpdateImportTaskEntity.java new file mode 100644 index 00000000..5714d07e --- /dev/null +++ b/nflg_project_dev/material/src/main/java/com/nflg/product/material/pojo/entity/MaterialUpdateImportTaskEntity.java @@ -0,0 +1,88 @@ +package com.nflg.product.material.pojo.entity; + + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 物料变更批量导入任务表 + */ + +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-material-pojo-entity-MaterialUpdateImportTaskEntity") +@TableName(value = "t_material_update_import_task") +public class MaterialUpdateImportTaskEntity implements Serializable { + + /** + * 行id + */ + @TableId(value = "row_id", type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "行id") + private Long rowId; + + /** + * 文件名称 + */ + @TableField(value = "file_name") + @ApiModelProperty(value = "文件名称") + private String fileName; + + /** + * 总条数 + */ + @TableField(value = "total_num") + @ApiModelProperty(value = "总条数") + private Integer totalNum; + + /** + * 成功条数 + */ + @TableField(value = "success_num") + @ApiModelProperty(value = "成功条数") + private Integer successNum; + + /** + * 失败条数 + */ + @TableField(value = "fail_num") + @ApiModelProperty(value = "失败条数") + private Integer failNum; + + /** + * 失败原因 + */ + @TableField(value = "fail_reason") + @ApiModelProperty(value = "失败原因") + private String failReason; + + /** + * 任务状态:0进行中 1已完成 + */ + @TableField(value = "task_status") + @ApiModelProperty(value = "任务状态:0进行中 1已完成 2已中止") + private Integer taskStatus; + + /** + * 创建人 + */ + @TableField(value = "created_by", fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建人") + private String createdBy; + + /** + * 创建时间 + */ + @TableField(value = "created_time", fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private LocalDateTime createdTime; + + private static final long serialVersionUID = 1L; + +} diff --git a/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java b/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java index 32798d53..744e7703 100644 --- a/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java +++ b/nflg_project_dev/material/src/main/java/com/nflg/product/material/service/MaterialUpdateBillService.java @@ -21,6 +21,7 @@ import com.nflg.product.base.core.exception.NflgBusinessException; import com.nflg.product.base.core.vo.PageVO; import com.nflg.product.material.constant.*; import com.nflg.product.material.mapper.master.MaterialUpdateBillMapper; +import com.nflg.product.material.mapper.master.MaterialUpdateImportTaskMapper; import com.nflg.product.material.pojo.dto.ExcelDTO.MaterialStateUpExcelDTO; import com.nflg.product.material.pojo.dto.ExcelDTO.TwentyMaterialTemplateExcelDTO; import com.nflg.product.material.pojo.dto.MaterialMainAddAttrParamDTO; @@ -48,9 +49,12 @@ import org.ttzero.excel.reader.ExcelReader; import javax.annotation.Resource; import java.io.IOException; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -89,6 +93,8 @@ public class MaterialUpdateBillService extends ServiceImpl redisTemplate; + @Resource + private MaterialUpdateImportTaskMapper materialUpdateImportTaskMapper; private static final String PREFIX = "frontend:material"; @@ -403,18 +409,26 @@ public class MaterialUpdateBillService extends ServiceImpl excelContext = EecExcelUtil.getExcelContext(file.getInputStream(), MaterialStateUpExcelDTO.class); - if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > 1000) { + if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > batchSize) { if (excelContext.size() > 10000) { return ResultVO.error("导入失败,最多支持10000条批量导入"); } redisTemplate.opsForValue().set(buildKey(userCode + ":updateBatchImport"), file.getOriginalFilename()); + Map indexMaterialMap = new HashMap<>(excelContext.size()); + for (int i = 0; i < excelContext.size(); i++) { + indexMaterialMap.put(excelContext.get(i).getMaterialNo(), i + 1); + } + Long rowId = IdWorker.getId(); // 大数据量,子线程分批次提交OA(每批1000条),主线程提前返回结果给前端 CompletableFuture task1 = CompletableFuture.supplyAsync(() -> { long startTime = System.currentTimeMillis(); - List> lists = Lists.partition(excelContext, 1000); + insertMaterialUpdateImportTask(rowId, excelContext.size(), file.getOriginalFilename(), userCode); + List> lists = Lists.partition(excelContext, batchSize); lists.forEach(items -> this.handleImportDataForState(items, applyDeptName, deptEnt, realName, userCode)); + updateMaterialUpdateImportTask(rowId, excelContext.size(), excelContext.size(), 0, ""); long endTime = System.currentTimeMillis(); log.info("物料变更批量导入耗时(ms): {}", endTime - startTime); redisTemplate.delete(buildKey(userCode + ":updateBatchImport")); @@ -423,6 +437,15 @@ public class MaterialUpdateBillService extends ServiceImpl { // 异常处理器,打印异常信息并返回默认值 log.error("物料变更批量导入异常: " + ex.getMessage()); + String errMaterialNo = getErrMaterialNo(ex.getMessage()); + int successNum = 0; + int failNum = excelContext.size(); + if (StrUtil.isNotEmpty(errMaterialNo)) { + Integer idx = indexMaterialMap.get(errMaterialNo); + successNum = idx / batchSize; + failNum = excelContext.size() - (idx / batchSize); + } + updateMaterialUpdateImportTask(rowId, excelContext.size(), successNum, failNum, ex.getMessage()); redisTemplate.delete(buildKey(userCode + ":updateBatchImport")); return -1; }); @@ -435,16 +458,23 @@ public class MaterialUpdateBillService extends ServiceImpl excelContext = EecExcelUtil.getExcelContext(file.getInputStream(), TwentyMaterialTemplateExcelDTO.class); - if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > 1000) { + if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > batchSize) { if (excelContext.size() > 10000) { return ResultVO.error("导入失败,最多支持10000条批量导入"); } redisTemplate.opsForValue().set(buildKey(userCode + ":updateBatchImport"), file.getOriginalFilename()); + Map indexMaterialMap = new HashMap<>(excelContext.size()); + for (int i = 0; i < excelContext.size(); i++) { + indexMaterialMap.put(excelContext.get(i).getMaterialNo(), i + 1); + } + Long rowId = IdWorker.getId(); // 大数据量,子线程分批次提交OA(每批1000条),主线程提前返回结果给前端 CompletableFuture task1 = CompletableFuture.supplyAsync(() -> { long startTime = System.currentTimeMillis(); - List> lists = Lists.partition(excelContext, 1000); + insertMaterialUpdateImportTask(rowId, excelContext.size(), file.getOriginalFilename(), userCode); + List> lists = Lists.partition(excelContext, batchSize); lists.forEach(items -> this.handleImportDataForSummary(items, applyDeptName, deptEnt, realName, userCode)); + updateMaterialUpdateImportTask(rowId, excelContext.size(), excelContext.size(), 0, ""); long endTime = System.currentTimeMillis(); log.info("物料变更批量导入耗时(ms): {}", endTime - startTime); redisTemplate.delete(buildKey(userCode + ":updateBatchImport")); @@ -453,6 +483,15 @@ public class MaterialUpdateBillService extends ServiceImpl { // 异常处理器,打印异常信息并返回默认值 log.error("物料变更批量导入异常: " + ex.getMessage()); + String errMaterialNo = getErrMaterialNo(ex.getMessage()); + int successNum = 0; + int failNum = excelContext.size(); + if (StrUtil.isNotEmpty(errMaterialNo)) { + Integer idx = indexMaterialMap.get(errMaterialNo); + successNum = idx / batchSize; + failNum = excelContext.size() - (idx / batchSize); + } + updateMaterialUpdateImportTask(rowId, excelContext.size(), successNum, failNum, ex.getMessage()); redisTemplate.delete(buildKey(userCode + ":updateBatchImport")); return -1; }); @@ -466,6 +505,51 @@ public class MaterialUpdateBillService extends ServiceImpl 0) { + desc += StrUtil.format(",第{}条起因为“{}”而中止", successNum + 1, exceptionMsg); + update.setTaskStatus(2); // 已中止 + } else { + update.setTaskStatus(1); // 已完成 + } + update.setFailReason(desc); + materialUpdateImportTaskMapper.updateById(update); + } + + + // 从报错信息找到第一个物料号 + private String getErrMaterialNo(String exceptionMsg) { + if (StrUtil.isEmpty(exceptionMsg)) { + return ""; + } + Pattern pattern = Pattern.compile("\\d{10}"); + Matcher matcher = pattern.matcher(exceptionMsg); + if (matcher.find()) { + return matcher.group(); + } + return ""; + } + /** * 状态变更 */ @@ -1114,4 +1198,8 @@ public class MaterialUpdateBillService extends ServiceImpl getMaterialUpdateImportTaskList() { + return materialUpdateImportTaskMapper.getMaterialUpdateImportTaskList(SessionUtil.getUserCode()); + } } diff --git a/nflg_project_dev/material/src/main/resources/mapper/master/MaterialUpdateImportTaskMapper.xml b/nflg_project_dev/material/src/main/resources/mapper/master/MaterialUpdateImportTaskMapper.xml new file mode 100644 index 00000000..5feb00ff --- /dev/null +++ b/nflg_project_dev/material/src/main/resources/mapper/master/MaterialUpdateImportTaskMapper.xml @@ -0,0 +1,13 @@ + + + + + +