代码更新

This commit is contained in:
梁州 2024-07-19 16:50:18 +08:00
parent 380a0c1bf4
commit e27702f8ce
20 changed files with 1252 additions and 815 deletions

View File

@ -157,6 +157,7 @@
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
<version>3.2.1</version> <version>3.2.1</version>
</dependency> </dependency>
<!-- 邮件 -->
<dependency> <dependency>
<groupId>javax.mail</groupId> <groupId>javax.mail</groupId>
<artifactId>mail</artifactId> <artifactId>mail</artifactId>
@ -167,6 +168,12 @@
<artifactId>ews-java-api</artifactId> <artifactId>ews-java-api</artifactId>
<version>2.0</version> <version>2.0</version>
</dependency> </dependency>
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -7,6 +7,9 @@ import org.springframework.context.annotation.Configuration;
import java.util.Properties; import java.util.Properties;
/**
* 分页配置
*/
@SpringBootConfiguration @SpringBootConfiguration
public class PageHelperConfig { public class PageHelperConfig {
@Bean @Bean

View File

@ -3,7 +3,8 @@ package com.wms.constants.enums;
public enum ConfigMapKeyEnum { public enum ConfigMapKeyEnum {
MAX_WEIGHT("MAX_WEIGHT"), MAX_WEIGHT("MAX_WEIGHT"),
URL_WCS_TASK("URL_WCS_TASK"), URL_WCS_TASK("URL_WCS_TASK"),
URL_NEW_DESTINATION("URL_NEW_DESTINATION"); URL_NEW_DESTINATION("URL_NEW_DESTINATION"),
URL_WCS_PICK_TASK("URL_WCS_PICK_TASK");
private final String configKey; private final String configKey;
ConfigMapKeyEnum(String configKey) { ConfigMapKeyEnum(String configKey) {
this.configKey = configKey; this.configKey = configKey;

View File

@ -0,0 +1,25 @@
package com.wms.constants.enums;
public enum PickTaskStatusEnum {
TEMP(-1, "暂存"),
NEW(0, "初始化"),
SEND(1, "已发送"),
FINISH(2, "已完成");
private final Integer code;
private final String value;
PickTaskStatusEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -1,13 +1,22 @@
package com.wms.controller; package com.wms.controller;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.*; import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity; import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.LocationDto;
import com.wms.entity.app.dto.StockDto; import com.wms.entity.app.dto.StockDto;
import com.wms.entity.app.dto.TaskRecordDto; import com.wms.entity.app.dto.TaskRecordDto;
import com.wms.entity.app.dto.VehicleDto;
import com.wms.entity.app.request.LocationQuery;
import com.wms.entity.app.request.StockQuery; import com.wms.entity.app.request.StockQuery;
import com.wms.entity.app.request.TaskRecordQuery; import com.wms.entity.app.request.TaskRecordQuery;
import com.wms.entity.app.request.VehicleQuery;
import com.wms.entity.table.Location;
import com.wms.entity.table.Vehicle;
import com.wms.service.*; import com.wms.service.*;
import com.wms.utils.StringUtils;
import com.wms.utils.excel.ExcelUtils; import com.wms.utils.excel.ExcelUtils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@ -23,6 +32,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.Collections;
import java.util.List; import java.util.List;
import static com.wms.utils.HttpUtils.getIpAddr; import static com.wms.utils.HttpUtils.getIpAddr;
@ -36,10 +46,12 @@ import static com.wms.utils.StringUtils.convertJsonString;
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/wms/excel") @RequestMapping(value = "/wms/excel")
public class ExcelController { public class ExcelController {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
private final StockService stockService;// 库存服务 private final StockService stockService;// 库存服务
private final HttpServletRequest servletRequest;// 请求服务 private final HttpServletRequest servletRequest;// 请求服务
private final TaskRecordService taskRecordService;// 任务记录服务 private final TaskRecordService taskRecordService;// 任务记录服务
private final VehicleService vehicleService;// 载具服务
private final LocationService locationService;// 库位服务
/** /**
* 导入库存信息 * 导入库存信息
@ -54,6 +66,7 @@ public class ExcelController {
logger.info("导入库存请求ip{}", getIpAddr(servletRequest)); logger.info("导入库存请求ip{}", getIpAddr(servletRequest));
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
List<StockDto> stocksDto = ExcelUtils.readMultipartFile(file, StockDto.class);
response.setCode(ResponseCode.OK.getCode()); response.setCode(ResponseCode.OK.getCode());
response.setMessage("导入库存成功"); response.setMessage("导入库存成功");
response.setReturnData(file); response.setReturnData(file);
@ -118,4 +131,46 @@ public class ExcelController {
List<TaskRecordDto> inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO()); List<TaskRecordDto> inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO());
ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class); ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class);
} }
/**
* 导出载具记录
*
* @param response 请求
*/
@GetMapping("/downloadVehicleExcel")
@ResponseBody
public void downloadVehicleExcel(@RequestParam("vehicleQuery") VehicleQuery vehicleQuery, HttpServletResponse response) {
logger.info("导出载具记录,查询参数:{}请求ip{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest));
List<Vehicle> vehicles = vehicleService.list(new LambdaQueryWrapper<Vehicle>()
.like(StringUtils.isNotEmpty(vehicleQuery.getVehicleId()), Vehicle::getVehicleId, vehicleQuery.getVehicleId())
.like(StringUtils.isNotEmpty(vehicleQuery.getCurrentLocation()), Vehicle::getCurrentLocation, vehicleQuery.getCurrentLocation())
.eq(vehicleQuery.getIsEmpty() != null, Vehicle::getIsEmpty, vehicleQuery.getIsEmpty())
.eq(vehicleQuery.getVehicleStatus() != null, Vehicle::getVehicleStatus, vehicleQuery.getVehicleStatus()));
if (vehicles == null || vehicles.isEmpty()) {
ExcelUtils.export(response, "载具报表", Collections.emptyList(), VehicleDto.class);
} else {
ExcelUtils.export(response, "载具报表", BeanUtil.copyToList(vehicles, VehicleDto.class), VehicleDto.class);
}
}
/**
* 导出库位详情
*
* @param response 请求
*/
@GetMapping("/downloadLocationsExcel")
@ResponseBody
public void downloadLocationsExcel(@RequestParam("locationQuery") LocationQuery locationQuery, HttpServletResponse response) {
logger.info("导出库位详情,查询参数:{}请求ip{}", convertJsonString(locationQuery), getIpAddr(servletRequest));
List<Location> locations = locationService.list(new LambdaQueryWrapper<Location>()
.like(StringUtils.isNotEmpty(locationQuery.getLocationId()), Location::getLocationId, locationQuery.getLocationId())
.eq(locationQuery.getAreaId() != null, Location::getAreaId, locationQuery.getAreaId())
.eq(locationQuery.getIsLock() != null, Location::getIsLock, locationQuery.getIsLock())
.eq(locationQuery.getLocationStatus() != null, Location::getLocationStatus, locationQuery.getLocationStatus()));
if (locations == null || locations.isEmpty()) {
ExcelUtils.export(response, "库位报表", Collections.emptyList(), LocationDto.class);
} else {
ExcelUtils.export(response, "库位报表", BeanUtil.copyToList(locations, LocationDto.class), LocationDto.class);
}
}
} }

View File

@ -1,20 +1,10 @@
package com.wms.controller; package com.wms.controller;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.TaskDto;
import com.wms.entity.app.wcs.WcsTaskRequest;
import com.wms.entity.table.Stand; import com.wms.entity.table.Stand;
import com.wms.entity.table.Task;
import com.wms.entity.table.WmsLog;
import com.wms.service.*; import com.wms.service.*;
import com.wms.service.business.IWmsJobService;
import com.wms.service.business.IWorkService; import com.wms.service.business.IWorkService;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import com.wms.utils.WmsUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -28,11 +18,8 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import static com.wms.utils.StringUtils.convertJsonString; import static com.wms.utils.StringUtils.convertJsonString;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import static com.wms.config.InitLocalConfig.configMap;
/** /**
* 定期任务类 * 定期任务类
*/ */
@ -41,21 +28,9 @@ import static com.wms.config.InitLocalConfig.configMap;
public class JobComponent { public class JobComponent {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
/** /**
* 任务服务 * WMS定时任务服务
*/ */
private final TaskService taskService; private final IWmsJobService wmsJobService;
/**
* 库存服务
*/
private final StockService stockService;
/**
* 任务记录服务
*/
private final TaskRecordService taskRecordService;
/**
* 日志服务
*/
private final LogService logService;
/** /**
* 站台服务 * 站台服务
*/ */
@ -70,60 +45,61 @@ public class JobComponent {
* 向Wcs下发任务 * 向Wcs下发任务
* 每2秒执行一次 * 每2秒执行一次
*/ */
// @Scheduled(fixedDelay = 2000) @Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void executeTasks() { public void executeTasks() {
try {
// 发送正常任务 // 发送正常任务
sendCommonTasks(); wmsJobService.sendCommonTasks();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
try {
// 发送拣选任务 // 发送拣选任务
sendPickTasks(); wmsJobService.sendPickTasks();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
try {
// 针对重复入库的任务发送新的目的地 // 针对重复入库的任务发送新的目的地
solveDuplicateTask(); wmsJobService.solveDuplicateTask();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
} }
/** /**
* 检测工作 * 检测工作
*/ */
// @Scheduled(fixedDelay = 2000) @Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void detectWork() { public void detectWork() {
try {
// 轮询工作站台判断是否需要下发任务 // 轮询工作站台判断是否需要下发任务
List<Stand> stands = standService.list(new LambdaQueryWrapper<Stand>() List<Stand> stands = standService.list(new LambdaQueryWrapper<Stand>()
.eq(Stand::getStandType, 2)); .eq(Stand::getStandType, 2));
for (Stand workStation : stands) { for (Stand workStation : stands) {
try {
// 创建工作 // 创建工作
workService.createWork(workStation.getStandId()); workService.createWork(workStation.getStandId());
// 执行工作
workService.doWork(workStation.getStandId());
}
} catch (Exception e) { } catch (Exception e) {
// 回滚事务 // 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("检测工作时发生错误:{}", convertJsonString(e)); logger.error("创建工作时发生错误:{}", convertJsonString(e));
}
try {
// 执行工作
workService.doWork(workStation.getStandId());
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("执行工作时发生错误:{}", convertJsonString(e));
}
} }
} }
// /**
// * 每天查询一次是否有过期的库存
// * 每天晚上8点执行一次
// */
//// @Scheduled(cron = "0 0 20 * * ?")
// public void detectOutOfDateStock() {
// logger.info("执行定时任务:查询过期库存");
// List<StockDto> outOfDateStocks = stockService.selStockOutOfDate();
// if (outOfDateStocks.size() > 0) {
// logger.info("过期库存数量不为0准备更新过期库存");
// for (StockDto outOfDateStock : outOfDateStocks) {
// try {
// outOfDateStock.setGoodsStatus(GoodsStatus.OVERDUE.getCode());
// stockService.modifyStock(outOfDateStock);
// logger.info("过期库存更新成功");
// } catch (Exception e) {
// logger.error("过期库存更新异常:{}", e.getMessage());
// }
// }
// }
// }
// //
// /** // /**
// * 每天查询一次是否有入库后长期未使用的库存 // * 每天查询一次是否有入库后长期未使用的库存
@ -161,223 +137,4 @@ public class JobComponent {
// logger.info("删除过期日志数据失败"); // logger.info("删除过期日志数据失败");
// } // }
// } // }
/**
* 发送正常的任务
*/
private void sendCommonTasks() {
try {
// 检索任务表---新建未下发的任务
LambdaQueryWrapper<Task> waitForDistributeTaskQuery = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode());
List<TaskDto> allTasks = BeanUtil.copyToList(taskService.list(waitForDistributeTaskQuery), TaskDto.class);
// 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表
List<String> taskGroupIds = new ArrayList<>();
if (!allTasks.isEmpty()) {
for (TaskDto task : allTasks) {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
continue;
}
}
if (taskGroupIds.contains(task.getTaskGroup())) {
// 已经发送过的任务组直接设置状态
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
}
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) {
tempTask.setTaskType(TaskType.OUT.getCode());
} else {
tempTask.setTaskType(task.getTaskType());
}
tempTask.setOrigin(task.getOrigin());
tempTask.setDestination(task.getDestination());
tempTask.setVehicleNo(task.getVehicleId());
tempTask.setVehicleSize(task.getVehicleSize());
tempTask.setWeight(task.getWeight());
tempTask.setPriority(task.getTaskPriority());
request.add(tempTask);
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.size() == 0) {
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
taskService.saveBatch(BeanUtil.copyToList(allTasks, Task.class));
} else {
if (result != null) {
logger.error("存在错误:{}", result.getMessage());
} else {
logger.error("请求无返回");
}
}
} else {
logger.error("WCS发送任务地址为空");
}
}
} catch (Exception exception) {
logger.error("向Wcs发送任务时发生异常{}", convertJsonString(exception));
}
}
/**
* 发送拣选任务
*/
private void sendPickTasks() {
try {
// 检索任务表---新建未下发的任务
LambdaQueryWrapper<Task> waitForDistributeTaskQuery = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode());
List<TaskDto> allTasks = BeanUtil.copyToList(taskService.list(waitForDistributeTaskQuery), TaskDto.class);
// 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表
List<String> taskGroupIds = new ArrayList<>();
if (!allTasks.isEmpty()) {
for (TaskDto task : allTasks) {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
continue;
}
}
if (taskGroupIds.contains(task.getTaskGroup())) {
// 已经发送过的任务组直接设置状态
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
}
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) {
tempTask.setTaskType(TaskType.OUT.getCode());
} else {
tempTask.setTaskType(task.getTaskType());
}
tempTask.setOrigin(task.getOrigin());
tempTask.setDestination(task.getDestination());
tempTask.setVehicleNo(task.getVehicleId());
tempTask.setVehicleSize(task.getVehicleSize());
tempTask.setWeight(task.getWeight());
tempTask.setPriority(task.getTaskPriority());
request.add(tempTask);
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.size() == 0) {
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
taskService.saveBatch(BeanUtil.copyToList(allTasks, Task.class));
} else {
if (result != null) {
logger.error("存在错误:{}", result.getMessage());
} else {
logger.error("请求无返回");
}
}
} else {
logger.error("WCS发送任务地址为空");
}
}
} catch (Exception exception) {
logger.error("向Wcs发送任务时发生异常{}", convertJsonString(exception));
}
}
/**
* 处理重复入库的任务
*/
private void solveDuplicateTask() {
try {
// 检索任务表---新建未下发的任务
LambdaQueryWrapper<Task> duplicateTaskQueryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskType, TaskType.IN.getCode())
.eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode());
List<TaskDto> duplicateTasks = BeanUtil.copyToList(taskService.list(duplicateTaskQueryWrapper), TaskDto.class);
// 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表
List<String> taskGroupIds = new ArrayList<>();
if (!duplicateTasks.isEmpty()) {
for (TaskDto task : duplicateTasks) {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
continue;
}
}
if (taskGroupIds.contains(task.getTaskGroup())) {
// 已经发送过的任务组直接设置状态
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
}
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
tempTask.setDestination(task.getDestination());
tempTask.setVehicleNo(task.getVehicleId());
request.add(tempTask);
task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.size() == 0) {
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_NEW_DESTINATION.getConfigKey());
if (url != null) {
logger.info("向WCS发送新目的地地址{},请求详情:{}", url, convertJsonString(request));
request.forEach(wcsTaskRequest -> {
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(wcsTaskRequest)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送新目的地", "setStackerTaskNewDestination", JSON.toJSONString(wcsTaskRequest), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
taskService.saveBatch(BeanUtil.copyToList(duplicateTasks, Task.class));
} else {
if (result != null) {
logger.error("存在错误:{}", result.getMessage());
} else {
logger.error("请求无返回");
}
}
});
} else {
logger.error("向WCS发送新目的地的地址为空");
}
}
} catch (Exception exception) {
logger.error("向WCS发送新目的地时发生异常{}", convertJsonString(exception));
}
}
} }

View File

@ -4,22 +4,24 @@ import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms.annotation.MyLog; import com.wms.annotation.MyLog;
import com.wms.constants.enums.*; import com.wms.constants.enums.*;
import com.wms.entity.app.*; import com.wms.entity.app.*;
import com.wms.entity.app.dto.PageDto;
import com.wms.entity.app.dto.extend.StockDetailInfo; import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.app.dto.extend.TaskDetailInfo;
import com.wms.entity.app.request.GoodsInRequest;
import com.wms.entity.app.request.TaskInRequest; import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest; import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.app.request.TaskQuery;
import com.wms.entity.app.vo.TaskVO;
import com.wms.entity.app.wcs.WcsTaskResultRequest; import com.wms.entity.app.wcs.WcsTaskResultRequest;
import com.wms.entity.app.wcs.WcsVehicleInRequest; import com.wms.entity.app.wcs.WcsVehicleInRequest;
import com.wms.entity.table.*; import com.wms.entity.table.*;
import com.wms.service.*; import com.wms.service.*;
import com.wms.service.business.IValidateService;
import com.wms.service.business.IWmsTaskService;
import com.wms.utils.HttpUtils; import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils; import com.wms.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -32,11 +34,9 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import static com.wms.config.InitLocalConfig.configMap;
import static com.wms.utils.StringUtils.convertJsonString; import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId; import static com.wms.utils.WmsUtils.generateId;
@ -68,22 +68,26 @@ public class TaskController {
* 任务记录服务 * 任务记录服务
*/ */
private final TaskRecordService taskRecordService; private final TaskRecordService taskRecordService;
/**
* 站台服务
*/
private final StandService standService;
/**
* 物料服务
*/
private final GoodsService goodsService;
/** /**
* 载具服务 * 载具服务
*/ */
private final VehicleService vehicleService; private final VehicleService vehicleService;
/**
* 拣选任务服务
*/
private final PickTaskService pickTaskService;
/** /**
* 请求头部信息 * 请求头部信息
*/ */
private final HttpServletRequest servletRequest; private final HttpServletRequest servletRequest;
/**
* WMS任务服务
*/
private final IWmsTaskService wmsTaskService;
/**
* 验证服务
*/
private final IValidateService validateService;
/** /**
* 接收入库任务请求 * 接收入库任务请求
@ -101,7 +105,7 @@ public class TaskController {
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
// 验证入库请求 // 验证入库请求
String validationInfo = validateTaskInRequest(taskInRequest); String validationInfo = validateService.validateTaskInRequest(taskInRequest);
if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) { if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) {
logger.error("入库请求验证错误!{}", validationInfo); logger.error("入库请求验证错误!{}", validationInfo);
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());
@ -111,9 +115,9 @@ public class TaskController {
// 生成入库任务 // 生成入库任务
String saveTaskResult; String saveTaskResult;
if (taskInRequest.getGoodsList() == null || taskInRequest.getGoodsList().isEmpty()) {// 空托入库 if (taskInRequest.getGoodsList() == null || taskInRequest.getGoodsList().isEmpty()) {// 空托入库
saveTaskResult = genEmptyInTask(taskInRequest); saveTaskResult = wmsTaskService.genEmptyInTask(taskInRequest);
} else {// 带料入库 } else {// 带料入库
saveTaskResult = genGoodsInTask(taskInRequest); saveTaskResult = wmsTaskService.genGoodsInTask(taskInRequest);
} }
if (!saveTaskResult.equals("")) { if (!saveTaskResult.equals("")) {
// 返回失败 // 返回失败
@ -138,149 +142,6 @@ public class TaskController {
} }
} }
/**
* 添加空入库任务
*
* @param taskInRequest 入库请求
* @return 添加结果
*/
private String genEmptyInTask(TaskInRequest taskInRequest) {
String result = "";
Task tempInTask = new Task();
tempInTask.setTaskId(generateId("RK_"));
tempInTask.setTaskType(TaskType.IN.getCode());
tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
tempInTask.setTaskGroup(generateId(""));
tempInTask.setTaskPriority(1);
tempInTask.setVehicleId(taskInRequest.getVehicleId());
tempInTask.setVehicleSize(1);
tempInTask.setWeight(taskInRequest.getTotalWeight());
tempInTask.setCreateTime(LocalDateTime.now());
tempInTask.setUserName(taskInRequest.getUserName());
try {
if (!taskService.save(tempInTask)) {
return "添加空入库任务失败";
}
} catch (Exception e) {
logger.error("添加空入库任务异常:{}", convertJsonString(e));
return "添加空入库任务失败";
}
return result;
}
/**
* 添加入库任务
*
* @param taskInRequest 入库请求
* @return 添加结果
*/
private String genGoodsInTask(TaskInRequest taskInRequest) {
String result = "";
String taskGroupId = generateId("");
List<Task> tempTasks = new ArrayList<>();
for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
Task tempInTask = new Task();
tempInTask.setTaskId(generateId("RK_"));
tempInTask.setTaskType(TaskType.IN.getCode());
tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
tempInTask.setTaskGroup(taskGroupId);
tempInTask.setTaskPriority(1);
tempInTask.setVehicleId(taskInRequest.getVehicleId());
tempInTask.setVehicleSize(1);
tempInTask.setWeight(taskInRequest.getTotalWeight());
tempInTask.setCreateTime(LocalDateTime.now());
tempInTask.setUserName(taskInRequest.getUserName());
// 物料相关信息
TaskDetailInfo goodsRelatedInfo = new TaskDetailInfo();
// TODO 物料信息需要完善
goodsRelatedInfo.setGoodsId(goodsInRequest.getGoodsId());
goodsRelatedInfo.setGoodsName("");
goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum());
goodsRelatedInfo.setOriginNum(BigDecimal.ZERO);
tempInTask.setGoodsRelated(goodsRelatedInfo);
tempTasks.add(tempInTask);
}
try {
if (!taskService.saveBatch(tempTasks)) {
return "添加入库任务失败";
}
} catch (Exception e) {
logger.error("添加入库任务异常:{}", convertJsonString(e));
return "添加入库任务失败";
}
return result;
}
/**
* 验证入库请求
*
* @param taskInRequest 入库请求
* @return 验证结果---空为验证通过否则输出错误信息
*/
private String validateTaskInRequest(TaskInRequest taskInRequest) {
// 验证任务请求
if (taskInRequest == null) {
return TaskInValidationEnum.NO_REQUEST_BODY.getErrorMessage();
}
// 验证载具号
if (StringUtils.isEmpty(taskInRequest.getVehicleId())) {
return TaskInValidationEnum.NO_VEHICLE_ID.getErrorMessage();
}
// 验证载具号是否重复入库
if (vehicleService.exists(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskInRequest.getVehicleId())
.and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())
.or().eq(Vehicle::getVehicleStatus, VehicleStatus.MOVE.getCode())))) {
return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage();
}
// 验证当前载具是否已经有入库任务
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getVehicleId, taskInRequest.getVehicleId())
.and(wrapper -> wrapper.eq(Task::getTaskType, TaskType.IN.getCode())))) {
return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage();
}
// 验证重量
if (taskInRequest.getTotalWeight() == null) {
return TaskInValidationEnum.NO_WEIGHT.getErrorMessage();
}
BigDecimal max_weight = BigDecimal.valueOf(10000000);
try {
max_weight = new BigDecimal(configMap.get(ConfigMapKeyEnum.MAX_WEIGHT.getConfigKey()));
} catch (Exception e) {
logger.error("转换配置项---最大承重,发生错误");
}
if (taskInRequest.getTotalWeight().compareTo(max_weight) > 0) {
// 超重
return TaskInValidationEnum.OVER_WEIGHT.getErrorMessage();
}
// 验证起点
if (StringUtils.isEmpty(taskInRequest.getOriginPoint())) {
return TaskInValidationEnum.NO_IN_POINT.getErrorMessage();
} else {
if (!standService.validateStand(taskInRequest.getOriginPoint(), TaskType.IN.getCode())) {
return TaskInValidationEnum.ERROR_IN_POINT.getErrorMessage();
}
}
// 验证物料信息
if (taskInRequest.getGoodsList() != null && !taskInRequest.getGoodsList().isEmpty()) {
for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
// 验证物料编号
if (StringUtils.isEmpty(goodsInRequest.getGoodsId())) {
return TaskInValidationEnum.NO_GOODS_ID.getErrorMessage();
} else {
if (!goodsService.validateGoodsId(goodsInRequest.getGoodsId())) {
return TaskInValidationEnum.ERROR_GOODS_ID.getErrorMessage();
}
}
// 验证数量
if (goodsInRequest.getGoodsNum() == null || goodsInRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
return TaskInValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
}
}
}
return TaskInValidationEnum.OK.getErrorMessage();
}
/** /**
* 接收出库任务请求 * 接收出库任务请求
* *
@ -297,7 +158,7 @@ public class TaskController {
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
// 验证出库请求 // 验证出库请求
String validationInfo = validateTaskOutRequest(taskOutRequest); String validationInfo = validateService.validateTaskOutRequest(taskOutRequest);
if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) { if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) {
logger.error("出库请求验证错误!{}", validationInfo); logger.error("出库请求验证错误!{}", validationInfo);
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());
@ -307,9 +168,9 @@ public class TaskController {
// 没有物料单纯载具或者库位出库 // 没有物料单纯载具或者库位出库
String genResult; String genResult;
if (StringUtils.isEmpty(taskOutRequest.getGoodsId())) { if (StringUtils.isEmpty(taskOutRequest.getGoodsId())) {
genResult = genVehicleLocationOutTask(taskOutRequest); genResult = wmsTaskService.genVehicleLocationOutTask(taskOutRequest);
} else { } else {
genResult = genGoodsOutTask(taskOutRequest); genResult = wmsTaskService.genGoodsOutTask(taskOutRequest);
} }
if (!genResult.equals("")) { if (!genResult.equals("")) {
logger.error("出库错误!{}", genResult); logger.error("出库错误!{}", genResult);
@ -333,253 +194,6 @@ public class TaskController {
} }
} }
/**
* 生成载具或库位出库任务
*
* @param taskOutRequest 出库请求
* @return 结果
*/
private String genVehicleLocationOutTask(TaskOutRequest taskOutRequest) {
// 查询对应载具
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
// 创建空出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(taskOutRequest.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(currentVehicle.getCurrentLocation());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
taskService.save(vehicleOutTask);
// 对应载具所有库存上锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getVehicleId, taskOutRequest.getVehicleId()));
// 对应载具状态设置
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
} else {
// 查找对应库位
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
// 创建空出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(currentLocation.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(currentLocation.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
taskService.save(vehicleOutTask);
// 对应库位所有库存上锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getLocationId, taskOutRequest.getOriginPoint()));
// 对应库位状态设置
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getCurrentLocation, taskOutRequest.getOriginPoint()));
}
return "";
}
/**
* 生成物料出库任务
*
* @param taskOutRequest 出库请求
* @return 结果
*/
private String genGoodsOutTask(TaskOutRequest taskOutRequest) {
// 查询库存
LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
.apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId())
.apply("goods_related -> '$.remainNum' > 0")
.eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
.eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
List<Stock> stocks = stockService.list(stockQueryWrapper);
List<Task> goodsOutTasks = new ArrayList<>();
BigDecimal needNum = taskOutRequest.getGoodsNum();
for (Stock stock : stocks) {
if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {// 库存状态正常的情况
// 悲观锁锁定库存状态---同一载具下的库存
boolean lockStocksFlag = stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getVehicleId, stock.getVehicleId())
.eq(Stock::getStockStatus, StockStatus.OK.getCode()));
// 锁定载具状态
boolean lockVehicleFlag = vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, stock.getVehicleId())
.eq(Vehicle::getVehicleStatus, VehicleStatus.ON));
if (!lockStocksFlag || !lockVehicleFlag) {
// 释放锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OK.getCode())
.eq(Stock::getVehicleId, stock.getVehicleId())
.eq(Stock::getStockStatus, StockStatus.OK.getCode()));
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())
.eq(Vehicle::getVehicleId, stock.getVehicleId()));
continue;
}
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(stock.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(stock.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
// TODO 设定物料相关信息 需要完善
TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
vehicleOutTask.setGoodsRelated(taskDetailInfo);
goodsOutTasks.add(vehicleOutTask);
needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
} else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) {
// 查询到当前当前载具对应的任务并同步
Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, stock.getVehicleId()));
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
if (sameVehicleTask != null) {
vehicleOutTask.setTaskGroup(sameVehicleTask.getTaskGroup());
vehicleOutTask.setTaskStatus(sameVehicleTask.getTaskStatus());
vehicleOutTask.setTaskPriority(sameVehicleTask.getTaskPriority());
vehicleOutTask.setPreTask(sameVehicleTask.getPreTask());
} else {
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
}
vehicleOutTask.setVehicleId(stock.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(stock.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
// TODO 设定物料相关信息 需要完善
TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
vehicleOutTask.setGoodsRelated(taskDetailInfo);
goodsOutTasks.add(vehicleOutTask);
needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
}
// 盘点,移库,锁定状态不可使用
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
// 库存足够跳出循环
break;
}
}
// 添加任务记录表
taskService.saveBatch(goodsOutTasks);
return "";
}
/**
* 验证出库请求
*
* @param taskOutRequest 出库请求
* @return 验证结果---空为验证通过否则输出错误信息
*/
private String validateTaskOutRequest(TaskOutRequest taskOutRequest) {
// 验证任务
if (taskOutRequest == null) {
return TaskOutValidationEnum.NO_REQUEST_BODY.getErrorMessage();
}
// 验证是否包含请求信息
if (StringUtils.isEmpty(taskOutRequest.getGoodsId())
&& StringUtils.isEmpty(taskOutRequest.getVehicleId())
&& StringUtils.isEmpty(taskOutRequest.getOriginPoint())) {
return TaskOutValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
}
// 验证载具号
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())
&& vehicleService.exists(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()))) {
return TaskOutValidationEnum.ERROR_VEHICLE_ID.getErrorMessage();
}
// 验证库位
if (StringUtils.isNotEmpty(taskOutRequest.getOriginPoint())
&& locationService.exists(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()))) {
return TaskOutValidationEnum.ERROR_ORIGIN_POINT.getErrorMessage();
}
// 验证终点站台
if (taskOutRequest.getIsPicking() == 0) {// 出库
if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 2)) {
return TaskOutValidationEnum.ERROR_DESTINATION_POINT.getErrorMessage();
}
} else {// 拣选出库
if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 3)) {
return TaskOutValidationEnum.ERROR_PICK_STAND.getErrorMessage();
}
}
// 验证物料信息
if (StringUtils.isNotEmpty(taskOutRequest.getGoodsId())) {
if (taskOutRequest.getGoodsNum() == null || taskOutRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
return TaskOutValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
}
// 查询库存信息
LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
.apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId())
.apply("goods_related -> '$.remainNum' > 0")
.eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
.eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
if (!stockService.exists(stockQueryWrapper)) {
return TaskOutValidationEnum.NO_STOCK.getErrorMessage();
}
} else {
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, currentVehicle.getCurrentLocation()));
if (!Objects.equals(currentVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) {
return TaskOutValidationEnum.ERROR_VEHICLE_STATUS.getErrorMessage();
}
if (!Objects.equals(currentLocation.getIsLock(), 1)) {
return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
}
} else {
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
if (!Objects.equals(currentLocation.getIsLock(), 1)) {
return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
}
if (!Objects.equals(currentLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode())) {
return TaskOutValidationEnum.ERROR_ORIGIN_POINT_STATUS.getErrorMessage();
}
}
}
return TaskOutValidationEnum.OK.getErrorMessage();
}
/** /**
* 接收任务反馈 * 接收任务反馈
* *
@ -595,7 +209,7 @@ public class TaskController {
// 创建响应信息 // 创建响应信息
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
String validateInfo = validateTaskResult(wcsTaskResultRequest); String validateInfo = validateService.validateTaskResult(wcsTaskResultRequest);
if (!Objects.equals(validateInfo, TaskResultValidationEnum.OK.getErrorMessage())) { if (!Objects.equals(validateInfo, TaskResultValidationEnum.OK.getErrorMessage())) {
logger.error("任务反馈请求验证失败:{}", validateInfo); logger.error("任务反馈请求验证失败:{}", validateInfo);
// 返回其他异常 // 返回其他异常
@ -730,10 +344,6 @@ public class TaskController {
continue; continue;
} }
if (outTask.getIsPicking() == 1) { if (outTask.getIsPicking() == 1) {
// 拣选任务更新任务状态
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.PICKING.getCode())
.eq(Task::getTaskId, outTask.getTaskId()));
// 当前载具上所有库存状态设置为拣选 // 当前载具上所有库存状态设置为拣选
stockService.update(new LambdaUpdateWrapper<Stock>() stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.PICKING.getCode()) .set(Stock::getStockStatus, StockStatus.PICKING.getCode())
@ -744,18 +354,23 @@ public class TaskController {
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, outTask.getVehicleId()) .eq(Vehicle::getVehicleId, outTask.getVehicleId())
.ne(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())); .ne(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()));
} else { // 将该载具对应的拣选任务设置为可发送状态
// 添加任务记录 pickTaskService.update(new LambdaUpdateWrapper<PickTask>()
outTask.setTaskStatus(WmsTaskStatus.FINISH.getCode()); .set(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode())
outTask.setFinishTime(LocalDateTime.now()); .eq(PickTask::getVehicleId, outTask.getVehicleId())
taskRecordService.save(BeanUtil.copyProperties(outTask, TaskRecord.class)); .eq(PickTask::getPickStatus, PickTaskStatusEnum.TEMP.getCode()));
// 删除移库任务 } else {// 代表整出
taskService.remove(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, outTask.getTaskId()));
// 删除当前载具上所有库存 // 删除当前载具上所有库存
stockService.remove(new LambdaQueryWrapper<Stock>().eq(Stock::getVehicleId, outTask.getVehicleId())); stockService.remove(new LambdaQueryWrapper<Stock>().eq(Stock::getVehicleId, outTask.getVehicleId()));
// 删除载具 // 删除载具
vehicleService.remove(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, outTask.getVehicleId())); vehicleService.remove(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, outTask.getVehicleId()));
} }
// 添加任务记录
outTask.setTaskStatus(WmsTaskStatus.FINISH.getCode());
outTask.setFinishTime(LocalDateTime.now());
taskRecordService.save(BeanUtil.copyProperties(outTask, TaskRecord.class));
// 删除出库任务
taskService.remove(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, outTask.getTaskId()));
// 释放原来的库位 // 释放原来的库位
locationService.update(new LambdaUpdateWrapper<Location>() locationService.update(new LambdaUpdateWrapper<Location>()
.set(Location::getLocationStatus, LocationStatus.EMPTY.getCode()) .set(Location::getLocationStatus, LocationStatus.EMPTY.getCode())
@ -825,40 +440,6 @@ public class TaskController {
} }
} }
/**
* 验证任务反馈的请求信息
*
* @param wcsTaskResultRequest 任务反馈的请求
* @return 验证结果
*/
private String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest) {
// 验证请求体是否为空
if (wcsTaskResultRequest == null) {
return TaskResultValidationEnum.NO_REQUEST_BODY.getErrorMessage();
}
// 验证是否缺少必须信息
if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || StringUtils.isEmpty(wcsTaskResultRequest.getVehicleId())
|| wcsTaskResultRequest.getTaskStatus() == null) {
return TaskResultValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
}
// 验证反馈的任务号是否正确
if (!taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskGroup, wcsTaskResultRequest.getTaskId()))) {
return TaskResultValidationEnum.ERROR_TASK_GROUP.getErrorMessage();
}
// 验证反馈的任务状态枚举是否正确
boolean isValidWcsTaskStatus = false;
for (WcsTaskStatus wcsTaskStatus : WcsTaskStatus.values()) {
if (Objects.equals(wcsTaskStatus.getCode(), wcsTaskResultRequest.getTaskStatus())) {
isValidWcsTaskStatus = true;
break;
}
}
if (!isValidWcsTaskStatus) {
return TaskResultValidationEnum.ERROR_TASK_STATUS.getErrorMessage();
}
return TaskResultValidationEnum.OK.getErrorMessage();
}
/** /**
* Wcs请求载具入库 * Wcs请求载具入库
* *
@ -875,7 +456,7 @@ public class TaskController {
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
// 验证入库请求 // 验证入库请求
String validationInfo = validateVehicleRequest(wcsVehicleInRequest); String validationInfo = validateService.validateVehicleRequest(wcsVehicleInRequest);
if (!Objects.equals(validationInfo, "")) { if (!Objects.equals(validationInfo, "")) {
logger.error("请求载具入库发生错误:{}", validationInfo); logger.error("请求载具入库发生错误:{}", validationInfo);
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());
@ -944,31 +525,6 @@ public class TaskController {
} }
} }
/**
* 验证载具入库请求的正确性
* @param wcsVehicleInRequest 载具入库请求
* @return 验证结果
*/
private String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest) {
// 判断请求信息
if (wcsVehicleInRequest == null) {
return "请求信息为空";
}
// 判断是否缺少载具号
if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) {
return "缺少载具号";
}
// 判断当前载具号是否存在任务
LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo())
.eq(Task::getTaskType, TaskType.IN.getCode());
if (!taskService.exists(queryWrapper)) {
return "当前载具没有入库或回库任务";
}
return "";
}
/** /**
* Wcs反馈重复入库问题 * Wcs反馈重复入库问题
* *
@ -985,7 +541,7 @@ public class TaskController {
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
// 验证入库请求 // 验证入库请求
String validationInfo = validateDuplicateLocationRequest(duplicateLocationRequest); String validationInfo = validateService.validateDuplicateLocationRequest(duplicateLocationRequest);
if (!Objects.equals(validationInfo, "")) { if (!Objects.equals(validationInfo, "")) {
logger.error("反馈重复入库错误:{}", validationInfo); logger.error("反馈重复入库错误:{}", validationInfo);
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());
@ -1057,32 +613,68 @@ public class TaskController {
} }
/** /**
* 验证重复入库问题反馈的请求 * 查找所有物料
* @param duplicateLocationRequest 请求信息
* @return 验证结果
*/ */
private String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest) { @PostMapping("/getTasksByPage")
// 判断请求信息 @ResponseBody
if (duplicateLocationRequest == null) { @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
return "请求信息为空"; public String getTasksByPage(@RequestBody TaskQuery taskQuery) {
ResponseEntity response = new ResponseEntity();
try {
Page<Task> page = taskQuery.toMpPage();
//更新条件
LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<Task>()
.eq(taskQuery.getTaskType() != null, Task::getTaskType, taskQuery.getTaskType())
.eq(taskQuery.getTaskStatus() != null, Task::getTaskStatus, taskQuery.getTaskStatus())
.like(StringUtils.isNotEmpty(taskQuery.getVehicleId()), Task::getVehicleId, taskQuery.getVehicleId())
.apply(StringUtils.isNotEmpty(taskQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", taskQuery.getGoodsId())
.apply(StringUtils.isNotEmpty(taskQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", taskQuery.getGoodsName());
Page<Task> tasksPage = taskService.page(page, lambdaQueryWrapper);
// 生成数据
PageDto<TaskVO> pageDto = PageDto.of(tasksPage, tasks -> BeanUtil.copyProperties(tasks, TaskVO.class));
response.setCode(ResponseCode.OK.getCode());
response.setMessage("查询成功");
response.setReturnData(pageDto);
return convertJsonString(response);
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("查询任务发生异常");
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("查询任务发生异常");
return convertJsonString(response);
} }
// 判断是否缺少任务号
if (StringUtils.isEmpty(duplicateLocationRequest.getTaskId())) {
return "缺少任务号";
}
// 判断是否缺少载具号
if (StringUtils.isEmpty(duplicateLocationRequest.getVehicleId())) {
return "缺少载具号";
}
// 判断当前载具号是否存在任务
LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskGroup, duplicateLocationRequest.getTaskId())
.eq(Task::getVehicleId, duplicateLocationRequest.getVehicleId())
.eq(Task::getTaskType, TaskType.IN.getCode());
if (!taskService.exists(queryWrapper)) {
return "当前反馈的重复入库任务不存在";
} }
return ""; /**
* 根据
*/
@PostMapping("/getTasks")
@ResponseBody
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public String getTasks(@RequestBody TaskQuery taskQuery) {
ResponseEntity response = new ResponseEntity();
try {
//更新条件
LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<Task>()
.eq(taskQuery.getTaskType() != null, Task::getTaskType, taskQuery.getTaskType())
.eq(taskQuery.getTaskStatus() != null, Task::getTaskStatus, taskQuery.getTaskStatus())
.eq(taskQuery.getIsPicking() != null, Task::getIsPicking, taskQuery.getIsPicking())
.like(StringUtils.isNotEmpty(taskQuery.getVehicleId()), Task::getVehicleId, taskQuery.getVehicleId())
.apply(StringUtils.isNotEmpty(taskQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", taskQuery.getGoodsId())
.apply(StringUtils.isNotEmpty(taskQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", taskQuery.getGoodsName());
List<Task> tasks = taskService.list(lambdaQueryWrapper);
response.setCode(ResponseCode.OK.getCode());
response.setMessage("查询成功");
response.setReturnData(tasks.isEmpty() ? new ArrayList<Task>() : tasks);
return convertJsonString(response);
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("查询任务发生异常");
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("查询任务发生异常");
return convertJsonString(response);
}
} }
} }

View File

@ -0,0 +1,44 @@
package com.wms.entity.app.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.app.dto.extend.TaskDetailInfo;
import com.wms.entity.table.Task;
import com.wms.utils.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class TaskQuery extends PageQuery {
@JsonProperty("taskType")
private Integer taskType;
@JsonProperty("vehicleId")
private String vehicleId;
@JsonProperty("goodsId")
private String goodsId;
@JsonProperty("goodsName")
private String goodsName;
@JsonProperty("taskStatus")
private Integer taskStatus;
@JsonProperty("isPicking")
private Integer isPicking;
/**
* 根据客户端查询生成数据库查询条件
* @return 数据库PO
*/
public Task toTaskPO() {
Task taskPO = new Task();
taskPO.setTaskType(taskType);// 任务类型
taskPO.setVehicleId(vehicleId);// 载具号
taskPO.setIsPicking(isPicking);
if (StringUtils.isNotEmpty(goodsId) || StringUtils.isNotEmpty(goodsName)) {// 包含物料详细信息
TaskDetailInfo goodsRelatedPO = new TaskDetailInfo();
goodsRelatedPO.setGoodsId(goodsId);
goodsRelatedPO.setGoodsName(goodsName);
taskPO.setGoodsRelated(goodsRelatedPO);
}
return taskPO;
}
}

View File

@ -0,0 +1,82 @@
package com.wms.entity.app.vo;
import com.wms.entity.app.dto.extend.TaskDetailInfo;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 任务记录VO
*/
@Data
public class TaskVO {
/**
* 任务号
*/
private String taskId;
/**
* 任务类型
*/
private Integer taskType;
/**
* 任务状态
*/
private Integer taskStatus;
/**
* 起点
*/
private String origin;
/**
* 终点
*/
private String destination;
/**
* 任务优先级
*/
private Integer taskPriority;
/**
* 任务组
*/
private String taskGroup;
/**
* 载具号
*/
private String vehicleId;
/**
* 重量
*/
private BigDecimal weight;
/**
* 载具尺寸
*/
private Integer vehicleSize;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 完成时间
*/
private LocalDateTime finishTime;
/**
* 用户名
*/
private String userName;
/**
* 物料相关
*/
private TaskDetailInfo goodsRelated;
/**
* 前置任务号
*/
private String preTask;
/**
* 是否拣选
*/
private Integer isPicking;
/**
* 拣选站台
*/
private String pickStand;
}

View File

@ -30,7 +30,7 @@ public class PickTask {
private String standId; private String standId;
/** /**
* 拣选任务状态 * 拣选任务状态
* -1已取消 * -1暂时不可发送
* 0初始化 * 0初始化
* 1已发送 * 1已发送
* 2已完成 * 2已完成

View File

@ -1,10 +1,46 @@
package com.wms.service.business; package com.wms.service.business;
import com.wms.entity.app.request.TaskInRequest; import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.app.wcs.WcsTaskResultRequest;
import com.wms.entity.app.wcs.WcsVehicleInRequest;
/** /**
* 验证服务接口 * 验证服务接口
*/ */
public interface IValidateService { public interface IValidateService {
/**
* 验证入库请求
* @param taskInRequest 入库请求
* @return 验证结果
*/
String validateTaskInRequest(TaskInRequest taskInRequest); String validateTaskInRequest(TaskInRequest taskInRequest);
/**
* 验证出库请求
* @param taskOutRequest 出库请求
* @return 验证结果
*/
String validateTaskOutRequest(TaskOutRequest taskOutRequest);
/**
* 验证任务结果反馈请求
* @param wcsTaskResultRequest 任务结果反馈请求
* @return 验证结果
*/
String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest);
/**
* 验证载具入库请求
* @param wcsVehicleInRequest 载具入库请求
* @return 验证结果
*/
String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest);
/**
* 验证重复入库请求
* @param duplicateLocationRequest 重复入库请求
* @return 验证结果
*/
String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest);
} }

View File

@ -0,0 +1,24 @@
package com.wms.service.business;
/**
* Wms定时任务服务接口
*/
public interface IWmsJobService {
/**
* 执行普通任务
* @throws Exception 异常用于回滚事务
*/
void sendCommonTasks() throws Exception;
/**
* 发送拣选任务
* @throws Exception 异常用于回滚事务
*/
void sendPickTasks() throws Exception;
/**
* 发送重复入库修正后的任务
* @throws Exception 异常用于回滚
*/
void solveDuplicateTask() throws Exception;
}

View File

@ -0,0 +1,37 @@
package com.wms.service.business;
import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
/**
* WMS任务服务接口
*/
public interface IWmsTaskService {
/**
* 创建载具入库任务
* @param taskInRequest 入库请求
* @return 结果
*/
String genEmptyInTask(TaskInRequest taskInRequest);
/**
* 创建物料入库任务
* @param taskInRequest 入库请求
* @return 结果
*/
String genGoodsInTask(TaskInRequest taskInRequest);
/**
* 创建载具或库位出库任务
* @param taskOutRequest 出库请求
* @return 结果
*/
String genVehicleLocationOutTask(TaskOutRequest taskOutRequest);
/**
* 创建物料出库任务
* @param taskOutRequest 出库请求
* @return 结果
*/
String genGoodsOutTask(TaskOutRequest taskOutRequest);
}

View File

@ -1,18 +1,17 @@
package com.wms.service.business.serviceImplements; package com.wms.service.business.serviceImplements;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.ConfigMapKeyEnum; import com.wms.constants.enums.*;
import com.wms.constants.enums.TaskInValidationEnum;
import com.wms.constants.enums.TaskType;
import com.wms.constants.enums.VehicleStatus;
import com.wms.entity.app.request.GoodsInRequest; import com.wms.entity.app.request.GoodsInRequest;
import com.wms.entity.app.request.TaskInRequest; import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.app.wcs.WcsTaskResultRequest;
import com.wms.entity.app.wcs.WcsVehicleInRequest;
import com.wms.entity.table.Location;
import com.wms.entity.table.Stock;
import com.wms.entity.table.Task; import com.wms.entity.table.Task;
import com.wms.entity.table.Vehicle; import com.wms.entity.table.Vehicle;
import com.wms.service.GoodsService; import com.wms.service.*;
import com.wms.service.StandService;
import com.wms.service.TaskService;
import com.wms.service.VehicleService;
import com.wms.service.business.IValidateService; import com.wms.service.business.IValidateService;
import com.wms.utils.StringUtils; import com.wms.utils.StringUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -22,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Objects;
import static com.wms.config.InitLocalConfig.configMap; import static com.wms.config.InitLocalConfig.configMap;
@ -32,10 +32,18 @@ import static com.wms.config.InitLocalConfig.configMap;
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ValidateServiceImplements implements IValidateService { public class ValidateServiceImplements implements IValidateService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志 private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
private final VehicleService vehicleService; private final VehicleService vehicleService;// 载具服务
private final TaskService taskService; private final TaskService taskService;// 任务服务
private final StandService standService; private final StandService standService;// 站台服务
private final GoodsService goodsService; private final GoodsService goodsService;// 物料服务
private final LocationService locationService;// 库位服务
private final StockService stockService;// 库存服务
/**
* 验证入库请求
* @param taskInRequest 入库请求
* @return 验证结果
*/
@Override @Override
public String validateTaskInRequest(TaskInRequest taskInRequest) { public String validateTaskInRequest(TaskInRequest taskInRequest) {
if (taskInRequest == null) { if (taskInRequest == null) {
@ -97,4 +105,170 @@ public class ValidateServiceImplements implements IValidateService {
} }
return TaskInValidationEnum.OK.getErrorMessage(); return TaskInValidationEnum.OK.getErrorMessage();
} }
/**
* 验证出库请求
* @param taskOutRequest 出库请求
* @return 验证结果
*/
@Override
public String validateTaskOutRequest(TaskOutRequest taskOutRequest) {
// 验证任务
if (taskOutRequest == null) {
return TaskOutValidationEnum.NO_REQUEST_BODY.getErrorMessage();
}
// 验证是否包含请求信息
if (StringUtils.isEmpty(taskOutRequest.getGoodsId())
&& StringUtils.isEmpty(taskOutRequest.getVehicleId())
&& StringUtils.isEmpty(taskOutRequest.getOriginPoint())) {
return TaskOutValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
}
// 验证载具号
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())
&& vehicleService.exists(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()))) {
return TaskOutValidationEnum.ERROR_VEHICLE_ID.getErrorMessage();
}
// 验证库位
if (StringUtils.isNotEmpty(taskOutRequest.getOriginPoint())
&& locationService.exists(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()))) {
return TaskOutValidationEnum.ERROR_ORIGIN_POINT.getErrorMessage();
}
// 验证终点站台
if (taskOutRequest.getIsPicking() == 0) {// 出库
if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 2)) {
return TaskOutValidationEnum.ERROR_DESTINATION_POINT.getErrorMessage();
}
} else {// 拣选出库
if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 3)) {
return TaskOutValidationEnum.ERROR_PICK_STAND.getErrorMessage();
}
}
// 验证物料信息
if (StringUtils.isNotEmpty(taskOutRequest.getGoodsId())) {
if (taskOutRequest.getGoodsNum() == null || taskOutRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
return TaskOutValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
}
// 查询库存信息
LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
.apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId())
.apply("goods_related -> '$.remainNum' > 0")
.eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
.eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
if (!stockService.exists(stockQueryWrapper)) {
return TaskOutValidationEnum.NO_STOCK.getErrorMessage();
}
} else {
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, currentVehicle.getCurrentLocation()));
if (!Objects.equals(currentVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) {
return TaskOutValidationEnum.ERROR_VEHICLE_STATUS.getErrorMessage();
}
if (!Objects.equals(currentLocation.getIsLock(), 1)) {
return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
}
} else {
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
if (!Objects.equals(currentLocation.getIsLock(), 1)) {
return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage();
}
if (!Objects.equals(currentLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode())) {
return TaskOutValidationEnum.ERROR_ORIGIN_POINT_STATUS.getErrorMessage();
}
}
}
return TaskOutValidationEnum.OK.getErrorMessage();
}
/**
* 验证任务反馈的请求信息
*
* @param wcsTaskResultRequest 任务反馈的请求
* @return 验证结果
*/
@Override
public String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest) {
// 验证请求体是否为空
if (wcsTaskResultRequest == null) {
return TaskResultValidationEnum.NO_REQUEST_BODY.getErrorMessage();
}
// 验证是否缺少必须信息
if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || StringUtils.isEmpty(wcsTaskResultRequest.getVehicleId())
|| wcsTaskResultRequest.getTaskStatus() == null) {
return TaskResultValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage();
}
// 验证反馈的任务号是否正确
if (!taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskGroup, wcsTaskResultRequest.getTaskId()))) {
return TaskResultValidationEnum.ERROR_TASK_GROUP.getErrorMessage();
}
// 验证反馈的任务状态枚举是否正确
boolean isValidWcsTaskStatus = false;
for (WcsTaskStatus wcsTaskStatus : WcsTaskStatus.values()) {
if (Objects.equals(wcsTaskStatus.getCode(), wcsTaskResultRequest.getTaskStatus())) {
isValidWcsTaskStatus = true;
break;
}
}
if (!isValidWcsTaskStatus) {
return TaskResultValidationEnum.ERROR_TASK_STATUS.getErrorMessage();
}
return TaskResultValidationEnum.OK.getErrorMessage();
}
/**
* 验证载具入库请求的正确性
* @param wcsVehicleInRequest 载具入库请求
* @return 验证结果
*/
@Override
public String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest) {
// 判断请求信息
if (wcsVehicleInRequest == null) {
return "请求信息为空";
}
// 判断是否缺少载具号
if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) {
return "缺少载具号";
}
// 判断当前载具号是否存在任务
LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo())
.eq(Task::getTaskType, TaskType.IN.getCode());
if (!taskService.exists(queryWrapper)) {
return "当前载具没有入库或回库任务";
}
return "";
}
/**
* 验证重复入库问题反馈的请求
* @param duplicateLocationRequest 请求信息
* @return 验证结果
*/
@Override
public String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest) {
// 判断请求信息
if (duplicateLocationRequest == null) {
return "请求信息为空";
}
// 判断是否缺少任务号
if (StringUtils.isEmpty(duplicateLocationRequest.getTaskId())) {
return "缺少任务号";
}
// 判断是否缺少载具号
if (StringUtils.isEmpty(duplicateLocationRequest.getVehicleId())) {
return "缺少载具号";
}
// 判断当前载具号是否存在任务
LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskGroup, duplicateLocationRequest.getTaskId())
.eq(Task::getVehicleId, duplicateLocationRequest.getVehicleId())
.eq(Task::getTaskType, TaskType.IN.getCode());
if (!taskService.exists(queryWrapper)) {
return "当前反馈的重复入库任务不存在";
}
return "";
}
} }

View File

@ -0,0 +1,253 @@
package com.wms.service.business.serviceImplements;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.wcs.WcsStandTaskRequest;
import com.wms.entity.app.wcs.WcsTaskRequest;
import com.wms.entity.table.PickTask;
import com.wms.entity.table.Task;
import com.wms.entity.table.WmsLog;
import com.wms.service.LogService;
import com.wms.service.PickTaskService;
import com.wms.service.TaskService;
import com.wms.service.business.IWmsJobService;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import com.wms.utils.WmsUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
import static com.wms.config.InitLocalConfig.configMap;
import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId;
/**
* Wms定时任务服务实现
*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WmsJobServiceImplements implements IWmsJobService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
private final LogService logService;// 日志服务
private final TaskService taskService;// 任务服务
private final PickTaskService pickTaskService;// 拣选任务服务
/**
* 发送正常的任务
*/
public void sendCommonTasks() throws Exception {
try {
// 检索任务表---新建未下发的任务
LambdaQueryWrapper<Task> waitForDistributeTaskQuery = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode());
List<Task> allTasks = taskService.list(waitForDistributeTaskQuery);
// 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表
List<String> taskGroupIds = new ArrayList<>();
if (!allTasks.isEmpty()) {
for (Task task : allTasks) {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
continue;
}
}
if (taskGroupIds.contains(task.getTaskGroup())) {
continue;
}
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) {
tempTask.setTaskType(TaskType.OUT.getCode());
} else {
tempTask.setTaskType(task.getTaskType());
}
tempTask.setOrigin(task.getOrigin());
tempTask.setDestination(task.getDestination());
tempTask.setVehicleNo(task.getVehicleId());
tempTask.setVehicleSize(task.getVehicleSize());
tempTask.setWeight(task.getWeight());
tempTask.setPriority(task.getTaskPriority());
request.add(tempTask);
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.size() == 0) {
// 没有新任务发送
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
.in(Task::getTaskGroup, taskGroupIds)
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()));
} else {
logger.error("发送任务错误:{}", convertJsonString(result));
}
} else {
logger.error("WCS发送任务地址为空");
}
}
} catch (Exception exception) {
logger.error("向WCS发送任务时发生异常{}", convertJsonString(exception));
throw new Exception("向WCS发送任务时发生异常");
}
}
/**
* 发送拣选任务
*/
public void sendPickTasks() throws Exception {
try {
// 检索任务表---新建未下发的拣选任务
LambdaQueryWrapper<PickTask> waitForDistributePickTaskQuery = new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode());
List<PickTask> allPickTasks = pickTaskService.list(waitForDistributePickTaskQuery);
if (allPickTasks == null || allPickTasks.isEmpty()) {
return;
}
// 需要发送给wcs的拣选任务列表
List<WcsStandTaskRequest> request = new ArrayList<>();
// 载具对应站台列表
Map<String, List<String>> vehicleAndStansMap = new HashMap<>();
// 循环生成载具对应站台列表
for (PickTask pickTask : allPickTasks) {
// 当前载具已经添加过站台
if (vehicleAndStansMap.containsKey(pickTask.getVehicleId())) {
List<String> oldStandIds = vehicleAndStansMap.get(pickTask.getVehicleId());
oldStandIds.add(pickTask.getStandId());
vehicleAndStansMap.replace(pickTask.getVehicleId(), oldStandIds);
} else {// 新载具
List<String> newStandIds = new ArrayList<>();
newStandIds.add(pickTask.getStandId());
vehicleAndStansMap.put(pickTask.getVehicleId(), newStandIds);
}
}
// 循环生成Wcs任务请求
for (String vehicleId : vehicleAndStansMap.keySet()) {
WcsStandTaskRequest requestSingle = new WcsStandTaskRequest();
requestSingle.setTaskGroup(WmsUtils.generateId(vehicleId));
requestSingle.setTaskType(1);
requestSingle.setVehicleNo(vehicleId);
requestSingle.setLocation(vehicleAndStansMap.get(vehicleId));
requestSingle.setRemark("站台拣选任务");
request.add(requestSingle);
}
if (!request.isEmpty()) {
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_PICK_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送拣选任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送拣选任务", "setConveyTask", convertJsonString(request), convertJsonString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
pickTaskService.update(new LambdaUpdateWrapper<PickTask>()
.set(PickTask::getPickStatus, PickTaskStatusEnum.SEND.getCode())
.in(PickTask::getVehicleId, vehicleAndStansMap.keySet())
.eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode()));
} else {
logger.error("发送拣选任务错误:{}", convertJsonString(result));
}
} else {
logger.error("WCS发送拣选任务地址为空");
}
}
} catch (Exception exception) {
logger.error("向WCS发送拣选任务时发生异常{}", convertJsonString(exception));
throw new Exception("向WCS发送拣选任务时发生异常");
}
}
/**
* 处理重复入库的任务
*/
public void solveDuplicateTask() throws Exception {
try {
// 检索任务表---重复入库的任务
LambdaQueryWrapper<Task> duplicateTaskQueryWrapper = new LambdaQueryWrapper<Task>()
.eq(Task::getTaskType, TaskType.IN.getCode())
.eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode());
List<Task> duplicateTasks = taskService.list(duplicateTaskQueryWrapper);
// 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表
List<String> taskGroupIds = new ArrayList<>();
if (!duplicateTasks.isEmpty()) {
for (Task task : duplicateTasks) {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
continue;
}
}
if (taskGroupIds.contains(task.getTaskGroup())) {
// 已经发送过的任务组跳过
continue;
}
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
tempTask.setDestination(task.getDestination());
tempTask.setVehicleNo(task.getVehicleId());
request.add(tempTask);
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.isEmpty()) {
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_NEW_DESTINATION.getConfigKey());
if (url != null) {
logger.info("向WCS发送新目的地地址{},请求详情:{}", url, convertJsonString(request));
request.forEach(wcsTaskRequest -> {
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(wcsTaskRequest)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送新目的地", "setStackerTaskNewDestination", convertJsonString(wcsTaskRequest), convertJsonString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
.in(Task::getTaskGroup, taskGroupIds)
.eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode()));
} else {
logger.error("发送新目的地错误:{}", convertJsonString(result));
}
});
} else {
logger.error("向WCS发送新目的地的地址为空");
}
}
} catch (Exception exception) {
logger.error("向WCS发送新目的地时发生异常{}", convertJsonString(exception));
throw new Exception("向WCS发送新目的地时发生异常");
}
}
}

View File

@ -0,0 +1,298 @@
package com.wms.service.business.serviceImplements;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms.constants.enums.StockStatus;
import com.wms.constants.enums.TaskType;
import com.wms.constants.enums.VehicleStatus;
import com.wms.constants.enums.WmsTaskStatus;
import com.wms.entity.app.dto.extend.TaskDetailInfo;
import com.wms.entity.app.request.GoodsInRequest;
import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.table.Location;
import com.wms.entity.table.Stock;
import com.wms.entity.table.Task;
import com.wms.entity.table.Vehicle;
import com.wms.service.*;
import com.wms.service.business.IWmsTaskService;
import com.wms.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId;
/**
* WMS任务服务实现
*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WmsTaskServiceImplements implements IWmsTaskService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
private final VehicleService vehicleService;// 载具服务
private final TaskService taskService;// 任务服务
private final LocationService locationService;// 库位服务
private final StockService stockService;// 库存服务
/**
* 添加空入库任务
*
* @param taskInRequest 入库请求
* @return 添加结果
*/
@Override
public String genEmptyInTask(TaskInRequest taskInRequest) {
String result = "";
Task tempInTask = new Task();
tempInTask.setTaskId(generateId("RK_"));
tempInTask.setTaskType(TaskType.IN.getCode());
tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
tempInTask.setTaskGroup(generateId(""));
tempInTask.setTaskPriority(1);
tempInTask.setVehicleId(taskInRequest.getVehicleId());
tempInTask.setVehicleSize(1);
tempInTask.setWeight(taskInRequest.getTotalWeight());
tempInTask.setCreateTime(LocalDateTime.now());
tempInTask.setUserName(taskInRequest.getUserName());
try {
if (!taskService.save(tempInTask)) {
return "添加空入库任务失败";
}
} catch (Exception e) {
logger.error("添加空入库任务异常:{}", convertJsonString(e));
return "添加空入库任务失败";
}
return result;
}
/**
* 添加入库任务
*
* @param taskInRequest 入库请求
* @return 添加结果
*/
@Override
public String genGoodsInTask(TaskInRequest taskInRequest) {
String result = "";
String taskGroupId = generateId("");
List<Task> tempTasks = new ArrayList<>();
for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
Task tempInTask = new Task();
tempInTask.setTaskId(generateId("RK_"));
tempInTask.setTaskType(TaskType.IN.getCode());
tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
tempInTask.setTaskGroup(taskGroupId);
tempInTask.setTaskPriority(1);
tempInTask.setVehicleId(taskInRequest.getVehicleId());
tempInTask.setVehicleSize(1);
tempInTask.setWeight(taskInRequest.getTotalWeight());
tempInTask.setCreateTime(LocalDateTime.now());
tempInTask.setUserName(taskInRequest.getUserName());
// 物料相关信息
TaskDetailInfo goodsRelatedInfo = new TaskDetailInfo();
// TODO 物料信息需要完善
goodsRelatedInfo.setGoodsId(goodsInRequest.getGoodsId());
goodsRelatedInfo.setGoodsName("");
goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum());
goodsRelatedInfo.setOriginNum(BigDecimal.ZERO);
tempInTask.setGoodsRelated(goodsRelatedInfo);
tempTasks.add(tempInTask);
}
try {
if (!taskService.saveBatch(tempTasks)) {
return "添加入库任务失败";
}
} catch (Exception e) {
logger.error("添加入库任务异常:{}", convertJsonString(e));
return "添加入库任务失败";
}
return result;
}
/**
* 生成载具或库位出库任务
*
* @param taskOutRequest 出库请求
* @return 结果
*/
@Override
public String genVehicleLocationOutTask(TaskOutRequest taskOutRequest) {
// 查询对应载具
if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
// 创建空出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(taskOutRequest.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(currentVehicle.getCurrentLocation());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
taskService.save(vehicleOutTask);
// 对应载具所有库存上锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getVehicleId, taskOutRequest.getVehicleId()));
// 对应载具状态设置
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
} else {
// 查找对应库位
Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
// 创建空出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(currentLocation.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(currentLocation.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
taskService.save(vehicleOutTask);
// 对应库位所有库存上锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getLocationId, taskOutRequest.getOriginPoint()));
// 对应库位状态设置
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getCurrentLocation, taskOutRequest.getOriginPoint()));
}
return "";
}
/**
* 生成物料出库任务
*
* @param taskOutRequest 出库请求
* @return 结果
*/
@Override
public String genGoodsOutTask(TaskOutRequest taskOutRequest) {
// 查询库存
LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
.apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId())
.apply("goods_related -> '$.remainNum' > 0")
.eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
.eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
List<Stock> stocks = stockService.list(stockQueryWrapper);
List<Task> goodsOutTasks = new ArrayList<>();
BigDecimal needNum = taskOutRequest.getGoodsNum();
for (Stock stock : stocks) {
if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {// 库存状态正常的情况
// 悲观锁锁定库存状态---同一载具下的库存
boolean lockStocksFlag = stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.eq(Stock::getVehicleId, stock.getVehicleId())
.eq(Stock::getStockStatus, StockStatus.OK.getCode()));
// 锁定载具状态
boolean lockVehicleFlag = vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, stock.getVehicleId())
.eq(Vehicle::getVehicleStatus, VehicleStatus.ON));
if (!lockStocksFlag || !lockVehicleFlag) {
// 释放锁
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OK.getCode())
.eq(Stock::getVehicleId, stock.getVehicleId())
.eq(Stock::getStockStatus, StockStatus.OK.getCode()));
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())
.eq(Vehicle::getVehicleId, stock.getVehicleId()));
continue;
}
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(stock.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(stock.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
// TODO 设定物料相关信息 需要完善
TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
vehicleOutTask.setGoodsRelated(taskDetailInfo);
goodsOutTasks.add(vehicleOutTask);
needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
} else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) {
// 查询到当前当前载具对应的任务并同步
Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, stock.getVehicleId()));
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
if (sameVehicleTask != null) {
vehicleOutTask.setTaskGroup(sameVehicleTask.getTaskGroup());
vehicleOutTask.setTaskStatus(sameVehicleTask.getTaskStatus());
vehicleOutTask.setTaskPriority(sameVehicleTask.getTaskPriority());
vehicleOutTask.setPreTask(sameVehicleTask.getPreTask());
} else {
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
}
vehicleOutTask.setVehicleId(stock.getVehicleId());
vehicleOutTask.setUserName(taskOutRequest.getUserName());
vehicleOutTask.setOrigin(stock.getLocationId());
vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
vehicleOutTask.setCreateTime(LocalDateTime.now());
// TODO 设定物料相关信息 需要完善
TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
vehicleOutTask.setGoodsRelated(taskDetailInfo);
goodsOutTasks.add(vehicleOutTask);
needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
}
// 盘点,移库,锁定状态不可使用
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
// 库存足够跳出循环
break;
}
}
// 添加任务记录表
taskService.saveBatch(goodsOutTasks);
return "";
}
}

View File

@ -2,10 +2,7 @@ package com.wms.service.business.serviceImplements;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms.constants.enums.StockStatus; import com.wms.constants.enums.*;
import com.wms.constants.enums.TaskType;
import com.wms.constants.enums.VehicleStatus;
import com.wms.constants.enums.WmsTaskStatus;
import com.wms.entity.app.dto.WorkCenterAndOrderDto; import com.wms.entity.app.dto.WorkCenterAndOrderDto;
import com.wms.entity.app.dto.extend.StockDetailInfo; import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.table.*; import com.wms.entity.table.*;
@ -215,7 +212,7 @@ public class WorkServiceImplements implements IWorkService {
outsideVehiclesService.updateBatchById(usedOutsideVehiclesList); outsideVehiclesService.updateBatchById(usedOutsideVehiclesList);
// 生成拣选任务 // 生成拣选任务
List<String> vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).toList(); List<String> vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).toList();
createPickTasks(vehicleIds, workStation); createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode());
} }
// 判断此时需求数量是否为0 // 判断此时需求数量是否为0
if (needNum.compareTo(BigDecimal.ZERO) <= 0) { if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
@ -408,6 +405,7 @@ public class WorkServiceImplements implements IWorkService {
tempOutTask.setOrigin(tempStock.getLocationId()); tempOutTask.setOrigin(tempStock.getLocationId());
tempOutTask.setDestination(""); tempOutTask.setDestination("");
tempOutTask.setCreateTime(LocalDateTime.now()); tempOutTask.setCreateTime(LocalDateTime.now());
tempOutTask.setIsPicking(1);
outTasks.add(tempOutTask); outTasks.add(tempOutTask);
// 添加载具列表 // 添加载具列表
vehicleIds.add(tempStock.getVehicleId()); vehicleIds.add(tempStock.getVehicleId());
@ -453,15 +451,19 @@ public class WorkServiceImplements implements IWorkService {
// 保存流转箱信息 // 保存流转箱信息
outsideVehiclesService.saveBatch(outsideVehicles); outsideVehiclesService.saveBatch(outsideVehicles);
// 保存拣选任务至拣选任务表 // 保存拣选任务至拣选任务表
createPickTasks(vehicleIds, workStation); createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.TEMP.getCode());
} }
/** /**
* 生成拣选任务 * 生成拣选任务
* @param vehicleIds 载具列表 * @param vehicleIds 载具列表
* @param workStation 工作站台 * @param workStation 工作站台
* @param pickStatus 任务状态只接受-10-1暂存不发送0可发送
*/ */
private void createPickTasks(List<String> vehicleIds, String workStation) { private void createPickTasks(List<String> vehicleIds, String workStation, Integer pickStatus) {
if (!Objects.equals(pickStatus, PickTaskStatusEnum.TEMP.getCode()) && !Objects.equals(pickStatus, PickTaskStatusEnum.NEW.getCode())) {
return;
}
// 拣选任务暂存列表 // 拣选任务暂存列表
List<PickTask> pickTasks = new ArrayList<>(); List<PickTask> pickTasks = new ArrayList<>();
vehicleIds.forEach(vehicleId -> { vehicleIds.forEach(vehicleId -> {
@ -470,7 +472,7 @@ public class WorkServiceImplements implements IWorkService {
tempPickTask.setPickTaskId(generateId("PICK_")); tempPickTask.setPickTaskId(generateId("PICK_"));
tempPickTask.setVehicleId(vehicleId); tempPickTask.setVehicleId(vehicleId);
tempPickTask.setStandId(workStation); tempPickTask.setStandId(workStation);
tempPickTask.setPickStatus(0); tempPickTask.setPickStatus(pickStatus);
tempPickTask.setLastUpdateTime(LocalDateTime.now()); tempPickTask.setLastUpdateTime(LocalDateTime.now());
pickTasks.add(tempPickTask); pickTasks.add(tempPickTask);
}); });

View File

@ -0,0 +1,19 @@
package com.wms.webSocket.client;
import jakarta.websocket.Session;
import lombok.Data;
/**
*
*/
@Data
public class WebSocketClient {
/**
* 连接会话
*/
private Session session;
/**
* 连接uri
*/
private String uri;
}

View File

@ -0,0 +1,16 @@
package com.wms.webSocket.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* ws配置类
*/
@SpringBootConfiguration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}

View File

@ -0,0 +1,12 @@
package com.wms.webSocket.service;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
/**
* ws服务
*/
@ServerEndpoint(value = "/websocket/{userName}")
@Component
public class WebSocketService {
}