我来为您提供一个完整的Java WMS系统架构和核心代码实现。
系统架构设计
```java
// 核心领域模型 - 仓库基础信息
@Entity
@Table(name = "wms_warehouse")
public class Warehouse {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String code; // 仓库编码
private String name; // 仓库名称
private String type; // 仓库类型:AUTO-自动化, MANUAL-手动
private Integer status; // 状态:1-启用, 0-停用
// 自动化设备配置
@Embedded
private AutomationConfig automationConfig;
// getters and setters
}
// 自动化设备配置
@Embeddable
public class AutomationConfig {
private Boolean hasConveyor; // 是否有输送线
private Boolean hasRobotArm; // 是否有机械臂
private Boolean hasStacker; // 是否有堆垛机
private Boolean hasElevator; // 是否有提升机
private String wcsEndpoint; // WCS系统接口地址
}
```
核心入库管理
```java
@Service
@Transactional
public class InboundService {
@Autowired
private InventoryService inventoryService;
@Autowired
private WcsService wcsService;
@Autowired
private ErpService erpService;
/**
* 创建入库单
*/
public InboundOrder createInboundOrder(InboundRequest request) {
// 1. 验证数据
validateInboundRequest(request);
// 2. 创建入库单
InboundOrder order = new InboundOrder();
order.setOrderNo(generateOrderNo());
order.setStatus(OrderStatus.CREATED);
order.setSourceSystem(request.getSourceSystem());
order.setReferenceNo(request.getReferenceNo());
// 3. 保存入库单明细
List<InboundOrderDetail> details = request.getDetails().stream()
.map(detail -> createOrderDetail(order, detail))
.collect(Collectors.toList());
order.setDetails(details);
inboundOrderRepository.save(order);
// 4. 通知ERP系统
erpService.confirmInboundOrderCreated(order);
return order;
}
/**
* 执行入库操作
*/
public void executeInbound(Long orderId) {
InboundOrder order = inboundOrderRepository.findById(orderId)
.orElseThrow(() -> new BusinessException("入库单不存在"));
// 1. 分配库位
List<LocationAllocation> allocations = allocateLocations(order);
// 2. 生成设备任务
List<EquipmentTask> tasks = generateEquipmentTasks(order, allocations);
// 3. 下发任务到WCS
wcsService.dispatchTasks(tasks);
// 4. 更新订单状态
order.setStatus(OrderStatus.EXECUTING);
inboundOrderRepository.save(order);
}
/**
* 入库完成回调
*/
@Async
public void handleInboundComplete(WcsTaskCompleteEvent event) {
// 1. 更新库存
inventoryService.updateInventoryOnInbound(
event.getOrderId(),
event.getSkuCode(),
event.getQuantity(),
event.getLocationCode()
);
// 2. 更新订单状态
InboundOrder order = inboundOrderRepository.findById(event.getOrderId())
.orElseThrow(() -> new BusinessException("入库单不存在"));
updateOrderProgress(order, event);
// 3. 如果全部完成,通知ERP
if (order.isCompleted()) {
erpService.notifyInboundComplete(order);
}
}
}
```
出库管理
```java
@Service
public class OutboundService {
/**
* 创建出库单
*/
public OutboundOrder createOutboundOrder(OutboundRequest request) {
// 1. 库存预占
InventoryReservation reservation = inventoryService
.reserveInventory(request.getSkuCode(), request.getQuantity());
if (!reservation.isSuccess()) {
throw new BusinessException("库存不足,出库单创建失败");
}
// 2. 创建出库单
OutboundOrder order = new OutboundOrder();
order.setOrderNo(generateOutboundOrderNo());
order.setStatus(OrderStatus.CREATED);
order.setReservationId(reservation.getReservationId());
// 3. 生成拣货任务
List<PickingTask> pickingTasks = generatePickingTasks(order, reservation);
order.setPickingTasks(pickingTasks);
outboundOrderRepository.save(order);
return order;
}
/**
* 执行出库拣选
*/
public void executePicking(Long orderId) {
OutboundOrder order = outboundOrderRepository.findById(orderId)
.orElseThrow(() -> new BusinessException("出库单不存在"));
// 1. 生成设备任务
List<EquipmentTask> tasks = order.getPickingTasks().stream()
.map(this::convertToEquipmentTask)
.collect(Collectors.toList());
// 2. 下发到WCS执行
wcsService.dispatchTasks(tasks);
// 3. 更新状态
order.setStatus(OrderStatus.PICKING);
outboundOrderRepository.save(order);
}
/**
* 出库确认
*/
public void confirmOutbound(Long orderId) {
OutboundOrder order = outboundOrderRepository.findById(orderId)
.orElseThrow(() -> new BusinessException("出库单不存在"));
// 1. 扣减库存
inventoryService.deductReservedInventory(order.getReservationId());
// 2. 更新状态
order.setStatus(OrderStatus.COMPLETED);
order.setActualOutboundTime(LocalDateTime.now());
// 3. 通知ERP系统
erpService.notifyOutboundComplete(order);
}
}
```
库存管理
```java
@Service
public class InventoryService {
@Autowired
private InventoryRepository inventoryRepository;
/**
* 库存查询
*/
public InventorySummary getInventorySummary(String skuCode) {
List<Inventory> inventories = inventoryRepository.findBySkuCode(skuCode);
InventorySummary summary = new InventorySummary();
summary.setSkuCode(skuCode);
summary.setTotalQuantity(calculateTotalQuantity(inventories));
summary.setAvailableQuantity(calculateAvailableQuantity(inventories));
summary.setReservedQuantity(calculateReservedQuantity(inventories));
summary.setLocations(groupByLocation(inventories));
return summary;
}
/**
* 库存移动
*/
public void moveInventory(InventoryMoveRequest request) {
// 1. 验证源库位库存
Inventory source = inventoryRepository
.findByLocationCodeAndSkuCode(request.getFromLocation(), request.getSkuCode())
.orElseThrow(() -> new BusinessException("源库位库存不存在"));
if (source.getAvailableQuantity() < request.getQuantity()) {
throw new BusinessException("源库位库存不足");
}
// 2. 扣减源库位
source.setAvailableQuantity(source.getAvailableQuantity() - request.getQuantity());
inventoryRepository.save(source);
// 3. 增加目标库位
Inventory target = inventoryRepository
.findByLocationCodeAndSkuCode(request.getToLocation(), request.getSkuCode())
.orElseGet(() -> createNewInventory(request));
target.setAvailableQuantity(target.getAvailableQuantity() + request.getQuantity());
inventoryRepository.save(target);
// 4. 记录库存移动日志
logInventoryMovement(request);
}
/**
* 库存盘点
*/
public StockCountResult executeStockCount(StockCountRequest request) {
// 1. 生成盘点任务
StockCountTask task = createStockCountTask(request);
// 2. 锁定库存
lockInventoryForCounting(task.getLocationCodes());
// 3. 执行盘点(自动化设备或人工)
if (isAutomatedWarehouse(request.getWarehouseCode())) {
// 使用自动化设备盘点
wcsService.executeStockCount(task);
} else {
// 人工盘点
manualStockCountService.executeCount(task);
}
// 4. 处理盘点结果
return processStockCountResult(task);
}
}
```
设备调度集成
```java
@Service
public class WcsService {
@Autowired
private RestTemplate restTemplate;
@Value("${wcs.endpoint}")
private String wcsEndpoint;
/**
* 下发任务到WCS
*/
public void dispatchTasks(List<EquipmentTask> tasks) {
WcsTaskRequest request = new WcsTaskRequest();
request.setTasks(tasks);
request.setTimestamp(LocalDateTime.now());
try {
ResponseEntity<WcsResponse> response = restTemplate.postForEntity(
wcsEndpoint + "/api/tasks/dispatch",
request,
WcsResponse.class
);
if (!response.getStatusCode().is2xxSuccessful() ||
!response.getBody().isSuccess()) {
throw new BusinessException("WCS任务下发失败: " + response.getBody().getMessage());
}
// 更新任务状态
updateTaskStatus(tasks, TaskStatus.DISPATCHED);
} catch (Exception e) {
log.error("WCS接口调用失败", e);
throw new BusinessException("设备调度系统通信失败");
}
}
/**
* 处理WCS任务完成回调
*/
@PostMapping("/wcs/callback/task-complete")
public ResponseEntity<?> handleTaskComplete(@RequestBody WcsTaskCompleteEvent event) {
log.info("收到WCS任务完成回调: {}", event);
// 根据任务类型处理
switch (event.getTaskType()) {
case INBOUND:
inboundService.handleInboundComplete(event);
break;
case OUTBOUND:
outboundService.handleOutboundComplete(event);
break;
case MOVEMENT:
inventoryService.handleMovementComplete(event);
break;
case COUNT:
stockCountService.handleCountComplete(event);
break;
}
return ResponseEntity.ok().build();
}
}
```
ERP/MES系统集成
```java
@Service
public class ErpService {
@Autowired
private ErpClient erpClient;
/**
* 同步物料信息
*/
public void syncMaterialInfo(String materialCode) {
try {
MaterialInfo material = erpClient.getMaterialInfo(materialCode);
materialService.syncMaterial(material);
} catch (Exception e) {
log.error("ERP物料信息同步失败: {}", materialCode, e);
throw new BusinessException("ERP系统通信失败");
}
}
/**
* 通知入库完成
*/
public void notifyInboundComplete(InboundOrder order) {
ErpInboundCompleteRequest request = new ErpInboundCompleteRequest();
request.setOrderNo(order.getOrderNo());
request.setReferenceNo(order.getReferenceNo());
request.setCompletedTime(LocalDateTime.now());
request.setDetails(convertToErpDetails(order.getDetails()));
erpClient.notifyInboundComplete(request);
}
}
// ERP接口客户端
@Component
public class ErpClient {
@Value("${erp.endpoint}")
private String erpEndpoint;
@Autowired
private RestTemplate restTemplate;
public MaterialInfo getMaterialInfo(String materialCode) {
String url = String.format("%s/api/materials/%s", erpEndpoint, materialCode);
ResponseEntity<ErpResponse<MaterialInfo>> response = restTemplate
.getForEntity(url, new ParameterizedTypeReference<ErpResponse<MaterialInfo>>() {});
if (response.getStatusCode().is2xxSuccessful() &&
response.getBody() != null &&
response.getBody().isSuccess()) {
return response.getBody().getData();
}
throw new BusinessException("获取ERP物料信息失败");
}
}
```
系统配置
```java
@Configuration
public class WmsConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
// 配置超时时间
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(30000);
restTemplate.setRequestFactory(factory);
// 添加拦截器
restTemplate.getInterceptors().add(new LoggingInterceptor());
return restTemplate;
}
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("wms-async-");
executor.initialize();
return executor;
}
}
```
这个WMS系统实现了:
1. 完整的入库/出库流程管理
2. 实时库存管理
3. 自动化设备集成
4. ERP/MES系统对接
5. 任务调度和状态跟踪
系统采用Spring Boot + JPA技术栈,支持高并发处理,具备良好的扩展性和可维护性。
2810

被折叠的 条评论
为什么被折叠?



