Merge remote-tracking branch 'origin/master-hlq20240911update'
This commit is contained in:
commit
d3ee516d11
|
|
@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.nflg.product.base.core.api.BaseApi;
|
||||
import com.nflg.product.base.core.conmon.util.SessionUtil;
|
||||
import com.nflg.product.base.core.exception.NflgBusinessException;
|
||||
import com.nflg.product.material.pojo.dto.FindLastAttrValuesDTO;
|
||||
import com.nflg.product.material.pojo.dto.MaterialMainDTO;
|
||||
|
|
@ -94,7 +95,7 @@ public class MaterialMainApi extends BaseApi {
|
|||
@GetMapping("selectByRowId")
|
||||
@ApiOperation("auto-根据rowId查询物料主数据表")
|
||||
public ResultVO<MaterialMainVO> selectByRowId(@RequestParam("rowId") Long rowId, @RequestParam("type") Integer type) {
|
||||
return ResultVO.success(materialMainService.selectByRowId(rowId, type));
|
||||
return ResultVO.success(materialMainService.selectByRowId(rowId, type, SessionUtil.getUserCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ 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;
|
||||
import com.nflg.product.material.pojo.vo.MaterialUpdateBillVO;
|
||||
import com.nflg.product.material.service.MaterialUpdateBillService;
|
||||
|
|
@ -132,7 +134,7 @@ public class MaterialUpdateBillApi extends BaseApi {
|
|||
@ApiOperation("批量变更")
|
||||
@PostMapping("batchImport")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResultVO<Boolean> batchImport(@RequestParam(required = true, value = "file") MultipartFile file) throws IOException {
|
||||
public ResultVO<MaterialBatchImportVO> batchImport(@RequestParam(required = true, value = "file") MultipartFile file) throws IOException {
|
||||
try {
|
||||
return materialUpdateBillService.batchImport(file);
|
||||
} catch (Exception ex) {
|
||||
|
|
@ -190,4 +192,10 @@ public class MaterialUpdateBillApi extends BaseApi {
|
|||
public void doCalcRecommend() {
|
||||
materialUpdateToOAService.doFreezeState();
|
||||
}
|
||||
|
||||
@GetMapping("getMaterialUpdateImportTaskList")
|
||||
@ApiOperation("获取物料变更批量导入任务表")
|
||||
public ResultVO<List<MaterialUpdateImportTaskEntity>> getMaterialUpdateImportTaskList() {
|
||||
return ResultVO.success(materialUpdateBillService.getMaterialUpdateImportTaskList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.nflg.product.material.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisTemplateConfig {
|
||||
|
||||
/**
|
||||
* redis 解决key和value前多出一段xACxEDx00
|
||||
* c.r. https://blog.csdn.net/u010667710/article/details/131452820
|
||||
*
|
||||
* @param redisTemplate
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisTemplate<Object, Object> redisStringTemplate(RedisTemplate<Object, Object> redisTemplate) {
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setKeySerializer(stringRedisSerializer);
|
||||
// 如果手动将Value转换成了JSON,就不要再用JSON序列化器了。
|
||||
// redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
|
||||
redisTemplate.setValueSerializer(stringRedisSerializer);
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<MaterialUpdateImportTaskEntity> {
|
||||
List<MaterialUpdateImportTaskEntity> getMaterialUpdateImportTaskList(@Param("userCode") String userCode);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.nflg.product.material.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MaterialBatchImportVO {
|
||||
|
||||
private Boolean inBatches; // 是否分批次
|
||||
|
||||
}
|
||||
|
|
@ -823,12 +823,12 @@ public class MaterialMainService extends ServiceImpl<MaterialMainMapper, Materia
|
|||
*
|
||||
* @param list
|
||||
*/
|
||||
private void initFavoritesState(List<MaterialMainVO> list) {
|
||||
private void initFavoritesState(List<MaterialMainVO> list, String userCode) {
|
||||
if (list.size() <= 0) {
|
||||
return;
|
||||
}
|
||||
List<Long> materialRowIds = list.stream().map(MaterialMainVO::getRowId).collect(Collectors.toList());
|
||||
List<MaterialFavoritesEntity> favorityList = materialFavoritesService.lambdaQuery().eq(MaterialFavoritesEntity::getUserCode, SessionUtil.getUserCode()).in(MaterialFavoritesEntity::getMaterialRowId, materialRowIds).list();
|
||||
List<MaterialFavoritesEntity> favorityList = materialFavoritesService.lambdaQuery().eq(MaterialFavoritesEntity::getUserCode, userCode).in(MaterialFavoritesEntity::getMaterialRowId, materialRowIds).list();
|
||||
Map<Long, MaterialFavoritesEntity> favorityMap = ListCommonUtil.listToMap(favorityList, MaterialFavoritesEntity::getMaterialRowId);
|
||||
list.forEach(k -> {
|
||||
k.setFavoritesState(0);
|
||||
|
|
@ -862,7 +862,7 @@ public class MaterialMainService extends ServiceImpl<MaterialMainMapper, Materia
|
|||
* @param rowId 主键
|
||||
* @return 单条数据
|
||||
*/
|
||||
public MaterialMainVO selectByRowId(@RequestParam("rowId") Long rowId, Integer type) {
|
||||
public MaterialMainVO selectByRowId(@RequestParam("rowId") Long rowId, Integer type, String userCode) {
|
||||
long Date10 = new Date().getTime();
|
||||
log.info("[计算耗时][selectByRowId]================================" + Date10 );
|
||||
MaterialMainEntity materialMainEntity = materialMainMapper.selectById(rowId);
|
||||
|
|
@ -879,7 +879,7 @@ public class MaterialMainService extends ServiceImpl<MaterialMainMapper, Materia
|
|||
//task.add(CompletableFuture.runAsync(() -> {
|
||||
List<MaterialMainVO> list = new ArrayList<>();
|
||||
list.add(materialMainVO);
|
||||
initFavoritesState(list);
|
||||
initFavoritesState(list, userCode);
|
||||
//}));
|
||||
|
||||
long Date20 = new Date().getTime();
|
||||
|
|
@ -1108,7 +1108,7 @@ public class MaterialMainService extends ServiceImpl<MaterialMainMapper, Materia
|
|||
public MaterialMainVO selectByMaterialNo(String materialNo) {
|
||||
MaterialMainEntity ent = this.lambdaQuery().eq(MaterialMainEntity::getMaterialNo, materialNo).one();
|
||||
if (!Objects.isNull(ent)) {
|
||||
return selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode());
|
||||
return selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode(), SessionUtil.getUserCode());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1119,7 +1119,7 @@ public class MaterialMainService extends ServiceImpl<MaterialMainMapper, Materia
|
|||
list.add("22");
|
||||
MaterialMainEntity ent = materialMainMapper.selectByMaterialNoAndRelCategoryCode(materialNo, list);
|
||||
if (!Objects.isNull(ent)) {
|
||||
return selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode());
|
||||
return selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode(), SessionUtil.getUserCode());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public class MaterialSubmitService {
|
|||
|
||||
public void submitOne(Long rowId) {
|
||||
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(rowId, MaterialMainTypeEnum.ONE.getCode());
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(rowId, MaterialMainTypeEnum.ONE.getCode(), SessionUtil.getUserCode());
|
||||
if (materialMainVO.getProcessState() > 0) {
|
||||
|
||||
throw new NflgBusinessException(STATE.ParamErr, materialMainVO.getMaterialNo().concat("物料已提交,不能重复提交"));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -28,10 +29,7 @@ import com.nflg.product.material.pojo.dto.MaterialMainAttrDTO;
|
|||
import com.nflg.product.material.pojo.dto.MaterialUpdateBillDTO;
|
||||
import com.nflg.product.material.pojo.entity.*;
|
||||
import com.nflg.product.material.pojo.query.MaterialUpdateBillQuery;
|
||||
import com.nflg.product.material.pojo.vo.MaterialHomeMainVO;
|
||||
import com.nflg.product.material.pojo.vo.MaterialMainAttrValuesVO;
|
||||
import com.nflg.product.material.pojo.vo.MaterialMainVO;
|
||||
import com.nflg.product.material.pojo.vo.MaterialUpdateBillVO;
|
||||
import com.nflg.product.material.pojo.vo.*;
|
||||
import com.nflg.product.material.util.EecExcelUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import nflg.product.common.constant.STATE;
|
||||
|
|
@ -40,6 +38,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
|
@ -50,8 +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;
|
||||
|
||||
/**
|
||||
|
|
@ -88,6 +91,13 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
@Value("${material.home.day:30}")
|
||||
private Integer homeDay;
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
@Resource
|
||||
private MaterialUpdateImportTaskMapper materialUpdateImportTaskMapper;
|
||||
|
||||
private static final String PREFIX = "frontend:material";
|
||||
|
||||
/**
|
||||
* 分页查询所有数据
|
||||
*
|
||||
|
|
@ -346,7 +356,7 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
List<MaterialUpdateBillEntity> ents = new ArrayList<>();
|
||||
for (MaterialStateUpExcelDTO data : excelContext) {
|
||||
MaterialMainEntity material = materialMainService.lambdaQuery().eq(MaterialMainEntity::getMaterialNo, data.getMaterialNo()).one();
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(material.getRowId(), MaterialMainTypeEnum.ONE.getCode());
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(material.getRowId(), MaterialMainTypeEnum.ONE.getCode(), SessionUtil.getUserCode());
|
||||
MaterialUpdateBillEntity ent = new MaterialUpdateBillEntity();
|
||||
ent.setMaterialNo(data.getMaterialNo());
|
||||
ent.setOldMaterialState(material.getMaterialState());
|
||||
|
|
@ -363,16 +373,19 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
}
|
||||
this.saveBatch(ents);
|
||||
//同步OA
|
||||
materialUpdateToOAService.sysncToOaOnleState(ents);
|
||||
materialUpdateToOAService.sysncToOaOnleState(ents, SessionUtil.getUserCode());
|
||||
}
|
||||
|
||||
public ResultVO<Boolean> batchImport(MultipartFile file) throws IOException {
|
||||
public ResultVO<MaterialBatchImportVO> batchImport(MultipartFile file) throws IOException {
|
||||
if (file != null && !file.getOriginalFilename().endsWith("xls") && !file.getOriginalFilename().endsWith("xlsx")) {
|
||||
return ResultVO.error("上传的文件非Excel文件");
|
||||
}
|
||||
Object cacheFileName = redisTemplate.boundValueOps(buildKey(SessionUtil.getUserCode() + ":updateBatchImport")).get();
|
||||
if (ObjectUtil.isNotEmpty(cacheFileName) && file.getOriginalFilename().equals(cacheFileName)) {
|
||||
return ResultVO.error("当前Excel文件正在处理中,请勿重复导入");
|
||||
}
|
||||
|
||||
int lastColIndex = ExcelReader.read(file.getInputStream()).sheet(0).getHeader().getLastColumnIndex();
|
||||
List<MaterialUpdateBillEntity> ents = new ArrayList<>();
|
||||
|
||||
AuthorityDepartmentEntity deptEnt = departmentService.getById(SessionUtil.getPartRowId());
|
||||
if (Objects.isNull(deptEnt)) {
|
||||
|
|
@ -392,11 +405,159 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
applyDeptName = String.join("/", deptNameList);
|
||||
}
|
||||
|
||||
String realName = SessionUtil.getRealName();
|
||||
String userCode = SessionUtil.getUserCode();
|
||||
MaterialBatchImportVO importVO = new MaterialBatchImportVO();
|
||||
importVO.setInBatches(false);
|
||||
int batchSize = 1000;
|
||||
if (lastColIndex == 4) {
|
||||
List<MaterialStateUpExcelDTO> excelContext = EecExcelUtil.getExcelContext(file.getInputStream(), MaterialStateUpExcelDTO.class);
|
||||
if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > batchSize) {
|
||||
if (excelContext.size() > 10000) {
|
||||
return ResultVO.error("导入失败,最多支持10000条批量导入");
|
||||
}
|
||||
redisTemplate.opsForValue().set(buildKey(userCode + ":updateBatchImport"), file.getOriginalFilename());
|
||||
Map<String, Integer> 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<Integer> task1 = CompletableFuture.supplyAsync(() -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
insertMaterialUpdateImportTask(rowId, excelContext.size(), file.getOriginalFilename(), userCode);
|
||||
List<List<MaterialStateUpExcelDTO>> 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"));
|
||||
return 1;
|
||||
});
|
||||
task1.exceptionally(ex -> {
|
||||
// 异常处理器,打印异常信息并返回默认值
|
||||
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;
|
||||
});
|
||||
// task1.join(); // 阻塞获取结果
|
||||
importVO.setInBatches(true);
|
||||
return ResultVO.success(importVO);
|
||||
} else {
|
||||
this.handleImportDataForState(excelContext, applyDeptName, deptEnt, realName, userCode);
|
||||
}
|
||||
} else {
|
||||
// 制作物料
|
||||
List<TwentyMaterialTemplateExcelDTO> excelContext = EecExcelUtil.getExcelContext(file.getInputStream(), TwentyMaterialTemplateExcelDTO.class);
|
||||
if (CollectionUtil.isNotEmpty(excelContext) && excelContext.size() > batchSize) {
|
||||
if (excelContext.size() > 10000) {
|
||||
return ResultVO.error("导入失败,最多支持10000条批量导入");
|
||||
}
|
||||
redisTemplate.opsForValue().set(buildKey(userCode + ":updateBatchImport"), file.getOriginalFilename());
|
||||
Map<String, Integer> 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<Integer> task1 = CompletableFuture.supplyAsync(() -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
insertMaterialUpdateImportTask(rowId, excelContext.size(), file.getOriginalFilename(), userCode);
|
||||
List<List<TwentyMaterialTemplateExcelDTO>> 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"));
|
||||
return 1;
|
||||
});
|
||||
task1.exceptionally(ex -> {
|
||||
// 异常处理器,打印异常信息并返回默认值
|
||||
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;
|
||||
});
|
||||
// task1.join(); // 阻塞获取结果
|
||||
importVO.setInBatches(true);
|
||||
return ResultVO.success(importVO);
|
||||
} else {
|
||||
this.handleImportDataForSummary(excelContext, applyDeptName, deptEnt, realName, userCode);
|
||||
}
|
||||
}
|
||||
return ResultVO.success(importVO);
|
||||
}
|
||||
|
||||
private Long insertMaterialUpdateImportTask(Long rowId, Integer totalNum, String fileName, String userCode) {
|
||||
MaterialUpdateImportTaskEntity save = new MaterialUpdateImportTaskEntity();
|
||||
save.setRowId(rowId);
|
||||
save.setFileName(fileName);
|
||||
save.setTotalNum(totalNum);
|
||||
save.setSuccessNum(0);
|
||||
save.setFailNum(0);
|
||||
save.setTaskStatus(0);
|
||||
save.setCreatedBy(userCode);
|
||||
save.setCreatedTime(LocalDateTime.now());
|
||||
materialUpdateImportTaskMapper.insert(save);
|
||||
return save.getRowId();
|
||||
}
|
||||
|
||||
private void updateMaterialUpdateImportTask(Long rowId, Integer totalNum, Integer successNum, Integer failNum, String exceptionMsg) {
|
||||
MaterialUpdateImportTaskEntity update = new MaterialUpdateImportTaskEntity();
|
||||
update.setRowId(rowId);
|
||||
update.setSuccessNum(successNum);
|
||||
update.setFailNum(failNum);
|
||||
// 批量导入总条数{total_num}条,成功{success_num}条,失败{fail_num}条,第{success_num}条后因为“{fail_reason}”而中止
|
||||
String desc = StrUtil.format("批量导入总条数{}条,成功{}条,失败{}条", totalNum, successNum, failNum);
|
||||
if (failNum > 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 "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态变更
|
||||
*/
|
||||
private void handleImportDataForState(List<MaterialStateUpExcelDTO> excelContext, String applyDeptName, AuthorityDepartmentEntity deptEnt, String realName, String userCode) {
|
||||
List<MaterialUpdateBillEntity> ents = new ArrayList<>();
|
||||
excelContext = excelContext.stream().filter(u -> StrUtil.isNotBlank(u.getMaterialNo())).collect(Collectors.toList());
|
||||
if (excelContext.size() <= 0) {
|
||||
return ResultVO.error("导入内容不允许为空");
|
||||
throw new NflgBusinessException(STATE.ParamErr, "导入内容不允许为空");
|
||||
}
|
||||
|
||||
List<String> upMaterialNos = excelContext.stream().map(MaterialStateUpExcelDTO::getMaterialNo).collect(Collectors.toList());
|
||||
|
|
@ -431,11 +592,11 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
Set<String> notFreezeSet = new HashSet<>();
|
||||
for (MaterialStateUpExcelDTO data : excelContext) {
|
||||
MaterialMainEntity material = materialMainService.lambdaQuery().eq(MaterialMainEntity::getMaterialNo, data.getMaterialNo()).one();
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(material.getRowId(), MaterialMainTypeEnum.ONE.getCode());
|
||||
MaterialMainVO materialMainVO = materialMainService.selectByRowId(material.getRowId(), MaterialMainTypeEnum.ONE.getCode(), userCode);
|
||||
|
||||
String checkMaterialState = checkMaterialState(material);
|
||||
if (ObjectUtil.isNotEmpty(checkMaterialState)) {
|
||||
return ResultVO.error(checkMaterialState);
|
||||
throw new NflgBusinessException(STATE.ParamErr, checkMaterialState);
|
||||
}
|
||||
|
||||
// 如果物料是状态变更,且变更状态为冻结或完全弃用,物料昨日库得值 大于 0时,不允许申请冻结
|
||||
|
|
@ -449,7 +610,7 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
boolean flagThree = materialState.compareTo(MaterialStateEnum.FROZEN.getValue()) == 0 || materialState.compareTo(MaterialStateEnum.GIVEUP.getValue()) == 0;
|
||||
if (flagTwo && flagThree) {
|
||||
if (flagOne) {
|
||||
return ResultVO.error("物料编号为" + material.getMaterialNo() + "的物料还有库存,无法申请冻结或完全弃用");
|
||||
throw new NflgBusinessException(STATE.ParamErr, "物料编号为" + material.getMaterialNo() + "的物料还有库存,无法申请冻结或完全弃用");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -465,8 +626,8 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
ent.setOldCategoryNameTree(getMaterialCategoryTree(materialMainVO));
|
||||
ent.setOldMaterialDesc(material.getMaterialDesc());
|
||||
ent.setApplyDeptName(applyDeptName);
|
||||
ent.setCreatedByName(SessionUtil.getRealName());
|
||||
ent.setCreatedBy(SessionUtil.getUserCode());
|
||||
ent.setCreatedByName(realName);
|
||||
ent.setCreatedBy(userCode);
|
||||
ent.setCreatedTime(new Date());
|
||||
ents.add(ent);
|
||||
|
||||
|
|
@ -477,7 +638,7 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
this.validateFreezeStateChangeOther(ents, deptEnt.getDptCode());
|
||||
this.saveBatch(ents);
|
||||
//同步OA
|
||||
materialUpdateToOAService.sysncToOaOnleState(ents);
|
||||
materialUpdateToOAService.sysncToOaOnleState(ents, userCode);
|
||||
|
||||
if (CollectionUtil.isNotEmpty(notFreezeSet)) {
|
||||
// 过滤出 11、51物料 && 解冻
|
||||
|
|
@ -501,12 +662,16 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
materialMainService.updateBatchById(updateList);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 制作物料
|
||||
List<TwentyMaterialTemplateExcelDTO> excelContext = EecExcelUtil.getExcelContext(file.getInputStream(), TwentyMaterialTemplateExcelDTO.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 制作物料综合变更
|
||||
*/
|
||||
private void handleImportDataForSummary(List<TwentyMaterialTemplateExcelDTO> excelContext, String applyDeptName, AuthorityDepartmentEntity deptEnt, String realName, String userCode) {
|
||||
List<MaterialUpdateBillEntity> ents = new ArrayList<>();
|
||||
excelContext = excelContext.stream().filter(u -> StrUtil.isNotBlank(u.getMaterialNo())).collect(Collectors.toList());
|
||||
if (excelContext.size() <= 0) {
|
||||
return ResultVO.error("导入内容不允许为空");
|
||||
throw new NflgBusinessException(STATE.ParamErr, "导入内容不允许为空");
|
||||
}
|
||||
|
||||
List<String> upMaterialNos = excelContext.stream().map(TwentyMaterialTemplateExcelDTO::getMaterialNo).collect(Collectors.toList());
|
||||
|
|
@ -565,7 +730,7 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
|
||||
String checkMaterialState = checkMaterialState(material);
|
||||
if (ObjectUtil.isNotEmpty(checkMaterialState)) {
|
||||
return ResultVO.error(checkMaterialState);
|
||||
throw new NflgBusinessException(STATE.ParamErr, checkMaterialState);
|
||||
}
|
||||
|
||||
MaterialMainVO materialMainVO = new MaterialMainVO();
|
||||
|
|
@ -631,8 +796,8 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
ent.setUpdateResion(data.getUpdateResion());
|
||||
ent.setReplaceMaterialNo(data.getReplaceMaterialNo());
|
||||
ent.setApplyDeptName(applyDeptName);
|
||||
ent.setCreatedByName(SessionUtil.getRealName());
|
||||
ent.setCreatedBy(SessionUtil.getUserCode());
|
||||
ent.setCreatedByName(realName);
|
||||
ent.setCreatedBy(userCode);
|
||||
ent.setCreatedTime(new Date());
|
||||
ents.add(ent);
|
||||
|
||||
|
|
@ -640,15 +805,13 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
ResultVO<String> checkMaterialDesc = checkMaterialDesc(ent);
|
||||
if (Objects.nonNull(checkMaterialDesc)) {
|
||||
log.info("【checkMaterialDesc校验结果】:" + checkMaterialDesc.getMsg());
|
||||
return ResultVO.error(checkMaterialDesc.getMsg());
|
||||
throw new NflgBusinessException(STATE.ParamErr, checkMaterialDesc.getMsg());
|
||||
}
|
||||
}
|
||||
this.validateFreezeStateChangeOther(ents, deptEnt.getDptCode());
|
||||
this.saveBatch(ents);
|
||||
//同步OA
|
||||
materialUpdateToOAService.sysnToOa(ents);
|
||||
}
|
||||
return ResultVO.success(Boolean.TRUE);
|
||||
materialUpdateToOAService.sysnToOa(ents, userCode);
|
||||
}
|
||||
|
||||
// 申请部门是 营销中心,11,21变更,由冻结改成其他状态,不允许改成激活
|
||||
|
|
@ -850,7 +1013,7 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
MaterialUpdateBillEntity materialUpdateBillEntity = this.lambdaQuery().eq(MaterialUpdateBillEntity::getRowId, rowId).one();
|
||||
MaterialMainEntity ent = materialMainService.lambdaQuery().eq(MaterialMainEntity::getMaterialNo, materialNo).one();
|
||||
if (!Objects.isNull(ent)) {
|
||||
materialMainVO = materialMainService.selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode());
|
||||
materialMainVO = materialMainService.selectByRowId(ent.getRowId(), MaterialMainTypeEnum.ONE.getCode(), SessionUtil.getUserCode());
|
||||
materialMainVO.setMaterialDesc(materialUpdateBillEntity.getNewMateiralDesc());
|
||||
materialMainVO.setOldMaterialDesc(materialUpdateBillEntity.getOldMaterialDesc());
|
||||
materialMainVO.setShortMaterialDesc(materialUpdateBillEntity.getNewShortMaterialDesc());
|
||||
|
|
@ -1031,4 +1194,12 @@ public class MaterialUpdateBillService extends ServiceImpl<MaterialUpdateBillMap
|
|||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
private String buildKey(String key) {
|
||||
return StrUtil.format("{}:{}", PREFIX, key);
|
||||
}
|
||||
|
||||
public List<MaterialUpdateImportTaskEntity> getMaterialUpdateImportTaskList() {
|
||||
return materialUpdateImportTaskMapper.getMaterialUpdateImportTaskList(SessionUtil.getUserCode());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,13 +74,13 @@ public class MaterialUpdateToOAService {
|
|||
|
||||
public void submit(List<Long> rowIds) {
|
||||
List<MaterialUpdateBillEntity> entityList = materialUpdateBillService.lambdaQuery().in(MaterialUpdateBillEntity::getRowId, rowIds).list();
|
||||
sysnToOa(entityList);
|
||||
sysnToOa(entityList, SessionUtil.getUserCode());
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getHttpMap() {
|
||||
public Map<String, Object> getHttpMap(String userCode) {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("userid", SessionUtil.getUserCode());
|
||||
result.put("userid", userCode);
|
||||
result.put("summary", NacosConfig.getNacosConfig().getSummary());
|
||||
return result;
|
||||
}
|
||||
|
|
@ -89,9 +89,9 @@ public class MaterialUpdateToOAService {
|
|||
* 同步OA变更状态
|
||||
* @param data
|
||||
*/
|
||||
public void sysncToOaOnleState(List<MaterialUpdateBillEntity> data) {
|
||||
public void sysncToOaOnleState(List<MaterialUpdateBillEntity> data, String userCode) {
|
||||
|
||||
Map<String, Object> result = getHttpMap();
|
||||
Map<String, Object> result = getHttpMap(userCode);
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
data.forEach(u -> {
|
||||
Map<String, String> material = new LinkedHashMap<>();
|
||||
|
|
@ -133,14 +133,14 @@ public class MaterialUpdateToOAService {
|
|||
httpStateToOa(result, data);
|
||||
}
|
||||
|
||||
public void sysnToOa(List<MaterialUpdateBillEntity> data) {
|
||||
public void sysnToOa(List<MaterialUpdateBillEntity> data, String userCode) {
|
||||
// 批量提交,校验是否有重复物料变更
|
||||
Set<String> materialNoSet = data.stream().map(MaterialUpdateBillEntity::getMaterialNo).collect(Collectors.toSet());
|
||||
if (data.size() != materialNoSet.size()) {
|
||||
throw new NflgBusinessException(STATE.BusinessError, "批量提交的物料含重复项,请先删除重复项");
|
||||
}
|
||||
|
||||
Map<String, Object> result = getHttpMap();
|
||||
Map<String, Object> result = getHttpMap(userCode);
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
preHandleCategoryNameTree(data);
|
||||
data.forEach(u -> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
#nacos.server-addr=114.132.64.230:8123
|
||||
nacos.server-addr=192.168.0.194:8848
|
||||
|
||||
spring.cache.type=redis
|
||||
spring.redis.database=1
|
||||
spring.redis.host=192.168.0.194
|
||||
spring.redis.password=
|
||||
spring.redis.port=6379
|
||||
spring.redis.timeout=0
|
||||
spring.redis.ssl=false
|
||||
spring.redis.lettuce.pool.max-wait=-1ms
|
||||
spring.redis.lettuce.pool.max-active=8
|
||||
spring.redis.lettuce.pool.max-idle=8
|
||||
spring.redis.lettuce.pool.min-idle=0
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,12 @@
|
|||
nacos.server-addr=192.168.0.191:8848
|
||||
spring.cache.type=redis
|
||||
spring.redis.database=0
|
||||
spring.redis.host=192.168.0.191
|
||||
spring.redis.password=
|
||||
spring.redis.port=6379
|
||||
spring.redis.timeout=0
|
||||
spring.redis.ssl=false
|
||||
spring.redis.lettuce.pool.max-wait=-1ms
|
||||
spring.redis.lettuce.pool.max-active=8
|
||||
spring.redis.lettuce.pool.max-idle=8
|
||||
spring.redis.lettuce.pool.min-idle=0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
#nacos.server-addr=114.132.64.230:8123
|
||||
nacos.server-addr=192.168.0.194:8848
|
||||
|
||||
spring.cache.type=redis
|
||||
spring.redis.database=1
|
||||
spring.redis.host=192.168.0.194
|
||||
spring.redis.password=
|
||||
spring.redis.port=6379
|
||||
spring.redis.timeout=0
|
||||
spring.redis.ssl=false
|
||||
spring.redis.lettuce.pool.max-wait=-1ms
|
||||
spring.redis.lettuce.pool.max-active=8
|
||||
spring.redis.lettuce.pool.max-idle=8
|
||||
spring.redis.lettuce.pool.min-idle=0
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.nflg.product.material.mapper.master.MaterialUpdateImportTaskMapper">
|
||||
|
||||
<select id="getMaterialUpdateImportTaskList" resultType="com.nflg.product.material.pojo.entity.MaterialUpdateImportTaskEntity">
|
||||
select * from t_material_update_import_task where 1=1
|
||||
and task_status in (0,2)
|
||||
<if test="userCode != null and userCode != ''">
|
||||
and created_by = #{userCode}
|
||||
</if>
|
||||
order by created_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue