diff --git a/youchain-common/src/main/java/com/youchain/utils/RedisUtils.java b/youchain-common/src/main/java/com/youchain/utils/RedisUtils.java index 8eb3f3f..59bfebb 100644 --- a/youchain-common/src/main/java/com/youchain/utils/RedisUtils.java +++ b/youchain-common/src/main/java/com/youchain/utils/RedisUtils.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; @@ -45,6 +46,7 @@ public class RedisUtils { this.redisTemplate.setHashKeySerializer(new StringRedisSerializer()); this.redisTemplate.setKeySerializer(new StringRedisSerializer()); this.redisTemplate.setStringSerializer(new StringRedisSerializer()); + this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); } /** diff --git a/youchain-common/target/classes/com/youchain/utils/RedisUtils.class b/youchain-common/target/classes/com/youchain/utils/RedisUtils.class index 320a355..7cf34f6 100644 Binary files a/youchain-common/target/classes/com/youchain/utils/RedisUtils.class and b/youchain-common/target/classes/com/youchain/utils/RedisUtils.class differ diff --git a/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java b/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java index 637e4b2..495887a 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java @@ -30,6 +30,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -49,6 +50,7 @@ import static org.springframework.http.HttpStatus.OK; @Api(tags = "KMReS") @RequestMapping("/interfaces/api/amr") @Slf4j +@EnableAsync public class KMReSController { private final AgvTaskService agvTaskService; @@ -63,57 +65,78 @@ public class KMReSController { @ApiOperation("KMReS接口回调") @AnonymousAccess public ResponseEntity missionStateCallback(@RequestBody MissionStateCallback missionStateCallback) { - String id = missionStateCallback.getMissionCode();//作业 id - String containerCode = missionStateCallback.getContainerCode();//容器编号 - String missionStatus = missionStateCallback.getMissionStatus();//作业当前状态 - try { - //料箱出库任务 - if(id.indexOf("LX")!=-1){ - if(missionStatus.equals("CANCELED")){ - List agvTaskList= agvTaskService.findByjobCode(id); - for(AgvTask agvTask:agvTaskList){ - if(!agvTask.getStatus().equals(BizStatus.FINISH)){ - agvTask.setStatus(BizStatus.CANCEL); - agvTask.setEndTime(new Timestamp(new Date().getTime())); - agvTaskService.update(agvTask); - } - } - }else { - AgvTask agvTask= agvTaskService.findByjobCode(id,containerCode); - agvTaskService.agvTaskCallback(agvTask,missionStatus,containerCode); - List taskList = taskRepository.getAgvTaskList(agvTask.getId()); - Task task = taskList.get(0); - if(task==null){ - return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "任务不存在!", ""), BAD_REQUEST); - } - returnIssue(task);//叫料结果回传 - } + String id = missionStateCallback.getMissionCode(); // 作业 id + String containerCode = missionStateCallback.getContainerCode(); // 容器编号 + String missionStatus = missionStateCallback.getMissionStatus(); // 作业当前状态 - }else{ + try { + if (id.contains("LX")) { + //出库 + pickTask(id, containerCode, missionStatus); + } else { //入库 - AgvTaskDto agvTaskDto = agvTaskService.findById(Integer.parseInt(id)); - AgvTask agvTask = agvTaskService.toEntity(agvTaskDto);//转实体 - List taskList = taskRepository.getAgvTaskList(agvTask.getId()); - if (taskList.isEmpty()) { - return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "任务不存在!", ""), BAD_REQUEST); - } - Task task = taskList.get(0); - agvTaskService.agvTaskCallback(agvTask, task, missionStatus); - returnMo(task.getBillCode());//回传MO信息 + asnTask(id, missionStatus); } - return new ResponseEntity<>(ApiResult.success(OK.value(), "", ""), HttpStatus.OK); + return ResponseEntity.ok(ApiResult.success(HttpStatus.OK.value(), "", "")); } catch (Exception e) { - return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "KMReS接口回调异常", e.getMessage()), BAD_REQUEST); + return new ResponseEntity<>(ApiResult.fail(HttpStatus.BAD_REQUEST.value(), "KMReS接口回调异常", e.getMessage()), HttpStatus.BAD_REQUEST); } } + private void asnTask(String id, String missionStatus) { + AgvTaskDto agvTaskDto = agvTaskService.findById(Integer.parseInt(id)); + AgvTask agvTask = agvTaskService.toEntity(agvTaskDto); + Task task = getFirstTask(agvTask.getId()); + + if (task == null) { + throw new RuntimeException("任务不存在!"); + } + + agvTaskService.agvTaskCallback(agvTask, task, missionStatus); + returnMo(task.getBillCode()); // 回传 MO 信息 + } + + private void pickTask(String id, String containerCode, String missionStatus) throws Exception { + if ("CANCELED".equals(missionStatus)) { + cancelAgvTasks(id); + } else { + AgvTask agvTask = agvTaskService.findByjobCode(id, containerCode); + agvTaskService.agvTaskCallback(agvTask, missionStatus, containerCode); + Task task = getFirstTask(agvTask.getId()); + + if (task == null) { + throw new RuntimeException("任务不存在!"); + } + + returnIssue(task); // 叫料结果回传 + } + } + + private void cancelAgvTasks(String id) { + List agvTaskList = agvTaskService.findByjobCode(id); + for (AgvTask agvTask : agvTaskList) { + if (!agvTask.getStatus().equals(BizStatus.FINISH)) { + agvTask.setStatus(BizStatus.CANCEL); + agvTask.setEndTime(new Timestamp(new Date().getTime())); + agvTaskService.update(agvTask); + } + } + } + + private Task getFirstTask(Integer agvTaskId) { + List taskList = taskRepository.getAgvTaskList(agvTaskId); + return taskList.isEmpty() ? null : taskList.get(0); + } + + /** * 回传MO信息 * * @param billCode */ + @Async public void returnMo(String billCode) { OrderDto orderDto = orderService.findByBarcodeNumber(billCode); @@ -131,8 +154,7 @@ public class KMReSController { long endTime = System.currentTimeMillis(); long time = endTime - startTime; // 保存日志 - logService.saveLogInfo(returnMoInfo,UrlApi.publicApi, resultJson, "按MO票入库", time); - + logService.saveLogInfo(returnMoInfo, UrlApi.publicApi, resultJson, "按MO票入库", time); } @@ -152,12 +174,10 @@ public class KMReSController { long endTime = System.currentTimeMillis(); long time = endTime - startTime; // 保存日志 - logService.saveLogInfo(returnIssueInfo,UrlApi.publicApi, resultJson, "叫料结果回传", time); + logService.saveLogInfo(returnIssueInfo, UrlApi.publicApi, resultJson, "叫料结果回传", time); } - - public static ReturnMoInfo getReturnMoInfo(List tasks) { ReturnMoParams params = new ReturnMoParams(); params.setOrgId(808); diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MlsServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MlsServiceImpl.java index b82e12e..020b53e 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MlsServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MlsServiceImpl.java @@ -285,7 +285,7 @@ public class MlsServiceImpl implements MlsService { } else { DeptDto deptDto = deptService.findById(7L); dept = deptService.toEntity(deptDto); - redisUtils.set("dept", dept, 0); + redisUtils.set("dept", dept); } @@ -397,8 +397,7 @@ public class MlsServiceImpl implements MlsService { } @Override - @Transactional(rollbackFor = Exception.class) - public synchronized void getIssueInfo(IssueInfo issueInfo) { + public void getIssueInfo(IssueInfo issueInfo) { String taskNumber = issueInfo.getTaskNumber();//任务号 // 指定Set的类型 Set workOrderNameSet = issueInfo.getWorkOrderName(); @@ -407,18 +406,18 @@ public class MlsServiceImpl implements MlsService { } List inventoryList = inventoryService.findInvByBillCode(workOrderNameSet);//根据工单号查询库存信息 - if (inventoryList.size() == 0) { + if (inventoryList.isEmpty()) { throw new RuntimeException("无库存信息!"); } //目标点 Point endPoint = null; - boolean flag = redisUtils.hasKey("endPoint"); + boolean flag = redisUtils.hasKey("ckjbk"); if (flag) { - endPoint = (Point) redisUtils.get("endPoint"); + endPoint = (Point) redisUtils.get("ckjbk"); } else { endPoint = pointService.findByCode(null, null, null, "出库接驳口", null); - redisUtils.set("endPoint", endPoint, 0); + redisUtils.set("ckjbk", endPoint); } List inventoryToUpdate = new ArrayList<>(); @@ -444,6 +443,7 @@ public class MlsServiceImpl implements MlsService { pd.setOrderQty(inv.getQuantity()); pd.setAllocatedQty(inv.getQuantity()); pd.setStatus(BizStatus.ALLOCATE); + pd.setDept(item.getDept()); pickDetailToCreate.add(pd); //生成搬运任务 diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MoServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MoServiceImpl.java index 5a35c5d..9d41383 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MoServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/MoServiceImpl.java @@ -35,6 +35,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; + import java.util.*; import java.io.IOException; import javax.persistence.EntityManager; @@ -63,6 +64,7 @@ public class MoServiceImpl implements MoService { private final TaskService taskService; private final AsnDetailService asnDetailService; private final ItemKeyService itemKeyService; + private final RedisUtils redisUtils; @Override public Map queryAll(MoQueryCriteria criteria, Pageable pageable) { @@ -153,63 +155,62 @@ public class MoServiceImpl implements MoService { public void scanMo(String mo) { //条码格式;12227000016951-qth1847-240411422924 - String[] arr = mo.split("-"); - if (arr.length != 3) { - throw new RuntimeException("条码格式错误!"); - } + // 验证条码格式 + validateBarcodeFormat(mo); + String[] arr = mo.split("-"); String itemCode = arr[0];//物料编号 String stockCode = arr[1];//容器编号 String labelNo = arr[2];//标签号 - Item item = itemService.existItem(itemCode); - if (item == null) { - throw new RuntimeException(itemCode + "系统无此物料!"); + // 验证物料是否存在 + Item item = null; + boolean flagItem = redisUtils.hasKey(itemCode); + if (flagItem) { + item = (Item) redisUtils.get(itemCode); + } else { + item = getOrThrow(Optional.ofNullable(itemService.existItem(itemCode)), itemCode + " 系统无此物料!"); + redisUtils.set(itemCode,item); } - Stock stock = stockService.findByCode(stockCode, null); - if (stock == null) { - throw new RuntimeException(stockCode + "系统无此容器!"); + // 验证容器是否存在 + Stock stock=null; + boolean flagStock = redisUtils.hasKey(stockCode); + if (flagStock) { + stock = (Stock) redisUtils.get(stockCode); + } else { + stock = getOrThrow(Optional.ofNullable(stockService.findByCode(stockCode, null)), stockCode + " 系统无此容器!"); + redisUtils.set(stockCode,stock); } + // 验证容器状态 + validateStockStatus(stock); - if (stock.getStatus().equals(BaseStatus.USED)) { - throw new RuntimeException(stockCode + "箱码已经有绑定关系!"); + //验证入库接驳口是否存在 + Point srcPoint = null; + boolean flagSrcPoint = redisUtils.hasKey("rkjbk"); + if (flagSrcPoint) { + srcPoint = (Point) redisUtils.get("rkjbk"); + } else { + srcPoint = getOrThrow(Optional.ofNullable(pointService.findByCode(null, null, null, "入库接驳口", null)), "系统无入库接驳口!"); + redisUtils.set("rkjbk", srcPoint, 0); } + Point endPoint = getOrThrow(Optional.ofNullable(pointService.findByCode(null, BaseStatus.FREE, BaseStatus.STORAGE, "存储区", null)), "存储区没有空闲点位!"); - Point srcPoint = pointService.findByCode(null, null, null, "入库接驳口", null); - if (srcPoint == null) { - throw new RuntimeException("系统无入库接驳口!"); - } + MoDto moDto = getOrThrow(Optional.ofNullable(findByLabelNo(labelNo)), labelNo + " 系统无此标签!"); - Point endPoint = pointService.findByCode(null, BaseStatus.FREE, BaseStatus.STORAGE, "存储区", null); - if (endPoint == null) { - throw new RuntimeException("存储区没有空闲点位!"); - } + // 验证标签状态 + validateLabelState(moDto); - MoDto moDto = this.findByLabelNo(labelNo); - if (moDto == null) { - throw new RuntimeException(labelNo + "系统无此标签!"); - } + // 验证标签是否已入库 + validateTask(moDto); - if (!moDto.getLabelState().equals("PRINTED")) { - throw new RuntimeException(labelNo + "标签已被接收(已接收状态)!"); - } + // 验证送货单是否存在 + OrderDto orderDto = getOrThrow(Optional.ofNullable(orderService.findByDeliveryHeaderId(moDto.getDeliveryHeaderId())), moDto.getDeliveryHeaderId() + " 系统无此送货单!"); - if (taskService.findByLabelNo(labelNo).size() > 0) { - throw new RuntimeException(labelNo + "此标签已入库!"); - } - - OrderDto orderDto = orderService.findByDeliveryHeaderId(moDto.getDeliveryHeaderId()); - - if (orderDto == null) { - throw new RuntimeException(moDto.getDeliveryHeaderId() + "系统无此订单!"); - } - - if (!orderDto.getDeliveryStatus().equals("lm_initial")) { - throw new RuntimeException(moDto.getLabelNo() + "标签背后的送货单" + orderDto.getBarcodeNumber() + "已取消(标签失效)!"); - } + // 验证送货单状态 + validateOrder(orderDto, moDto); // 生成AGV任务和入库任务 createTasks(item, stock, srcPoint, endPoint, moDto.getLabelNo(), moDto, orderDto); @@ -220,6 +221,40 @@ public class MoServiceImpl implements MoService { } + private void validateBarcodeFormat(String mo) { + if (mo.split("-").length != 3) { + throw new IllegalArgumentException("条码格式错误!"); + } + } + + private T getOrThrow(Optional optional, String errorMessage) { + return optional.orElseThrow(() -> new RuntimeException(errorMessage)); + } + + private void validateStockStatus(Stock stock) { + if (stock.getStatus().equals(BaseStatus.USED)) { + throw new RuntimeException(stock.getCode() + " 箱码已经有绑定关系!"); + } + } + + private void validateLabelState(MoDto moDto) { + if (!"PRINTED".equals(moDto.getLabelState())) { + throw new RuntimeException(moDto.getLabelNo() + " 标签已被接收(已接收状态)!"); + } + } + + private void validateTask(MoDto moDto) { + if (taskService.findByLabelNo(moDto.getLabelNo()).size() > 0) { + throw new RuntimeException(moDto.getLabelNo() + "此标签已入库!"); + } + } + + private void validateOrder(OrderDto orderDto, MoDto moDto) { + if (!orderDto.getDeliveryStatus().equals("lm_initial")) { + throw new RuntimeException(moDto.getLabelNo() + "标签背后的送货单" + orderDto.getBarcodeNumber() + "已取消(标签失效)!"); + } + } + @Override public Map findBylabelNos(Set labelNos) { String hql = "from Mo where labelNo in (:labelNos) "; diff --git a/youchain-system/src/main/java/com/youchain/modules/quartz/task/moTask.java b/youchain-system/src/main/java/com/youchain/modules/quartz/task/moTask.java index 8125846..c8396df 100644 --- a/youchain-system/src/main/java/com/youchain/modules/quartz/task/moTask.java +++ b/youchain-system/src/main/java/com/youchain/modules/quartz/task/moTask.java @@ -44,8 +44,8 @@ public class moTask { params.setInvCodes(invCodes); //DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd HH:mm:ss") params.setIqcResult(""); - params.setStartTime("2024-04-28 00:00:00"); - params.setEndTime("2024-04-28 23:59:59"); + params.setStartTime("2024-04-27 00:00:00"); + params.setEndTime("2024-04-27 23:59:59"); params.setPageNo(1); params.setPageSize(100); MoInfo moInfo = new MoInfo(); diff --git a/youchain-system/src/main/java/com/youchain/modules/security/service/dto/OnlineUserDto.java b/youchain-system/src/main/java/com/youchain/modules/security/service/dto/OnlineUserDto.java index bff2d35..19ba01d 100644 --- a/youchain-system/src/main/java/com/youchain/modules/security/service/dto/OnlineUserDto.java +++ b/youchain-system/src/main/java/com/youchain/modules/security/service/dto/OnlineUserDto.java @@ -18,6 +18,8 @@ package com.youchain.modules.security.service.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; + +import java.io.Serializable; import java.util.Date; /** @@ -27,7 +29,7 @@ import java.util.Date; @Data @AllArgsConstructor @NoArgsConstructor -public class OnlineUserDto { +public class OnlineUserDto implements Serializable { /** * 用户名