新增webcad生产单导入:saveData异步保存优化

This commit is contained in:
gaoqr
2025-03-11 11:27:13 +08:00
parent 27027f6f2c
commit 0e2971df4f
4 changed files with 134 additions and 9 deletions
@@ -18,4 +18,5 @@ public class ErrorCodeConstants {
public static final ErrorCode WEBCAD_ORDER_IMPORT_FAILED = new ErrorCode(1_005_000_008, "导入失败:请检查拆单数据");
public static final ErrorCode WEBCAD_ORDER_IMPORT_PLATE_NOT_EXIST_ERROR = new ErrorCode(1_005_000_009, "导入失败:板材对应失败,板材库中不存在对应板材【{}】");
public static final ErrorCode WEBCAD_ORDER_IMPORT_SEAL_NOT_EXIST_ERROR = new ErrorCode(1_005_000_010, "导入失败:封边条对应失败,配件库中不存在对应封边条【{}】");
public static final ErrorCode WEBCAD_ORDER_IMPORT_SAVEDATA_ERROR = new ErrorCode(1_005_000_011, "导入失败:数据保存异常,请检查拆单数据");
}
@@ -31,7 +31,7 @@ public class OrderImportController {
private WebCadOrderImportService webCadOrderImportService;
@PostMapping("/webcad/import")
@Operation(summary = "生产单导入新增")
@Operation(summary = "webcad拆单导入生产单")
@OperateLog(type = IMPORT)
public CommonResult<Boolean> webCadOrderImport(@RequestBody WebCadDataReqVO webCadDataReqVO) {
webCadOrderImportService.webCadOrderImport(webCadDataReqVO);
@@ -25,7 +25,9 @@ import com.cf.imes.module.plan.service.order.OrderInputProcessor;
import com.cf.imes.module.plan.service.orderImport.factory.WebCadOrderImportFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@@ -91,7 +93,11 @@ public class WebCadOrderImportServiceImpl implements WebCadOrderImportService {
@Resource
private PlateGoodMapper plateGoodMapper;
@Resource
private DataSourceTransactionManager transactionManager;
@Override
@Transactional(rollbackFor = Exception.class)
public void webCadOrderImport(WebCadDataReqVO webCadDataReqVO) {
Long organId = OrganContextHolder.getOrganId();
String redisUniqueKey = "webcad";
@@ -106,7 +112,7 @@ public class WebCadOrderImportServiceImpl implements WebCadOrderImportService {
throw new ServiceException(ORDER_IMPORT_ORGAN_LOCK_ERROR);
}
WebCadOrderImportFactory webCadOrderImportFactory = new WebCadOrderImportFactory(organId, orderMapper, snowFlakeGenerator, orderBodyMapper, plateMapper, orderItemMapper, orderGroupMapper,
idWorker, orderInputProcessor, partsMapper, orderPartsMapper, goodsMapper, rawGoodsMapper, plateGoodMapper, customPlateNoGenerateService);
idWorker, orderInputProcessor, partsMapper, orderPartsMapper, goodsMapper, rawGoodsMapper, plateGoodMapper, customPlateNoGenerateService, transactionManager);
webCadOrderImportFactory.analyzeTempData(webCadDataReqVO);
} catch (ServiceException se) {
throw se;
@@ -6,6 +6,7 @@ import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
@@ -48,6 +49,9 @@ import com.cf.imes.module.plan.service.customplateno.vo.CustomPlateNoGenerateCon
import com.cf.imes.module.plan.service.order.OrderInputProcessor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@@ -55,11 +59,16 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_MATERIALS_EMPTY_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_PLATE_NOT_EXIST_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ROOMBODY_EMPTY_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_SAVEDATA_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_SEAL_NOT_EXIST_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_NOT_EXISTS_ERROR;
@@ -104,6 +113,8 @@ public class WebCadOrderImportFactory {
private CustomPlateNoGenerateService customPlateNoGenerateService;
private DataSourceTransactionManager transactionManager;
private Long organId;
private Long orderId;
@@ -115,6 +126,10 @@ public class WebCadOrderImportFactory {
private CustomPlateNoGenerateConfigVO plateNoGenerateConfigVO;
// 操作人
private String operatorName;
private LocalDateTime now;
// 柜体成倍信息缓存:{ 房间名+柜体名:childrenDTO }
private Map<String, WebCadDataDoubleRoomTreeReqVO.ChildrenDTO> roomBodyMap = new HashMap<>();
@@ -153,7 +168,8 @@ public class WebCadOrderImportFactory {
GoodsMapper goodsMapper,
RawGoodsMapper rawGoodsMapper,
PlateGoodMapper plateGoodMapper,
CustomPlateNoGenerateService customPlateNoGenerateService) {
CustomPlateNoGenerateService customPlateNoGenerateService,
DataSourceTransactionManager transactionManager) {
this.organId = organId;
this.orderMapper = orderMapper;
this.snowFlakeGenerator = snowFlakeGenerator;
@@ -169,6 +185,9 @@ public class WebCadOrderImportFactory {
this.rawGoodsMapper = rawGoodsMapper;
this.plateGoodMapper = plateGoodMapper;
this.customPlateNoGenerateService = customPlateNoGenerateService;
this.transactionManager = transactionManager;
operatorName = SecurityFrameworkUtils.getLoginUser().getNickname();
now = LocalDateTime.now();
}
public void analyzeTempData(WebCadDataReqVO webCadDataReqVO) {
@@ -419,6 +438,10 @@ public class WebCadOrderImportFactory {
OrderBodyDO orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId)
.roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0)
.depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("").remark("").deleted(false).build();
orderBodyDO.setCreator(operatorName);
orderBodyDO.setUpdater(operatorName);
orderBodyDO.setCreateTime(now);
orderBodyDO.setUpdateTime(now);
// 缓存成倍的柜体信息
bodyMap.put(roomBodyKey + i, orderBodyDO);
@@ -454,6 +477,10 @@ public class WebCadOrderImportFactory {
orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId)
.roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0)
.depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("").remark("").deleted(false).build();
orderBodyDO.setCreator(operatorName);
orderBodyDO.setUpdater(operatorName);
orderBodyDO.setCreateTime(now);
orderBodyDO.setUpdateTime(now);
// 缓存成倍的柜体信息
bodyMap.put(roomBodyKey, orderBodyDO);
@@ -533,10 +560,8 @@ public class WebCadOrderImportFactory {
.deleted(false)
.organId(organId)
.build();
String operatorName = SecurityFrameworkUtils.getLoginUser().getNickname();
plateDO.setCreator(operatorName);
plateDO.setUpdater(operatorName);
LocalDateTime now = LocalDateTime.now();
plateDO.setCreateTime(now);
plateDO.setUpdateTime(now);
@@ -624,6 +649,11 @@ public class WebCadOrderImportFactory {
.remark("")
.deleted(false)
.build();
orderGroupDO.setCreator(operatorName);
orderGroupDO.setUpdater(operatorName);
orderGroupDO.setCreateTime(now);
orderGroupDO.setUpdateTime(now);
orderGroupMap.put(groupMapKey, orderGroupDO);
orderGroupDOS.add(orderGroupDO);
} else {
@@ -731,6 +761,10 @@ public class WebCadOrderImportFactory {
orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId)
.roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0)
.depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("").remark("").deleted(false).build();
orderBodyDO.setCreator(operatorName);
orderBodyDO.setUpdater(operatorName);
orderBodyDO.setCreateTime(now);
orderBodyDO.setUpdateTime(now);
// 缓存成倍的柜体信息
bodyMap.put(roomBodyKey, orderBodyDO);
@@ -777,6 +811,11 @@ public class WebCadOrderImportFactory {
.remark("")
.deleted(false)
.build();
orderGroupDO.setCreator(operatorName);
orderGroupDO.setUpdater(operatorName);
orderGroupDO.setCreateTime(now);
orderGroupDO.setUpdateTime(now);
orderGroupMap.put(groupMapKey, orderGroupDO);
orderGroupDOS.add(orderGroupDO);
}
@@ -1045,15 +1084,94 @@ public class WebCadOrderImportFactory {
}
}
// /**
// * 数据保存入库
// */
// private void saveData() {
// orderInfoBatchInsertWithinThreshold(orderBodyMapper, bodyMap.values().stream().toList(), true);
// orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, true);
// orderInfoBatchInsertWithinThreshold(orderGroupMapper, orderGroupDOS, true);
// }
/**
* 数据保存入库
* orderBody、orderItem、orderGroup
*/
private void saveData() {
TransactionStatus transactionStatus = transactionManager.getTransaction(TransactionDefinition.withDefaults());
ExecutorService executorService = Executors.newFixedThreadPool(3);
AtomicBoolean hasError = new AtomicBoolean(false);
CountDownLatch latch = new CountDownLatch(3);
// 当前数据源data_code
String peek = DynamicDataSourceContextHolder.peek();
Runnable bodyTask = () -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderInfoBatchInsertWithinThreshold(orderBodyMapper, bodyMap.values().stream().toList(), true);
} catch (Exception e) {
hasError.set(true);
log.error("Error saving order bodies", e);
} finally {
latch.countDown();
}
};
Runnable itemTask = () -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, true);
} catch (Exception e) {
hasError.set(true);
log.error("Error saving order items", e);
} finally {
latch.countDown();
}
};
Runnable groupTask = () -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderInfoBatchInsertWithinThreshold(orderGroupMapper, orderGroupDOS, true);
} catch (Exception e) {
hasError.set(true);
log.error("Error saving order groups", e);
} finally {
latch.countDown();
}
};
// 执行子线程
executorService.submit(bodyTask);
executorService.submit(itemTask);
executorService.submit(groupTask);
try {
// 等待所有任务完成
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
hasError.set(true);
log.error("WEBCAD import saveData Thread interrupted", e);
} finally {
// 中止所有任务
executorService.shutdown();
}
if (hasError.get()) {
// 所有任务事务提交
transactionManager.rollback(transactionStatus);
// 抛出异常回滚主线程的数据
throw new ServiceException(WEBCAD_ORDER_IMPORT_SAVEDATA_ERROR);
} else {
// 所有任务事务回滚
transactionManager.commit(transactionStatus);
}
}
/**
* 清空所有列表