优化
This commit is contained in:
@@ -15,6 +15,8 @@ import com.baiyue.lastleg.entity.LastlegOrderDetail;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderStatusHistory;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderFee;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderOperationLog;
|
||||
import com.baiyue.lastleg.entity.ReceivingWarehouseOperation;
|
||||
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||
import com.baiyue.lastleg.inboundplan.entity.InboundPlanCarton;
|
||||
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanCartonMapper;
|
||||
import com.baiyue.lastleg.inventory.command.service.InventoryCommandService;
|
||||
@@ -23,6 +25,7 @@ import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderStatusHistoryMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderFeeMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderOperationLogMapper;
|
||||
import com.baiyue.lastleg.mapper.ReceivingWarehouseOperationMapper;
|
||||
import com.baiyue.lastleg.model.LastlegOrderType;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -37,6 +40,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -60,6 +64,8 @@ public class LastlegOrderService {
|
||||
@Resource private FbaWarehouseValidator fbaWarehouseValidator;
|
||||
@Resource private InventoryCommandService inventory;
|
||||
@Resource private InboundOrderDetainedOutboxService detainedOutbox;
|
||||
@Resource private ReceivingWarehouseOperationMapper receivingWarehouseOperations;
|
||||
@Resource private WarehouseResourceGateway warehouseResourceGateway;
|
||||
|
||||
public PageResult<LastlegOrderSummary> page(String customerId, LastlegOrderRequests.Query query) {
|
||||
Page<LastlegOrder> page = orderMapper.selectPage(
|
||||
@@ -99,9 +105,58 @@ public class LastlegOrderService {
|
||||
orderMapper.findContainerProgressItems(bookingId));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ContainerPlanProgressSummary changeReceivingWarehouse(String sourceContainerBookingId,
|
||||
String idempotencyKey, LastlegOrderRequests.ChangeReceivingWarehouse request, String operatorName) {
|
||||
String bookingId = normalizeBookingId(sourceContainerBookingId);
|
||||
String key = normalizeIdempotencyKey(idempotencyKey);
|
||||
String requestHash = hash(bookingId + "\n" + request.overseasWarehouseId() + "\n"
|
||||
+ request.expectedVersion() + "\n" + Objects.toString(request.remark(), ""));
|
||||
ReceivingWarehouseOperation replay = receivingWarehouseOperations.findByKey(key);
|
||||
if (replay != null) {
|
||||
if (!bookingId.equals(replay.getSourceContainerBookingId()) || !requestHash.equals(replay.getRequestHash())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||
"Idempotency-Key 已用于其他接柜仓修改请求");
|
||||
}
|
||||
return requireFrozenContainer(orderMapper.findContainerProgress(bookingId));
|
||||
}
|
||||
|
||||
List<LastlegOrder> orders = orderMapper.lockContainerOrders(bookingId);
|
||||
if (orders.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "来源柜不存在");
|
||||
int version = requireSingleAssignmentVersion(orders);
|
||||
if (version != request.expectedVersion()) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "接柜仓分配版本已变化,请刷新后重试");
|
||||
}
|
||||
if (orderMapper.countReceivingSessions(bookingId) > 0) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||
"海外PDA已建立接柜会话,接柜仓已永久锁定");
|
||||
}
|
||||
WarehouseResourceGateway.WarehouseReference warehouse =
|
||||
warehouseResourceGateway.requireActiveSharedWarehouse(request.overseasWarehouseId());
|
||||
int updated = orderMapper.updateContainerReceivingWarehouse(bookingId,
|
||||
Long.toString(warehouse.warehouseId()), warehouse.warehouseCode(), warehouse.warehouseName(), version);
|
||||
if (updated != orders.size()) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "柜内接柜仓分配发生并发变化");
|
||||
}
|
||||
orderMapper.updateContainerPlanReceivingWarehouse(bookingId, warehouse.warehouseId());
|
||||
ReceivingWarehouseOperation operation = new ReceivingWarehouseOperation();
|
||||
operation.setId(IdWorker.getId()); operation.setSourceContainerBookingId(bookingId);
|
||||
operation.setIdempotencyKey(key); operation.setRequestHash(requestHash);
|
||||
operation.setResultVersion(version + 1); operation.setOperatorName(operatorName);
|
||||
operation.setRemark(request.remark() == null ? null : request.remark().trim());
|
||||
operation.setCreatedAt(LocalDateTime.now()); receivingWarehouseOperations.insert(operation);
|
||||
return requireFrozenContainer(orderMapper.findContainerProgress(bookingId));
|
||||
}
|
||||
|
||||
private ContainerPlanProgressSummary requireFrozenContainer(ContainerPlanProgressSummary summary) {
|
||||
if (summary == null) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "来源柜不存在");
|
||||
try {
|
||||
ContainerNumbers.requireCanonical(summary.containerNo());
|
||||
if (!StringUtils.hasText(summary.overseasWarehouseId())
|
||||
|| !StringUtils.hasText(summary.overseasWarehouseCode())
|
||||
|| !StringUtils.hasText(summary.overseasWarehouseName()) || summary.assignmentVersion() < 0) {
|
||||
throw new IllegalArgumentException("receiving warehouse assignment drift");
|
||||
}
|
||||
return summary;
|
||||
} catch (IllegalArgumentException exception) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||
@@ -109,6 +164,42 @@ public class LastlegOrderService {
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeBookingId(String value) {
|
||||
String result = value == null ? null : value.trim();
|
||||
if (!StringUtils.hasText(result) || result.length() > 128) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "来源柜预订ID不能为空");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String normalizeIdempotencyKey(String value) {
|
||||
String result = value == null ? null : value.trim();
|
||||
if (!StringUtils.hasText(result) || result.length() > 255) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Idempotency-Key 必填且不得超过255字符");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int requireSingleAssignmentVersion(List<LastlegOrder> orders) {
|
||||
Integer version = orders.get(0).getReceivingWarehouseVersion();
|
||||
if (version == null || orders.stream().anyMatch(order -> !Objects.equals(version,
|
||||
order.getReceivingWarehouseVersion()) || !StringUtils.hasText(order.getOverseasWarehouseId())
|
||||
|| !StringUtils.hasText(order.getOverseasWarehouseCode())
|
||||
|| !StringUtils.hasText(order.getOverseasWarehouseName()))) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "柜内接柜仓分配事实不一致");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private String hash(String value) {
|
||||
try {
|
||||
return java.util.HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
|
||||
.digest(value.getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (Exception exception) {
|
||||
throw new IllegalStateException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public LastlegOrderDetailResponse detail(String customerId, long orderId) {
|
||||
LastlegOrder order = findOwned(customerId, orderId);
|
||||
List<LastlegOrderDetail> cargo = detailMapper.selectList(new LambdaQueryWrapper<LastlegOrderDetail>()
|
||||
@@ -434,7 +525,7 @@ public class LastlegOrderService {
|
||||
return new LastlegOrderSummary(o.getId(), o.getOrderNo(), o.getOrderType(),
|
||||
LastlegOrderType.labelOf(o.getOrderType()), o.getDestinationType(), o.getSourceInboundId(),
|
||||
displayInboundCode(o), o.getLxCode(), o.getSourceOrderNo(), o.getCustomerId(), o.getCustomerName(), o.getOverseasWarehouseId(),
|
||||
o.getOverseasWarehouseName(), o.getTransferWarehouseId(), o.getTransferWarehouseCode(),
|
||||
o.getOverseasWarehouseCode(), o.getOverseasWarehouseName(), o.getTransferWarehouseId(), o.getTransferWarehouseCode(),
|
||||
o.getTransferWarehouseName(), o.getFbaWarehouseCode(), o.getContainerNo(), o.getContainerStatus(),
|
||||
o.getAbnormal(), o.getDetained(), o.getPalletCount(), o.getPackageCount(), o.getVolumeCbm(),
|
||||
o.getProductQuantity(), o.getVolumeWeightKg(), o.getEstimatedArrivalAt(), o.getActualArrivalAt(),
|
||||
|
||||
Reference in New Issue
Block a user