| | |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.mapper.TaskMapper; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.asrs.task.handler.AgvHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Slf4j |
| | | @Service("taskService") |
| | | public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService { |
| | | |
| | |
| | | private OrderPakoutService orderPakoutService; |
| | | @Autowired |
| | | private OrderDetlPakoutService orderDetlPakoutService; |
| | | @Autowired |
| | | private AgvHandler agvHandler; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void completeWrkMast(String workNo, Long userId) { |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>().eq("wrk_no", workNo)); |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>() |
| | | .eq("wrk_no", workNo) |
| | | .andNew("(is_deleted = 0)")); |
| | | if (Cools.isEmpty(wrkMast)) { |
| | | throw new CoolException(workNo + "工作档不存在"); |
| | | } |
| | |
| | | throw new CoolException("当前工作档已完成"); |
| | | } |
| | | // 入库 + 库位转移 |
| | | if (wrkMast.getIoType() < 100){ |
| | | if (wrkMast.getIoType() < 50){ |
| | | wrkMast.setWrkSts(4L); |
| | | // 出库 |
| | | } else if (wrkMast.getWrkSts() > 10) { |
| | | } else { |
| | | wrkMast.setWrkSts(14L); |
| | | } |
| | | Date now = new Date(); |
| | |
| | | @Override |
| | | @Transactional |
| | | public void pickWrkMast(String workNo, Long userId) { |
| | | Task wrkMast = this.selectById(workNo); |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>() |
| | | .eq("wrk_no", workNo) |
| | | .andNew("(is_deleted = 0)")); |
| | | if (Cools.isEmpty(wrkMast)) { |
| | | throw new CoolException(workNo + "工作档不存在"); |
| | | } |
| | |
| | | @Transactional |
| | | public void cancelWrkMast(String workNo, Long userId) { |
| | | Date now = new Date(); |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>().eq("wrk_no", workNo)); |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>() |
| | | .eq("wrk_no", workNo) |
| | | .andNew("(is_deleted = 0)")); |
| | | if (Cools.isEmpty(wrkMast)) { |
| | | throw new CoolException(workNo + "工作档不存在"); |
| | | } |
| | | |
| | | // 如果是AGV任务,根据任务状态决定是否需要调用AGV接口取消任务 |
| | | // 仅状态7(新建AGV任务)不访问AGV直接取消;其他状态必须先调用AGV取消接口,AGV返回成功才能取消 |
| | | if ("agv".equals(wrkMast.getTaskType())) { |
| | | Long wrkSts = wrkMast.getWrkSts(); |
| | | if (wrkSts != null && wrkSts == 7L) { |
| | | // 状态7:新建AGV任务,未发送给AGV,无需调用AGV接口,直接取消 |
| | | String displayTaskId = (wrkMast.getWrkNo() != null) ? String.valueOf(wrkMast.getWrkNo()) : String.valueOf(wrkMast.getId()); |
| | | log.info("取消AGV任务:任务ID:{},状态:7(新建AGV任务),无需调用AGV接口,直接取消", displayTaskId); |
| | | } else { |
| | | // 非状态7(含8、9、10等):必须先调用AGV取消接口,AGV返回成功才能取消 |
| | | if (wrkMast.getId() == null) { |
| | | throw new CoolException("取消AGV任务失败:任务ID为空"); |
| | | } |
| | | String agvWrkNo = wrkMast.getAgvWrkNo(); |
| | | Integer wrkNo = wrkMast.getWrkNo(); |
| | | Long taskId = wrkMast.getId(); |
| | | if ((agvWrkNo == null || agvWrkNo.isEmpty()) && wrkNo == null && taskId == null) { |
| | | throw new CoolException("取消AGV任务失败:无法获取有效的任务标识(agvWrkNo、wrkNo和id都为空)"); |
| | | } |
| | | String errorMsg = agvHandler.cancelAgvTask(wrkMast); |
| | | if (errorMsg != null) { |
| | | log.warn("取消AGV任务失败,AGV未返回成功 - 任务ID:{},错误:{}", |
| | | (wrkMast.getWrkNo() != null) ? String.valueOf(wrkMast.getWrkNo()) : String.valueOf(wrkMast.getId()), errorMsg); |
| | | throw new CoolException("取消AGV任务失败:" + errorMsg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | String locNo = ""; // 待修改目标库位 |
| | | String locSts = ""; // 待修改目标库位状态 |
| | | // 入库取消(修改目标库位) |
| | |
| | | if (!taskLogService.save(wrkMast.getWrkNo())) { |
| | | throw new CoolException("保存工作历史档失败, workNo = " + wrkMast.getWrkNo()); |
| | | } |
| | | // 删除工作主档 |
| | | boolean wrkMastRes = taskService.deleteById(wrkMast); |
| | | // 逻辑删除工作主档 |
| | | wrkMast.setIsDeleted(1); |
| | | boolean wrkMastRes = taskService.updateById(wrkMast); |
| | | |
| | | if (wrkMast.getIoType() != 10 && wrkMast.getIoType() != 110) { |
| | | // 删除工作档明细 |
| | | boolean wrkDetlRes = taskDetlService.delete(new EntityWrapper<TaskDetl>().eq("wrk_no", workNo)); |
| | | } |
| | | |
| | | // 修改库位状态 |
| | | LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", locNo)); |
| | | if (Cools.isEmpty(locMast)) { |
| | | throw new CoolException("取消工作档失败,库位不存在:" + locNo); |
| | | // 修改库位状态(如果库位不为空) |
| | | boolean locMastRes = true; |
| | | if (!Cools.isEmpty(locNo)&&wrkMast.getIoType() > 100) { |
| | | LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", locNo)); |
| | | if (Cools.isEmpty(locMast)) { |
| | | throw new CoolException("取消工作档失败,库位不存在:" + locNo); |
| | | } |
| | | if (!Cools.isEmpty(locSts)) { |
| | | locMast.setLocSts(locSts); |
| | | locMast.setModiTime(now); |
| | | locMast.setModiUser(userId); |
| | | locMastRes = locCacheService.updateById(locMast); |
| | | } |
| | | } |
| | | locMast.setLocSts(locSts); |
| | | locMast.setModiTime(now); |
| | | locMast.setModiUser(userId); |
| | | boolean locMastRes = locCacheService.updateById(locMast); |
| | | if (!wrkMastRes || !locMastRes) { |
| | | throw new CoolException("保存数据失败"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteWrkMast(String workNo, Long userId) { |
| | | Date now = new Date(); |
| | | Task wrkMast = this.selectOne(new EntityWrapper<Task>() |
| | | .eq("wrk_no", workNo) |
| | | .andNew("(is_deleted = 0)")); |
| | | if (Cools.isEmpty(wrkMast)) { |
| | | throw new CoolException(workNo + "工作档不存在"); |
| | | } |
| | | |
| | | String displayTaskId = (wrkMast.getWrkNo() != null) ? String.valueOf(wrkMast.getWrkNo()) : String.valueOf(wrkMast.getId()); |
| | | |
| | | // 如果是AGV任务,尝试同步申请AGV取消(但不会被AGV返回的错误校验拦截,会继续删除) |
| | | if ("agv".equals(wrkMast.getTaskType())) { |
| | | Long wrkSts = wrkMast.getWrkSts(); |
| | | // 状态8和9:已发送给AGV任务,尝试调用AGV接口取消任务 |
| | | // 状态10:AGV呼叫异常,可以取消,但不会请求AGV取消接口 |
| | | // 状态7或更早:还未发送给AGV,无需调用AGV接口 |
| | | if (wrkSts != null && wrkSts >= 8L && wrkSts != 10L) { |
| | | try { |
| | | // 验证任务信息是否完整 |
| | | if (wrkMast.getId() != null) { |
| | | // 验证taskId是否可用(agvWrkNo、wrkNo或id至少有一个) |
| | | String agvWrkNo = wrkMast.getAgvWrkNo(); |
| | | Integer wrkNo = wrkMast.getWrkNo(); |
| | | Long taskId = wrkMast.getId(); |
| | | if ((agvWrkNo != null && !agvWrkNo.isEmpty()) || wrkNo != null || taskId != null) { |
| | | // 同步申请AGV取消,但不抛出异常(不会被错误校验拦截) |
| | | String errorMsg = agvHandler.cancelAgvTask(wrkMast); |
| | | if (errorMsg != null) { |
| | | log.warn("删除AGV任务:尝试取消AGV任务失败,但继续执行删除操作,任务ID:{},错误:{}", displayTaskId, errorMsg); |
| | | } else { |
| | | log.info("删除AGV任务:成功取消AGV任务,任务ID:{}", displayTaskId); |
| | | } |
| | | } else { |
| | | log.warn("删除AGV任务:无法获取有效的任务标识(agvWrkNo、wrkNo和id都为空),跳过AGV取消,继续执行删除操作,任务ID:{}", displayTaskId); |
| | | } |
| | | } else { |
| | | log.warn("删除AGV任务:任务ID为空,跳过AGV取消,继续执行删除操作,任务ID:{}", displayTaskId); |
| | | } |
| | | } catch (Exception e) { |
| | | // 捕获所有异常,记录日志但不阻止删除操作(不会被AGV返回的错误校验拦截) |
| | | log.error("删除AGV任务:尝试取消AGV任务时发生异常,但继续执行删除操作,任务ID:{}", displayTaskId, e); |
| | | } |
| | | } else { |
| | | // 状态10(AGV呼叫异常)或状态7或更早,无需调用AGV接口 |
| | | if (wrkSts != null && wrkSts == 10L) { |
| | | log.info("删除AGV任务:任务ID:{},状态:{}(AGV呼叫异常),无需调用AGV接口,直接删除", displayTaskId, wrkSts); |
| | | } else { |
| | | log.info("删除AGV任务:任务ID:{},状态:{}(待呼叫AGV或更早),无需调用AGV接口,直接删除", displayTaskId, wrkSts); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 释放库位等资源(类似cancelWrkMast的逻辑) |
| | | String locNo = ""; // 待修改目标库位 |
| | | String locSts = ""; // 待修改目标库位状态 |
| | | // 入库取消(修改目标库位) |
| | | if (wrkMast.getIoType() < 100) { |
| | | locNo = wrkMast.getLocNo(); |
| | | locSts = "O"; |
| | | |
| | | // 库位转移 |
| | | if (wrkMast.getIoType() == 11) { |
| | | // 库位转移:源库位 |
| | | LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", wrkMast.getSourceLocNo())); |
| | | if (!Cools.isEmpty(locMast)) { |
| | | locMast.setLocSts(wrkMast.getFullPlt().equalsIgnoreCase("N") ? "D" : "F"); |
| | | locMast.setModiTime(now); |
| | | locMast.setModiUser(userId); |
| | | locCacheService.updateById(locMast); |
| | | } |
| | | } |
| | | // 出库取消(修改源库位) |
| | | } else { |
| | | locNo = wrkMast.getSourceLocNo(); |
| | | // 出库 ===>> F.在库 |
| | | if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) { |
| | | locSts = "F"; |
| | | // 空板出库 ===>> D.空桶/空栈板 |
| | | } else if (wrkMast.getIoType() == 110) { |
| | | locSts = "D"; |
| | | // 库位转移 ===>> D.空桶/空栈板 |
| | | } else if (wrkMast.getIoType() == 11) { |
| | | locSts = wrkMast.getFullPlt().equalsIgnoreCase("N") ? "D" : "F"; |
| | | // 库位转移:目标库位 |
| | | LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", wrkMast.getLocNo())); |
| | | if (!Cools.isEmpty(locMast)) { |
| | | locMast.setLocSts("O"); |
| | | locMast.setModiTime(now); |
| | | locMast.setModiUser(userId); |
| | | locCacheService.updateById(locMast); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //取消入库工作档时,查询组托表,如果有将状态改为待处理 |
| | | if (wrkMast.getIoType() == 1) { |
| | | List<WaitPakin> waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", wrkMast.getBarcode())); |
| | | for (WaitPakin waitPakin : waitPakins) { |
| | | if (!Cools.isEmpty(waitPakin)) { |
| | | waitPakin.setIoStatus("N"); |
| | | waitPakin.setLocNo(""); |
| | | waitPakinService.update(waitPakin, new EntityWrapper<WaitPakin>() |
| | | .eq("zpallet", waitPakin.getZpallet()) |
| | | .eq("matnr", waitPakin.getMatnr()) |
| | | .eq("batch", waitPakin.getBatch())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 删除操作人员记录 |
| | | wrkMast.setManuType("手动删除"); |
| | | wrkMast.setModiUser(userId); |
| | | wrkMast.setModiTime(now); |
| | | // 逻辑删除工作主档 |
| | | wrkMast.setIsDeleted(1); |
| | | if (!taskService.updateById(wrkMast)) { |
| | | throw new CoolException("删除工作档失败"); |
| | | } |
| | | |
| | | if (wrkMast.getIoType() != 10 && wrkMast.getIoType() != 110) { |
| | | // 删除工作档明细 |
| | | taskDetlService.delete(new EntityWrapper<TaskDetl>().eq("wrk_no", workNo)); |
| | | } |
| | | |
| | | // 修改库位状态(如果库位不为空) |
| | | if (!Cools.isEmpty(locNo) && wrkMast.getIoType() > 100) { |
| | | LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", locNo)); |
| | | if (!Cools.isEmpty(locMast) && !Cools.isEmpty(locSts)) { |
| | | locMast.setLocSts(locSts); |
| | | locMast.setModiTime(now); |
| | | locMast.setModiUser(userId); |
| | | locCacheService.updateById(locMast); |
| | | } |
| | | } |
| | | |
| | | // 如果是入库任务,释放预约库位 |
| | | if (wrkMast.getIoType() != null && wrkMast.getIoType() < 100 && !Cools.isEmpty(wrkMast.getLocNo())) { |
| | | try { |
| | | LocCache locCache = locCacheService.selectOne( |
| | | new EntityWrapper<LocCache>().eq("loc_no", wrkMast.getLocNo()) |
| | | ); |
| | | if (locCache != null && "S".equals(locCache.getLocSts())) { |
| | | // 库位状态为S(入库预约),释放为O(闲置) |
| | | locCache.setLocSts("O"); |
| | | locCache.setModiTime(now); |
| | | locCache.setModiUser(userId); |
| | | locCacheService.updateById(locCache); |
| | | log.info("删除AGV任务:已释放预约库位:{}(S→O),任务ID:{}", wrkMast.getLocNo(), displayTaskId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("删除AGV任务:释放预约库位失败,库位:{},任务ID:{}", wrkMast.getLocNo(), displayTaskId, e); |
| | | } |
| | | } |
| | | |
| | | log.info("删除AGV任务成功:任务ID:{},工作号:{}", displayTaskId, workNo); |
| | | } |
| | | |
| | | @Override |
| | | public List<Task> selectToBeHistoryData() { |
| | | return this.baseMapper.selectToBeHistoryData(); |
| | | } |