package com.vincent.rsf.server.manager.schedules;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.vincent.rsf.framework.exception.CoolException;
|
import com.vincent.rsf.server.manager.entity.Matnr;
|
import com.vincent.rsf.server.manager.entity.WkOrder;
|
import com.vincent.rsf.server.manager.entity.WkOrderItem;
|
import com.vincent.rsf.server.manager.service.AsnOrderItemService;
|
import com.vincent.rsf.server.manager.service.AsnOrderService;
|
import com.vincent.rsf.server.manager.service.MatnrService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.text.SimpleDateFormat;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
/**
|
* ASN 单据压测数据定时生成器。
|
*/
|
@Slf4j
|
@Component
|
public class AsnOrderPressureSchedules {
|
|
private static final DateTimeFormatter ORDER_CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
private static final String ORDER_TYPE = "in";
|
private static final String ORDER_WORK_TYPE = "71";
|
private static final Integer TENANT_ID = 1;
|
private static final Long USER_ID = 51L;
|
private static final String MEMO = "ASN_PRESSURE_TEST";
|
private final AtomicBoolean running = new AtomicBoolean(false);
|
|
@Autowired
|
private AsnOrderService asnOrderService;
|
@Autowired
|
private AsnOrderItemService asnOrderItemService;
|
@Autowired
|
private MatnrService matnrService;
|
|
@Value("${pressure.asn-order.enabled:false}")
|
private boolean enabled;
|
|
@Value("${pressure.asn-order.order-count-per-run:20}")
|
private int orderCountPerRun;
|
|
@Value("${pressure.asn-order.item-count-per-order:5}")
|
private int itemCountPerOrder;
|
|
@Value("${pressure.asn-order.item-qty:10}")
|
private double itemQty;
|
|
@Scheduled(cron = "${pressure.asn-order.cron:0/10 * * * * ?}")
|
@Transactional(rollbackFor = Exception.class)
|
public void insertPressureOrders() {
|
if (!enabled) {
|
return;
|
}
|
if (!running.compareAndSet(false, true)) {
|
log.warn("ASN压测任务仍在执行中,本轮跳过");
|
return;
|
}
|
try {
|
if (orderCountPerRun <= 0 || itemCountPerOrder <= 0 || itemQty <= 0) {
|
log.warn("ASN压测任务配置无效,跳过执行: orderCountPerRun={}, itemCountPerOrder={}, itemQty={}",
|
orderCountPerRun, itemCountPerOrder, itemQty);
|
return;
|
}
|
|
List<Matnr> matnrs = loadMatnrs();
|
if (matnrs.isEmpty()) {
|
log.warn("ASN压测任务未获取到可用物料,跳过执行");
|
return;
|
}
|
Collections.shuffle(matnrs);
|
|
Date now = new Date();
|
LocalDateTime nowTime = LocalDateTime.now();
|
double totalQty = itemCountPerOrder * itemQty;
|
|
List<WkOrder> orders = new ArrayList<>(orderCountPerRun);
|
for (int i = 0; i < orderCountPerRun; i++) {
|
orders.add(buildOrder(now, nowTime, totalQty, i));
|
}
|
if (!asnOrderService.saveBatch(orders, 200)) {
|
throw new CoolException("ASN压测主单插入失败");
|
}
|
|
List<WkOrderItem> items = new ArrayList<>(orderCountPerRun * itemCountPerOrder);
|
for (int orderIndex = 0; orderIndex < orders.size(); orderIndex++) {
|
WkOrder order = orders.get(orderIndex);
|
for (int itemIndex = 0; itemIndex < itemCountPerOrder; itemIndex++) {
|
Matnr matnr = matnrs.get((orderIndex * itemCountPerOrder + itemIndex) % matnrs.size());
|
items.add(buildOrderItem(order, matnr, now, orderIndex, itemIndex));
|
}
|
}
|
if (!asnOrderItemService.saveBatch(items, 500)) {
|
throw new CoolException("ASN压测明细插入失败");
|
}
|
|
log.info("ASN压测任务执行完成,本次插入主单 {} 条,明细 {} 条", orders.size(), items.size());
|
} finally {
|
running.set(false);
|
}
|
}
|
|
private List<Matnr> loadMatnrs() {
|
int needCount = Math.min(Math.max(orderCountPerRun * itemCountPerOrder, 200), 2000);
|
return matnrService.list(new LambdaQueryWrapper<Matnr>()
|
.eq(Matnr::getDeleted, 0)
|
.eq(Matnr::getStatus, 1)
|
.select(Matnr::getId, Matnr::getCode, Matnr::getName, Matnr::getFieldsIndex,
|
Matnr::getSpec, Matnr::getModel, Matnr::getUnit, Matnr::getPurUnit,
|
Matnr::getStockUnit, Matnr::getBaseUnit, Matnr::getUseOrgId,
|
Matnr::getUseOrgName, Matnr::getErpClsId)
|
.orderByDesc(Matnr::getId)
|
.last("limit " + needCount));
|
}
|
|
private WkOrder buildOrder(Date now, LocalDateTime nowTime, double totalQty, int sequence) {
|
String suffix = String.format("%04d", sequence + 1);
|
String code = "erp" + nowTime.format(ORDER_CODE_FORMATTER) + suffix;
|
long serialNo = System.currentTimeMillis() * 1000 + sequence;
|
|
return new WkOrder()
|
.setCode(code)
|
.setPoCode(code)
|
.setPoId(serialNo)
|
.setType(ORDER_TYPE)
|
.setWkType(ORDER_WORK_TYPE)
|
.setAnfme(totalQty)
|
.setQty(totalQty)
|
.setWorkQty(0.0)
|
.setCheckType(0)
|
.setRleStatus((short) 0)
|
.setNtyStatus(0)
|
.setExceStatus((short) 4)
|
.setStatus(1)
|
.setDeleted(0)
|
.setTenantId(TENANT_ID)
|
.setCreateBy(USER_ID)
|
.setCreateTime(now)
|
.setUpdateBy(USER_ID)
|
.setUpdateTime(now)
|
.setMemo(MEMO)
|
.setReportOnce(4)
|
.setBusinessTime(now)
|
.setStationId("1215")
|
.setOrderInternalCode(String.valueOf(serialNo))
|
.setStockDirect("stockDirect")
|
.setCustomerId("custom1")
|
.setCustomerName("客户1")
|
.setSupplierId("gongys1")
|
.setSupplierName("供应商1")
|
.setStockOrgId("stockYH")
|
.setStockOrgName("浙江银湖箱包有限公司仓库")
|
.setPurchaseOrgId("yhcaigou")
|
.setPurchaseOrgName("浙江银湖箱包有限公司采购")
|
.setPurchaseUserId("caigouyuan1")
|
.setPurchaseUserName("采购员1")
|
.setPrdOrgId("prdYH")
|
.setPrdOrgName("浙江银湖箱包有限公司")
|
.setSaleOrgId("sale1")
|
.setSaleOrgName("生产组1")
|
.setSaleUserId("shengchanyuan1")
|
.setSaleUserName("生产员1")
|
.setVersion(0);
|
}
|
|
private WkOrderItem buildOrderItem(WkOrder order, Matnr matnr, Date now, int orderIndex, int itemIndex) {
|
String stockUnit = StringUtils.firstNonBlank(matnr.getStockUnit(), matnr.getPurUnit(), matnr.getUnit(), matnr.getBaseUnit());
|
String purUnit = StringUtils.firstNonBlank(matnr.getPurUnit(), matnr.getUnit(), matnr.getStockUnit(), matnr.getBaseUnit());
|
String baseUnit = StringUtils.firstNonBlank(matnr.getBaseUnit(), matnr.getUnit(), matnr.getStockUnit(), matnr.getPurUnit());
|
String batchCode = "B" + new SimpleDateFormat("yyyyMMddHHmmss").format(now)
|
+ String.format("%02d%02d", orderIndex + 1, itemIndex + 1);
|
String trackCode = "T" + System.currentTimeMillis() + String.format("%02d%02d", orderIndex + 1, itemIndex + 1);
|
|
return new WkOrderItem()
|
.setOrderId(order.getId())
|
.setOrderCode(order.getCode())
|
.setPlatItemId("M" + (itemIndex + 1))
|
.setPoCode(order.getPoCode())
|
.setFieldsIndex(matnr.getFieldsIndex())
|
.setMatnrId(matnr.getId())
|
.setMatnrCode(matnr.getCode())
|
.setMaktx(matnr.getName())
|
.setSpec(matnr.getSpec())
|
.setModel(matnr.getModel())
|
.setAnfme(itemQty)
|
.setWorkQty(0.0)
|
.setPurQty(itemQty)
|
.setQty(itemQty)
|
.setStockUnit(stockUnit)
|
.setPurUnit(purUnit)
|
.setBatch(batchCode)
|
.setSplrBatch(batchCode)
|
.setSplrCode("gongys1")
|
.setSplrName("供应商1")
|
.setTrackCode(trackCode)
|
.setBarcode(trackCode)
|
.setProdTime(new SimpleDateFormat("yyyy-MM-dd").format(now))
|
.setNtyStatus(0)
|
.setStatus(1)
|
.setDeleted(0)
|
.setTenantId(TENANT_ID)
|
.setCreateBy(USER_ID)
|
.setCreateTime(now)
|
.setUpdateBy(USER_ID)
|
.setUpdateTime(now)
|
.setMemo(MEMO)
|
.setBaseUnit(baseUnit)
|
.setUseOrgId(matnr.getUseOrgId())
|
.setUseOrgName(matnr.getUseOrgName())
|
.setErpClsId(matnr.getErpClsId())
|
.setPriceUnitId(baseUnit);
|
}
|
}
|