From a41f345b4e34930838f18095ae109eea367ef9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=97=AD=E6=98=8E=5C73939?= <739390650@QQ.COM> Date: Wed, 17 Dec 2025 18:24:49 +0800 Subject: [PATCH] =?UTF-8?q?opt:=E8=A5=BF=E9=97=A8=E5=AD=90=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E4=B8=8A=E7=BA=BF=E7=89=88=E6=9C=AC20251217?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../connector/service/dto/ConnectorDto.java | 4 + .../wms/ext/fab/controller/FabController.java | 23 +- .../ext/fab/service/dto/ExceptionInfo.java | 34 ++ .../wms/ext/fab/service/dto/OrderMater.java | 2 + .../ext/fab/service/impl/FabServiceImpl.java | 123 ++++ .../controller/HandheldController.java | 64 ++ .../ext/handheld/service/HandheldService.java | 50 ++ .../service/impl/HandheldServiceImpl.java | 555 +++++++++++++++++- .../service/impl/SortingServiceImpl.java | 35 +- .../nl/wms/sch/group/core/GroupStatus.java | 71 +++ .../dao/SchBaseVehiclematerialgroup.java | 4 + .../SchBaseVehiclematerialgroupMapper.xml | 4 +- ...chBaseVehiclematerialgroupServiceImpl.java | 26 + .../point/service/ISchBasePointService.java | 2 +- .../dao/mapper/SchBasePointMapper.java | 7 +- .../service/dao/mapper/SchBasePointMapper.xml | 75 +++ .../service/impl/SchBasePointServiceImpl.java | 119 +++- .../handheld/CombineSourceStoreInTask.java | 217 +++++++ .../handheld/CombineTargetStoreInTask.java | 180 ++++++ .../src/views/wms/produceScreen/index.vue | 431 +++++++++++++- .../views/wms/produceScreen/produceScreen.js | 20 +- .../src/views/wms/produceScreen/style.scss | 34 +- 22 files changed, 2013 insertions(+), 67 deletions(-) create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/ExceptionInfo.java create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/core/GroupStatus.java create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/handheld/CombineSourceStoreInTask.java create mode 100644 lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/task_manage/task/tasks/handheld/CombineTargetStoreInTask.java diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/connector/service/dto/ConnectorDto.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/connector/service/dto/ConnectorDto.java index 3f4bcb1..2140485 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/connector/service/dto/ConnectorDto.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/connector/service/dto/ConnectorDto.java @@ -97,6 +97,10 @@ public class ConnectorDto { * 交期时间 */ private String due_date; + /** + * 是否在库 + */ + private Boolean is_in_stock; /** * 优先级 */ diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/controller/FabController.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/controller/FabController.java index 161b0ca..4d4139a 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/controller/FabController.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/controller/FabController.java @@ -2,6 +2,7 @@ package org.nl.wms.ext.fab.controller; import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -59,7 +60,21 @@ public class FabController { /** - * 设备工序列表 + * 获取异常信息 + * + * @param deviceCode 设备编码 + * @return + */ + @Log("获取异常信息") + @GetMapping("/getExceptionMessage") + public ResponseEntity getExceptionMessage(String deviceCode) { + // 调用服务层获取异常信息 + List exceptions = fabService.getExceptionInfo(deviceCode); + return new ResponseEntity(TableDataInfo.build(exceptions), HttpStatus.OK); + } + + /** + * 获取异常详情接口 * * @return */ @@ -100,8 +115,8 @@ public class FabController { */ @Log("根据设备工序查询工单") @GetMapping("/regionOrder") - public ResponseEntity> selectOrderByPointCode(String deviceCode) { - List structList = iSchBasePointService.getStructList(deviceCode, null); + public ResponseEntity> selectOrderByPointCode(String deviceCode, String searchKey) { + List structList = iSchBasePointService.getStructList(deviceCode, null, searchKey); return new ResponseEntity(TableDataInfo.build(structList), HttpStatus.OK); } @@ -128,7 +143,7 @@ public class FabController { @Log("根据工单查询匹配库存") @GetMapping("/getMaterListByOrder") public ResponseEntity>> getMaterListByOrder(String order, String regionCode) { - List structList = iSchBasePointService.getStructList(regionCode, null); + List structList = iSchBasePointService.getStructList(regionCode, null,null); return new ResponseEntity(TableDataInfo.build(structList), HttpStatus.OK); } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/ExceptionInfo.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/ExceptionInfo.java new file mode 100644 index 0000000..62d1047 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/ExceptionInfo.java @@ -0,0 +1,34 @@ +package org.nl.wms.ext.fab.service.dto; + +/** + * 异常信息实体类 + */ +public class ExceptionInfo { + private String type; + private String message; + private String time; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/OrderMater.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/OrderMater.java index e2d4874..1e2545b 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/OrderMater.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/dto/OrderMater.java @@ -44,4 +44,6 @@ public class OrderMater { public String create_time; public String priority; + + public String is_lock; } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/impl/FabServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/impl/FabServiceImpl.java index 372ba25..3114632 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/impl/FabServiceImpl.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/fab/service/impl/FabServiceImpl.java @@ -7,9 +7,11 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import nl.basjes.shaded.org.springframework.util.Assert; +import org.checkerframework.checker.units.qual.A; import org.nl.common.enums.GoodsEnum; import org.nl.common.enums.region.RegionEnum; import org.nl.common.exception.BadRequestException; +import org.nl.system.service.param.dao.Param; import org.nl.wms.database.vehicle.service.IMdBaseVehicleService; import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle; import org.nl.wms.ext.acs.service.dto.to.BaseResponse; @@ -20,9 +22,13 @@ import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService; import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup; import org.nl.wms.sch.point.service.ISchBasePointService; import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.task.service.ISchBaseTaskService; +import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task_manage.task.core.TaskStatus; import org.nl.wms.sch.task_manage.task.tasks.pcoperation.PcOperationCMTask; import org.nl.wms.sch.task_manage.task.tasks.pcoperation.PcOperationSMTTask; import org.nl.wms.sch.task_manage.task.tasks.pcoperation.PcOperationSNTTask; +import org.nl.wms.sch.task_manage.task.tasks.pcoperation.PcOperationCNTask; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -42,6 +48,8 @@ public class FabServiceImpl { private ISchBasePointService iSchBasePointService; @Autowired private IMdBaseVehicleService iMdBaseVehicleService; + @Autowired + private ISchBaseTaskService iSchBaseTaskService; /** * pc呼叫满料 */ @@ -52,6 +60,8 @@ public class FabServiceImpl { @Autowired private PcOperationSNTTask pcOperationSNTTask; @Autowired + private PcOperationCNTask pcOperationCNTask; + @Autowired private ISchBaseVehiclematerialgroupService iSchBaseVehiclematerialgroupService; @@ -76,6 +86,119 @@ public class FabServiceImpl { } } + /** + * 获取设备异常信息 + * @param deviceCode 设备编码 + * @return 异常信息列表 + */ + public List getExceptionInfo(String deviceCode) { + List exceptions = new ArrayList<>(); + + //查询当前点位执行中的任务 + List schBaseTasks = iSchBaseTaskService.list(Wrappers.lambdaQuery(SchBaseTask.class) + .gt(SchBaseTask::getTask_status, TaskStatus.CREATED.getCode()) + .lt(SchBaseTask::getTask_status, TaskStatus.FINISHED.getCode()) + .and(lam -> lam.eq(SchBaseTask::getPoint_code1,deviceCode) + .or() + .eq(SchBaseTask::getPoint_code2,deviceCode)) + .ne(SchBaseTask::getTask_status,"任务完成") + .ne(SchBaseTask::getTask_status,"任务取消") + .ne(SchBaseTask::getTask_status,"") + .ne(SchBaseTask::getTask_status,null) + ); + for(SchBaseTask schBaseTask : schBaseTasks){ + ExceptionInfo exception = new ExceptionInfo(); + exception.setType("任务异常"); + exception.setMessage(schBaseTask.getRemark()); + exception.setTime(cn.hutool.core.date.DateUtil.now()); + exceptions.add(exception); + } + + // 检查载具无编号异常 + checkVehicleCode(deviceCode, exceptions); + + // 检查起点终点锁定异常 + checkPointLock(deviceCode, exceptions); + + // 检查ACS未连接异常 + checkAcsConnection(deviceCode, exceptions); + + // 检查AGV传感器报警异常 + checkAgvSensorAlarm(deviceCode, exceptions); + + // 检查sorting下发任务失败异常 + checkSortingTaskFailure(deviceCode, exceptions); + + return exceptions; + } + + /** + * 检查载具无编号异常 + */ + private void checkVehicleCode(String deviceCode, List exceptions) { + // SchBasePoint point = iSchBasePointService.selectByPointCode(deviceCode); + // if (point != null && (point.getVehicle_code() == null || point.getVehicle_code().isEmpty())) { + // ExceptionInfo exception = new ExceptionInfo(); + // exception.setType("载具异常"); + // exception.setMessage("载具无编号,请检查载具信息"); + // exception.setTime(cn.hutool.core.date.DateUtil.now()); + // exceptions.add(exception); + // } + } + + /** + * 检查起点终点锁定异常 + */ + private void checkPointLock(String deviceCode, List exceptions) { + // SchBasePoint point = iSchBasePointService.selectByPointCode(deviceCode); + // if (point != null && point.getIs_lock() != null && point.getIs_lock()) { + // ExceptionInfo exception = new ExceptionInfo(); + // exception.setType("系统异常"); + // exception.setMessage("起点终点锁定,无法执行操作"); + // exception.setTime(cn.hutool.core.date.DateUtil.now()); + // exceptions.add(exception); + // } + } + + /** + * 检查ACS未连接异常 + */ + private void checkAcsConnection(String deviceCode, List exceptions) { + // TODO: 实现ACS未连接检查逻辑 + // 这里需要调用ACS相关服务检查连接状态 + // ExceptionInfo exception = new ExceptionInfo(); + // exception.setType("ACS异常"); + // exception.setMessage("ACS未连接,请检查ACS服务"); + // exception.setTime(cn.hutool.core.date.DateUtil.now()); + // exceptions.add(exception); + } + + /** + * 检查AGV传感器报警异常 + */ + private void checkAgvSensorAlarm(String deviceCode, List exceptions) { + // TODO: 实现AGV传感器报警检查逻辑 + // 这里需要调用AGV相关服务检查传感器状态 + // ExceptionInfo exception = new ExceptionInfo(); + // exception.setType("AGV异常"); + // exception.setMessage("AGV传感器报警,请检查AGV设备"); + // exception.setTime(cn.hutool.core.date.DateUtil.now()); + // exceptions.add(exception); + } + + /** + * 检查sorting下发任务失败异常 + */ + private void checkSortingTaskFailure(String deviceCode, List exceptions) { + // TODO: 实现sorting下发任务失败检查逻辑 + // 这里需要查询任务表,检查sorting任务的状态 + // ExceptionInfo exception = new ExceptionInfo(); + // exception.setType("任务异常"); + // exception.setMessage("sorting下发任务失败,请检查任务配置"); + // exception.setTime(cn.hutool.core.date.DateUtil.now()); + // exceptions.add(exception); + } + @Transactional(rollbackFor = Exception.class) public void createAgvTask(JSONObject form, String type) { JSONObject param = new JSONObject(); diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/controller/HandheldController.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/controller/HandheldController.java index 865d0a2..177e9ae 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/controller/HandheldController.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/controller/HandheldController.java @@ -1,12 +1,16 @@ package org.nl.wms.ext.handheld.controller; import cn.dev33.satoken.annotation.SaIgnore; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.nl.common.base.TableDataInfo; import org.nl.common.logging.annotation.Log; +import org.nl.wms.ext.fab.service.dto.CallEmpVo; +import org.nl.wms.ext.fab.service.impl.FabServiceImpl; import org.nl.wms.ext.handheld.service.HandheldService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -28,6 +32,9 @@ public class HandheldController { @Autowired private HandheldService handheldService; + @Autowired + private FabServiceImpl fabService; + @PostMapping("/cageFrame") @Log("笼框补仓") public ResponseEntity createEmptyCageStorageTask(@RequestBody JSONObject param) { @@ -158,15 +165,72 @@ public class HandheldController { public ResponseEntity selectMaterialAndJpg(String pointCode) { return new ResponseEntity<>(handheldService.selectMaterialAndJpg(pointCode), HttpStatus.OK); } + + @PostMapping("/selectMaterial") + @Log("查询组盘物料信息") + public ResponseEntity selectMaterial(@RequestBody JSONObject json) { + //因为前端已经固定,后端跟随调整。因此看起来有点奇怪 + return new ResponseEntity<>(handheldService.selectMaterialByVehicleCode(json.getString("pointCode")), HttpStatus.OK); + } + @PostMapping("/getLlddw") @Log("查询料笼对接位点位状态") public ResponseEntity getLlddw() { return new ResponseEntity<>(handheldService.getLlddw(), HttpStatus.OK); } + @PostMapping("/fillUpEmpty") @Log("料笼对接位点位变成空载具") public ResponseEntity fillUpEmpty(@RequestBody JSONObject json) { handheldService.fillUpEmpty(json); return new ResponseEntity<>(HttpStatus.OK); } + + @PostMapping("/checkTrayInfo") + @Log("查询托盘物料信息用于合托") + @ApiOperation("查询托盘物料信息用于合托") + public ResponseEntity checkTrayInfo(@RequestBody JSONObject json) { + return new ResponseEntity<>(handheldService.checkTrayInfo(json.getString("vehicle_code")), HttpStatus.OK); + } + + @PostMapping("/combineMaterials") + @Log("执行合托操作") + @ApiOperation("执行合托操作") + public ResponseEntity combineMaterials(@RequestBody JSONObject json) { + return new ResponseEntity<>(handheldService.combineMaterials(json), HttpStatus.OK); + } + + @Log("查询托盘状态") + @ApiOperation(value = "查询托盘状态", notes = "查询托盘状态,包括是否在货架上、所在位置等信息") + @GetMapping("/queryVehicleStatus/{vehicleCode}") + public ResponseEntity queryVehicleStatus(@PathVariable String vehicleCode) { + return new ResponseEntity<>(handheldService.queryVehicleStatus(vehicleCode), HttpStatus.OK); + } + + @Log("生成入库任务") + @ApiOperation(value = "生成入库任务", notes = "扫描托盘码后生成入库任务") + @PostMapping("/generateStoreInTask") + public ResponseEntity generateStoreInTask(@RequestBody JSONObject json) { + return new ResponseEntity<>(handheldService.generateStoreInTask(json), HttpStatus.OK); + } + + @Log("查询托盘任务状态") + @ApiOperation(value = "查询托盘任务状态", notes = "检查AGV是否已取走托盘") + @GetMapping("/queryVehicleTaskStatus/{vehicleCode}") + public ResponseEntity queryVehicleTaskStatus(@PathVariable String vehicleCode) { + return new ResponseEntity<>(handheldService.queryVehicleTaskStatus(vehicleCode), HttpStatus.OK); + } + + /** + * 呼叫空料框 + * + * @return + */ + @Log("呼叫空料框") + @PostMapping("/callEmp") + public ResponseEntity callEmp(@RequestBody CallEmpVo callEmpVo) { + JSONObject toJSON = (JSONObject) JSON.toJSON(callEmpVo); + fabService.createAgvTask(toJSON, "cnt"); + return new ResponseEntity(TableDataInfo.build(), HttpStatus.OK); + } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/HandheldService.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/HandheldService.java index b448430..92f4886 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/HandheldService.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/HandheldService.java @@ -120,6 +120,20 @@ public interface HandheldService { * @return */ JSONObject selectMaterialAndJpg(String pointCode); + + /** + * 根据当前点位的托盘号查询物料信息 + * @param pointCode + * @return + */ + JSONObject selectMaterial(String pointCode); + + /** + * 根据当前点位的托盘号查询物料信息 + * @param + * @return + */ + JSONObject selectMaterialByVehicleCode(String vehicleCode); /** * 根据点位删除点位所在的载具信息 * @param pointCode @@ -128,4 +142,40 @@ public interface HandheldService { JSONObject deletevehiclemessage(String pointCode); List getLlddw(); void fillUpEmpty(JSONObject json); + + /** + * 查询托盘物料信息用于合托 + * @param vehicleCode 托盘编号 + * @return 查询结果 + */ + JSONObject checkTrayInfo(String vehicleCode); + + /** + * 执行合托操作 + * @param json 包含源托盘号、目标托盘号、选中的物料信息等 + * @return 合托结果,包含是否需要入库等信息 + */ + JSONObject combineMaterials(JSONObject json); + + /** + * 查询托盘状态 + * @param vehicleCode 托盘号 + * @return 托盘状态信息,包含是否在货架上、所在位置等 + */ + JSONObject queryVehicleStatus(String vehicleCode); + + /** + * 生成入库任务 + * @param json 参数,包含托盘号、操作人员等信息 + * @return 执行结果,包含是否成功、提示信息等 + */ + JSONObject generateStoreInTask(JSONObject json); + + /** + * 查询托盘任务状态,检查AGV是否已取走托盘 + * @param vehicleCode 托盘编号 + * @return 包含托盘任务状态、是否已取走等信息 + */ + JSONObject queryVehicleTaskStatus(String vehicleCode); + } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/impl/HandheldServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/impl/HandheldServiceImpl.java index b4786a9..a5797f7 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/impl/HandheldServiceImpl.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/handheld/service/impl/HandheldServiceImpl.java @@ -1,16 +1,29 @@ package org.nl.wms.ext.handheld.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import java.math.BigDecimal; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.Synchronized; import nl.basjes.shaded.org.springframework.util.Assert; import org.nl.common.enums.GoodsEnum; import org.nl.common.enums.VehicleTypeEnum; import org.nl.common.enums.region.RegionEnum; +import org.nl.system.service.dict.ISysDictService; +import org.nl.system.service.dict.dao.Dict; +import org.nl.wms.sch.task.service.dao.SchBaseTask; +import org.nl.wms.sch.task_manage.enums.GroupBindMaterialStatusEnum; import org.nl.common.exception.BadRequestException; import org.nl.common.utils.RedisUtils; import org.nl.common.utils.SecurityUtils; @@ -37,21 +50,27 @@ import org.nl.wms.sch.task.service.ISchBaseTaskService; import org.nl.wms.sch.task_manage.AbstractTask; import org.nl.wms.sch.task_manage.GeneralDefinition; import org.nl.wms.sch.task_manage.task.TaskFactory; +import org.nl.wms.sch.task_manage.task.core.TaskStatus; import org.nl.wms.sch.task_manage.task.core.TaskType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + import java.util.stream.Collectors; /** * @author LENOVO */ +@Slf4j @Service public class HandheldServiceImpl implements HandheldService { @@ -77,6 +96,10 @@ public class HandheldServiceImpl implements HandheldService { private WmsToAcsService wmsToAcsService; @Autowired private SchBaseVehiclematerialgroupMapper vehiclematerialgroupMapper; + + @Autowired + private ISysDictService dictService; + @Autowired private SchBasePointMapper schBasePointMapper; static final Map STATUS = MapOf.of("释放", "0", "锁定", "1"); @@ -199,7 +222,6 @@ public class HandheldServiceImpl implements HandheldService { * 验证托盘数量和类型 * * @param vehicles 回库托盘号 - * @param number 托盘数 * @param vehicleType 托盘类型 */ private void verifyNumber(String[] vehicles, String vehicleType) { @@ -648,6 +670,54 @@ public class HandheldServiceImpl implements HandheldService { return iSchBasePointService.selectPointByRegion(regionCode); } + @Override + public JSONObject selectMaterial(String pointCode) { + if (StrUtil.isEmpty(pointCode)) { + throw new BadRequestException("当前点位不能为空!"); + } + SchBasePoint schBasePoint = iSchBasePointService.selectByPointCode(pointCode); + if (ObjectUtil.isEmpty(schBasePoint)) { + throw new BadRequestException("当前点位不存在!"); + } + if (StrUtil.isNotEmpty(schBasePoint.getVehicle_code())) { + List list = new ArrayList<>(); + list.add(schBasePoint.getVehicle_code()); + List maps = iSchBaseVehiclematerialgroupService.selectOrdersByVehicleCode(list); + HashSet keys = new HashSet<>(); + maps.stream().forEach(item -> { + keys.add(MapOf.of("material_code", item.get("material_id"), "order_code", item.get("order_code"), + "material_qty", item.get("material_qty"), "due_date", item.get("due_date"))); + }); + JSONObject json = new JSONObject(); + json.put("materialList", keys); + return json; + } + return null; + } + + @Override + public JSONObject selectMaterialByVehicleCode(String vehicleCode) { + if (StrUtil.isEmpty(vehicleCode)) { + throw new BadRequestException("当前托盘不能为空!"); + } + + if (StrUtil.isNotEmpty(vehicleCode)) { + List list = new ArrayList<>(); + list.add(vehicleCode); + List maps = iSchBaseVehiclematerialgroupService.selectOrdersByVehicleCode(list); + HashSet keys = new HashSet<>(); + maps.stream().forEach(item -> { + keys.add(MapOf.of("material_code", item.get("material_id"), "order_code", item.get("order_code"), + "material_qty", item.get("material_qty"), "due_date", item.get("due_date"))); + }); + JSONObject json = new JSONObject(); + json.put("materialList", keys); + return json; + } + return null; + } + + @Override public JSONObject selectMaterialAndJpg(String pointCode) { if (StrUtil.isEmpty(pointCode)) { @@ -706,4 +776,487 @@ public class HandheldServiceImpl implements HandheldService { .eq(SchBasePoint::getPoint_code,pointCode) .set(SchBasePoint::getPoint_status, "1")); } + + @Override + public JSONObject checkTrayInfo(String vehicleCode) { + cn.hutool.core.lang.Assert.notBlank(vehicleCode, "托盘号不能为空"); + + try { + // 1. 检查托盘是否存在 + MdBaseVehicle vehicle = iMdBaseVehicleService.selectByVehicleCode(vehicleCode); + if (ObjectUtil.isEmpty(vehicle)) { + throw new BadRequestException("托盘不存在"); + } + + // 2. 查询托盘上的物料信息 + List materials = iSchBaseVehiclematerialgroupService.selectMaterialByVehicleCode(vehicleCode); + + // 3. 查询托盘所在位置 + SchBasePoint point = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", vehicleCode)); + + // 4. 组装返回结果 + JSONObject result = new JSONObject(); + result.put("vehicle_code", vehicleCode); + result.put("vehicle_type", vehicle.getVehicle_type()); + result.put("vehicle_type_name", vehicle.getVehicle_name()); + result.put("materials", materials); + + if (ObjectUtil.isNotEmpty(point)) { + result.put("point_code", point.getPoint_code()); + result.put("point_name", point.getPoint_name()); + result.put("region_code", point.getRegion_code()); + result.put("region_name", point.getRegion_name()); + } + + log.info("查询托盘信息成功:托盘编号[{}]", vehicleCode); + return result; + } catch (BadRequestException e) { + throw e; + } catch (Exception e) { + log.error("查询托盘信息失败:托盘编号[{}]", vehicleCode, e); + throw new BadRequestException("查询托盘信息失败:" + e.getMessage()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public JSONObject combineMaterials(JSONObject json) { + String operatorId = SecurityUtils.getCurrentNickName(); + cn.hutool.core.lang.Assert.notEmpty(json, "参数不能为空"); + String sourceVehicleCode = json.getString("source_vehicle_code"); // 原始托盘号 + String targetVehicleCode = json.getString("target_vehicle_code"); // 目标托盘号 + JSONArray selectedMaterials = json.getJSONArray("selected_materials"); // 选中的物料信息 + + // 参数验证 + cn.hutool.core.lang.Assert.notBlank(sourceVehicleCode, "原始托盘号不能为空"); + cn.hutool.core.lang.Assert.notBlank(targetVehicleCode, "目标托盘号不能为空"); + cn.hutool.core.lang.Assert.notEmpty(selectedMaterials, "至少选择一项物料进行合托"); + + // 验证源托盘和目标托盘不能相同 + if (sourceVehicleCode.equals(targetVehicleCode)) { + throw new BadRequestException("原始托盘和目标托盘不能相同"); + } + + try { + // 1. 检查托盘是否存在并获取托盘信息 + MdBaseVehicle sourceVehicle = iMdBaseVehicleService.selectByVehicleCode(sourceVehicleCode); + if (ObjectUtil.isEmpty(sourceVehicle)) { + throw new BadRequestException("原始托盘不存在"); + } + + MdBaseVehicle targetVehicle = iMdBaseVehicleService.selectByVehicleCode(targetVehicleCode); + if (ObjectUtil.isEmpty(targetVehicle)) { + throw new BadRequestException("目标托盘不存在"); + } + + List dictNotPointList = dictService.getDictByName("not_call_point_code"); + List notInPointList = new ArrayList<>(); + if(!CollectionUtils.isEmpty(dictNotPointList)){ + notInPointList = dictNotPointList.stream().map(Dict::getValue).collect(Collectors.toList()); + } + + // 2. 查询托盘所在位置,判断是否都在货架上 + SchBasePoint sourcePoint = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", sourceVehicleCode) + .notIn("point_code", Arrays.asList("SD01", "SD02")) + .notIn(!CollectionUtils.isEmpty(dictNotPointList),"point_code",notInPointList)); + SchBasePoint targetPoint = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", targetVehicleCode) + .notIn("point_code", Arrays.asList("SD01", "SD02")) + .notIn(!CollectionUtils.isEmpty(dictNotPointList),"point_code",notInPointList)); + + // 3. 并发控制:锁定托盘 + synchronized (this) { + try { + // 4. 查询源托盘的所有物料信息 + List allSourceMaterials = iSchBaseVehiclematerialgroupService.selectByVehicleCode(sourceVehicleCode); + + + // 7. 执行合托操作 + for (int i = 0; i < selectedMaterials.size(); i++) { + JSONObject selectedMaterial = selectedMaterials.getJSONObject(i); + String order_code = selectedMaterial.getString("order_code"); + String material_code = selectedMaterial.getString("material_code"); + + List sourceGroups = allSourceMaterials.stream() + .filter(a -> a.getOrder_code().equals(order_code) && a.getMaterial_id().equals(material_code)) + .collect(Collectors.toList()); + + if(CollectionUtil.isEmpty(sourceGroups)){ + throw new BadRequestException("不存在合托的物料编码和订单"); + } + + for (SchBaseVehiclematerialgroup sourceGroup : sourceGroups) { + sourceGroup.setVehicle_code(targetVehicleCode); + sourceGroup.setUpdate_time(DateUtil.now()); + sourceGroup.setUpdate_name(operatorId); + sourceGroup.setCreate_name(operatorId); + vehiclematerialgroupMapper.updateById(sourceGroup); + } + } + + // 8. 判断是否需要入库:如果两个托盘都不在货架上,则需要入库 + boolean needStoreIn = ObjectUtil.isEmpty(sourcePoint) && ObjectUtil.isEmpty(targetPoint); + + // 9. 组装返回结果 + JSONObject result = new JSONObject(); + result.put("success", true); + result.put("message", "合托操作成功"); + result.put("need_store_in", needStoreIn); + result.put("source_vehicle_code", sourceVehicleCode); + result.put("target_vehicle_code", targetVehicleCode); + + log.info("合托操作成功:源托盘[{}] -> 目标托盘[{}], 是否需要入库: {}", + sourceVehicleCode, targetVehicleCode, needStoreIn); + + return result; + } catch (BadRequestException e) { + throw e; + } + } + } catch (BadRequestException e) { + throw e; + } catch (Exception e) { + log.error("合托操作失败:源托盘[{}] -> 目标托盘[{}]", sourceVehicleCode, targetVehicleCode, e); + throw new BadRequestException("合托操作失败:" + e.getMessage()); + } + } + + @Override + public JSONObject queryVehicleStatus(String vehicleCode) { + cn.hutool.core.lang.Assert.notBlank(vehicleCode, "托盘号不能为空"); + + try { + // 1. 检查托盘是否存在 + MdBaseVehicle vehicle = iMdBaseVehicleService.selectByVehicleCode(vehicleCode); + if (ObjectUtil.isEmpty(vehicle)) { + throw new BadRequestException("托盘不存在"); + } + + // 2. 查询托盘所在位置 + SchBasePoint point = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", vehicleCode)); + + // 3. 判断托盘是否在货架上 + boolean isOnShelf = ObjectUtil.isNotEmpty(point); + + // 4. 查询托盘上的物料数量 + List groups = vehiclematerialgroupMapper.selectList( + Wrappers.lambdaQuery(SchBaseVehiclematerialgroup.class) + .eq(SchBaseVehiclematerialgroup::getVehicle_code, vehicleCode) + .eq(SchBaseVehiclematerialgroup::getIs_delete, false) + ); + boolean hasMaterial = CollectionUtil.isNotEmpty(groups); + + // 5. 查询是否有进行中的任务 + Integer taskCount = iSchBaseTaskService.count(new QueryWrapper() + .eq("vehicle_code", vehicleCode) + .lt("task_status",TaskStatus.FINISHED.getCode())); + + // 6. 组装返回结果 + JSONObject result = new JSONObject(); + result.put("vehicleCode", vehicleCode); + result.put("isOnShelf", isOnShelf); + result.put("hasMaterial", hasMaterial); + + if (isOnShelf) { + result.put("pointCode", point.getPoint_code()); + result.put("pointName", point.getPoint_name()); + result.put("regionCode", point.getRegion_code()); + result.put("regionName", point.getRegion_name()); + } + + // 7. 查询托盘状态(空闲/占用) + String vehicleStatus = ""; + if (hasMaterial || isOnShelf) { + vehicleStatus = "1"; // 1表示占用 + } else { + vehicleStatus = "0"; // 0表示空闲 + } + result.put("vehicleStatus", vehicleStatus); + + log.info("查询托盘状态成功:托盘编号[{}], 是否在货架上: {}, 托盘状态: {}", + vehicleCode, isOnShelf, vehicleStatus); + + return result; + } catch (BadRequestException e) { + throw e; + } catch (Exception e) { + log.error("查询托盘状态失败:托盘编号[{}]", vehicleCode, e); + throw new BadRequestException("查询托盘状态失败:" + e.getMessage()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public JSONObject generateStoreInTask(JSONObject json) { + String operatorId = SecurityUtils.getCurrentNickName(); + cn.hutool.core.lang.Assert.notEmpty(json, "参数不能为空"); + String vehicle_code = json.getString("vehicle_code"); // 入库托盘号 + String point_code = json.getString("point_code"); // 入库点位 + String sourceVehicleCode = json.getString("source_vehicle_code"); // 原始托盘号 + String targetVehicleCode = json.getString("target_vehicle_code"); // 目标托盘号 + + // 参数验证 + cn.hutool.core.lang.Assert.notBlank(sourceVehicleCode, "原始托盘号不能为空"); + cn.hutool.core.lang.Assert.notBlank(targetVehicleCode, "目标托盘号不能为空"); + cn.hutool.core.lang.Assert.notBlank(vehicle_code, "托盘号不能为空"); + cn.hutool.core.lang.Assert.notBlank(point_code, "入库点位不能为空"); + + try { + MdBaseVehicle targetVehicle = iMdBaseVehicleService.selectByVehicleCode(targetVehicleCode); + MdBaseVehicle sourceVehicle = iMdBaseVehicleService.selectByVehicleCode(sourceVehicleCode); + // 1. 检查点位是否存在 + SchBasePoint point = iSchBasePointService.selectByPointCode(point_code); + if (ObjectUtil.isEmpty(point)) { + throw new BadRequestException("入库点位不存在"); + } + + // 2. 检查托盘是否存在 + MdBaseVehicle vehicle = iMdBaseVehicleService.selectByVehicleCode(vehicle_code); + if (ObjectUtil.isEmpty(vehicle)) { + throw new BadRequestException("托盘不存在"); + } + + // 3. 检查是否是第二次入库,如果是,检查第一个托盘是否已被取走 + boolean isSecondStoreIn = false; + String firstVehicleCode = ""; + + if (StrUtil.isNotBlank(sourceVehicleCode) && StrUtil.isNotBlank(targetVehicleCode)) { + if (vehicle_code.equals(sourceVehicleCode)) { + + //查询targetVehicleCode 最近一条任务是否是合托入库任务,如果是则是二次 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(SchBaseTask::getIs_delete, 0) // 未删除 + .eq(SchBaseTask::getVehicle_code, targetVehicleCode) // 指定车辆 + .orderByDesc(SchBaseTask::getCreate_time) // 按创建时间降序(最新的在前) + .last("LIMIT 1"); + + SchBaseTask lastTask = iSchBaseTaskService.getOne(queryWrapper, false); // false:多条结果时不抛异常(保证只取1条) + + // 判断:若最近一条任务存在,且配置码是合托入库,则标记为二次入库 + if (lastTask != null &&"COMBINETARGETSTOREINTask".equals(lastTask.getConfig_code())) { + isSecondStoreIn = true; + firstVehicleCode = targetVehicleCode; + } + } else if (vehicle_code.equals(targetVehicleCode)) { + // 注释:判断sourceVehicleCode最近一条任务是否是合托入库任务,若是则标记为二次入库 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(SchBaseTask::getIs_delete, 0) // 未删除 + .eq(SchBaseTask::getVehicle_code, sourceVehicleCode) // 指定车辆 + .orderByDesc(SchBaseTask::getCreate_time) // 按创建时间降序(最新的在前) + .last("LIMIT 1"); // 只查最近1条任务 + + SchBaseTask lastTask = iSchBaseTaskService.getOne(queryWrapper, false); // false:多条结果时不抛异常(保证只取1条) + + // 判断:若最近一条任务存在,且配置码是合托入库,则标记为二次入库,因为原托盘入库可能是满料,所以不做任务类型判断 + if (lastTask != null + &&("COMBINETARGETSTOREINTask".equals(lastTask.getConfig_code())||"COMBINESOURCESTOREINTask".equals(lastTask.getConfig_code()) )) { + isSecondStoreIn = true; + firstVehicleCode = sourceVehicleCode; + } + } + } + if (!isSecondStoreIn) { + List dictNotPointList = dictService.getDictByName("not_call_point_code"); + List notInPointList = new ArrayList<>(); + if(!CollectionUtils.isEmpty(dictNotPointList)){ + notInPointList = dictNotPointList.stream().map(Dict::getValue).collect(Collectors.toList()); + } + + + // 1. 查询托盘所在位置,判断是否都在货架上 + SchBasePoint sourcePoint = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", sourceVehicleCode) + .notIn(!CollectionUtils.isEmpty(dictNotPointList),"point_code",notInPointList) + .notIn("point_code", Arrays.asList("SD01", "SD02"))); + SchBasePoint targetPoint = iSchBasePointService.getOne(new QueryWrapper() + .eq("vehicle_code", targetVehicleCode) + .notIn(!CollectionUtils.isEmpty(dictNotPointList),"point_code",notInPointList) + .notIn("point_code", Arrays.asList("SD01", "SD02"))); + + if (null != sourcePoint || null != targetPoint) { + String vehicleCode = ""; + if(null != sourcePoint){ + vehicleCode= sourceVehicleCode; + } else { + vehicleCode = targetVehicleCode; + } + throw new BadRequestException("有托盘在货架上,请先叫到点位上再下发任务,或者不执行入库功能,托盘号"+vehicleCode); + } + } + + // 4. 检查点位状态:如果是第二次入库,检查点位是否为空 + if (isSecondStoreIn) { + + // 检查第一个托盘是否已被取走(即不在当前点位且没有进行中的任务) + JSONObject firstVehicleStatus = queryVehicleTaskStatus(firstVehicleCode); + boolean isFirstTakenAway = firstVehicleStatus.getBooleanValue("isTakenAway"); + + if(null == targetVehicle || null == sourceVehicle){ + throw new BadRequestException("传入的原始/目标托盘有误"); + } + + // 检查点位是否为空点位 + if (StrUtil.isNotBlank(point.getVehicle_code()) && "G01".equals(targetVehicle.getVehicle_type()) && "G01".equals(sourceVehicle.getVehicle_type())) { + throw new BadRequestException("当前点位不为空,无法进行第二次入库,请等待第一个托盘被拿走后再执行"); + } + + + if (!isFirstTakenAway && "G01".equals(targetVehicle.getVehicle_type()) && "G01".equals(sourceVehicle.getVehicle_type())) { + throw new BadRequestException("第一个托盘还未取走,请等待取走后再提交"); + } + } + + // 5. 检查托盘是否已有入库任务 + //todo + SchBaseTask existingTask = iSchBaseTaskService.getOne(new QueryWrapper() + .eq("vehicle_code", vehicle_code) + .in("config_code", Arrays.asList("COMBINESOURCESTOREINTask", "COMBINETARGETSTOREINTask")) + .lt("task_status", TaskStatus.FINISHED.getCode())); + + if (ObjectUtil.isNotEmpty(existingTask)) { + throw new BadRequestException("该托盘已有进行中的入库任务"); + } + + //查询源托盘的托盘上是否还剩余阻盘 + int sourceResidue = iSchBaseVehiclematerialgroupService.count(new LambdaUpdateWrapper() + .eq(SchBaseVehiclematerialgroup::getIs_delete, 0) + .eq(SchBaseVehiclematerialgroup::getVehicle_code, sourceVehicleCode)); + + //剩余的物料为0 走空载具入库。其他走有料入库 + String config_code = vehicle_code.equals(sourceVehicleCode) && sourceResidue == 0 ?"COMBINESOURCESTOREINTask" + :"COMBINETARGETSTOREINTask"; + + // 6. 生成入库任务 + // 创建任务参数 + JSONObject taskParams = new JSONObject(); + taskParams.put("device_code", point_code); + taskParams.put("config_code", config_code); + taskParams.put("create_mode", GeneralDefinition.PDA_CREATION); + taskParams.put("vehicle_code", vehicle_code); + taskParams.put("vehicle_type", vehicle.getVehicle_type()); + + JSONObject ext_data = new JSONObject(); + ext_data.put("source_vehicle_code", sourceVehicleCode); + ext_data.put("target_vehicle_code", targetVehicleCode); + ext_data.put("operator_id", operatorId); + ext_data.put("source_type", "03"); // 03表示来自手持终端合托操作 + taskParams.put("ext_data", ext_data); + + // 执行任务生成 + AbstractTask storeInTask = taskFactory.getTask(config_code); + if (ObjectUtil.isEmpty(storeInTask)) { + throw new BadRequestException("获取入库任务处理器失败"); + } + + storeInTask.apply(taskParams); + + // 6. 更新点位状态 + iSchBasePointService.update(Wrappers.lambdaUpdate(SchBasePoint.class) + .eq(SchBasePoint::getPoint_code, point_code) + .set(SchBasePoint::getIs_lock, true) + .set(SchBasePoint::getVehicle_code, vehicle_code) + .set(SchBasePoint::getPoint_status, GoodsEnum.IN_STOCK.getValue())); + + + // 7. 组装返回结果 + JSONObject result = new JSONObject(); + result.put("success", true); + result.put("message", "入库任务生成成功"); + result.put("vehicle_code", vehicle_code); + result.put("is_second_store_in", !(!isSecondStoreIn && ( "G01".equals(targetVehicle.getVehicle_type()) && "G01".equals(sourceVehicle.getVehicle_type())))); + result.put("point_code", point_code); + + log.info("入库任务生成成功:托盘编号[{}], 是否第二次入库: {}, 操作人员: {}, 点位: {}", + vehicle_code, isSecondStoreIn, operatorId, point_code); + + return result; + } catch (BadRequestException e) { + throw e; + } catch (Exception e) { + log.error("生成入库任务失败:托盘编号[{}]", vehicle_code, e); + throw new BadRequestException("生成入库任务失败:" + e.getMessage()); + } + + } + + @Override + public JSONObject queryVehicleTaskStatus(String vehicleCode) { + cn.hutool.core.lang.Assert.notBlank(vehicleCode, "托盘号不能为空"); + + try { + // 1. 检查托盘是否存在 + MdBaseVehicle vehicle = iMdBaseVehicleService.selectByVehicleCode(vehicleCode); + if (ObjectUtil.isEmpty(vehicle)) { + throw new BadRequestException("托盘不存在"); + } + + // 2. 查询托盘的最新任务 + SchBaseTask latestTask = iSchBaseTaskService.getOne( + new QueryWrapper() + .eq("vehicle_code", vehicleCode) + .eq("task_status", TaskStatus.EXECUTING.getCode()) + .orderByDesc("create_time") + .last("LIMIT 1") + ); + + // 3. 查询托盘所在位置 + SchBasePoint point = iSchBasePointService.getOne( + new QueryWrapper() + .eq("vehicle_code", vehicleCode) + .in("point_code",Arrays.asList("SD01", "SD02")) + ); + + boolean isTakenAway = false; + + if(ObjectUtil.isEmpty(point)){ + isTakenAway = true; + } + + // 5. 组装返回结果 + JSONObject result = new JSONObject(); + result.put("vehicleCode", vehicleCode); + result.put("isTakenAway", isTakenAway); + + // 6. 添加任务信息 + if (ObjectUtil.isNotEmpty(latestTask)) { + JSONObject taskInfo = new JSONObject(); + taskInfo.put("taskId", latestTask.getTask_id()); + taskInfo.put("taskType", latestTask.getTask_type()); + taskInfo.put("taskStatus", latestTask.getTask_status()); + taskInfo.put("createTime", latestTask.getCreate_time()); + + // 任务状态描述 + String taskStateDesc = TaskStatus.getNameByCode(latestTask.getTask_status()); + taskInfo.put("taskStateDesc", taskStateDesc); + + result.put("latestTask", taskInfo); + } + + // 7. 添加位置信息 + if (ObjectUtil.isNotEmpty(point)) { + JSONObject locationInfo = new JSONObject(); + locationInfo.put("pointCode", point.getPoint_code()); + locationInfo.put("pointName", point.getPoint_name()); + locationInfo.put("regionCode", point.getRegion_code()); + locationInfo.put("regionName", point.getRegion_name()); + locationInfo.put("pointStatus", point.getPoint_status()); + + result.put("location", locationInfo); + } + + log.info("查询托盘任务状态成功:托盘编号[{}], AGV是否已取走: {}", + vehicleCode, isTakenAway); + + return result; + } catch (BadRequestException e) { + throw e; + } catch (Exception e) { + log.error("查询托盘任务状态失败:托盘编号[{}]", vehicleCode, e); + throw new BadRequestException("查询托盘任务状态失败:" + e.getMessage()); + } + + } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/sorting/service/impl/SortingServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/sorting/service/impl/SortingServiceImpl.java index 74b26fe..a929a7b 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/sorting/service/impl/SortingServiceImpl.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/sorting/service/impl/SortingServiceImpl.java @@ -9,6 +9,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.gson.Gson; @@ -41,6 +42,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -48,6 +51,8 @@ import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * @author LENOVO @@ -253,12 +258,30 @@ public class SortingServiceImpl implements SortingService { .eq(SchBaseVehiclematerialgroup::getJob_name, jobName) .eq(SchBaseVehiclematerialgroup::getCreate_name, "Connector")); List connectors = new ArrayList<>(); - for (SchBaseVehiclematerialgroup schBaseVehiclematerialgroup : list) { - Gson gson = new Gson(); - ConnectorDto connectorDto = gson.fromJson(schBaseVehiclematerialgroup.getExtend(), ConnectorDto.class); - connectorDto.setDueDate(StrUtil.isNotEmpty(connectorDto.getDueDate()) ? connectorDto.getDueDate() : DateUtil.now()); - connectorDto.setNextOperation(StrUtil.isNotEmpty(connectorDto.getNextOperation()) ? connectorDto.getNextOperation() : RegionEnum.TRUBEND_SHELVES_3_1_1.getRegion_code()); - connectors.add(connectorDto); + if(!CollectionUtils.isEmpty(list)) { + Set vehicleCodeList = list.stream().filter(a -> !StringUtils.isEmpty(a.getVehicle_code())) + .map(SchBaseVehiclematerialgroup::getVehicle_code).collect(Collectors.toSet()); + + List schBasePointList = iSchBasePointService.list(new LambdaQueryWrapper() + .in(!CollectionUtils.isEmpty(vehicleCodeList),SchBasePoint::getVehicle_code, vehicleCodeList) + .eq(SchBasePoint::getIs_used, true) + ); + + Set existVehicleCode = schBasePointList.stream().map(SchBasePoint::getVehicle_code).collect(Collectors.toSet()); + + for (SchBaseVehiclematerialgroup schBaseVehiclematerialgroup : list) { + Gson gson = new Gson(); + ConnectorDto connectorDto = gson.fromJson(schBaseVehiclematerialgroup.getExtend(), ConnectorDto.class); + connectorDto.setDueDate(StrUtil.isNotEmpty(connectorDto.getDueDate()) ? connectorDto.getDueDate() : DateUtil.now()); + connectorDto.setNextOperation(StrUtil.isNotEmpty(connectorDto.getNextOperation()) ? connectorDto.getNextOperation() : RegionEnum.TRUBEND_SHELVES_3_1_1.getRegion_code()); + + if(!CollectionUtils.isEmpty(vehicleCodeList)) { + connectorDto.setIs_in_stock(existVehicleCode.contains(schBaseVehiclematerialgroup.getVehicle_code())); + } else { + connectorDto.setIs_in_stock(false); + } + connectors.add(connectorDto); + } } log.info("sorting查询组盘响应参数:{}", JSONObject.toJSONString(connectors)); return connectors; diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/core/GroupStatus.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/core/GroupStatus.java new file mode 100644 index 0000000..38f82eb --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/core/GroupStatus.java @@ -0,0 +1,71 @@ +package org.nl.wms.sch.group.core; + +public enum GroupStatus { + ON_SHELVES("0", "货架待命", "货架待命"), + TASKING("1", "任务中", "任务中"), + MANUAL_PROCESSING("2", "人工处理中", "人工处理中"), + ; + + + GroupStatus(String code, String name, String desc) { + this.code = code; + this.name = name; + this.desc = desc; + } + + private String code; + private String name; + private String desc; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + /** + * 根据code查找name + * @param code 状态码 + * @return 状态名称 + */ + public static String getNameByCode(String code) { + for (GroupStatus status : GroupStatus.values()) { + if (status.getCode().equals(code)) { + return status.getName(); + } + } + return null; + } + + /** + * 根据name查找code + * @param name 状态名称 + * @return 状态码 + */ + public static String getCodeByName(String name) { + for (GroupStatus status : GroupStatus.values()) { + if (status.getName().equals(name)) { + return status.getCode(); + } + } + return null; + } +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java index ef8a99b..891a7a9 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/SchBaseVehiclematerialgroup.java @@ -165,6 +165,10 @@ public class SchBaseVehiclematerialgroup implements Serializable { @ApiModelProperty(value = "托盘图片路径") private String vehicle_path; + //货架待命 1 、任务中 2 、人工处理中 3 + @ApiModelProperty(value = "状态") + private String status; + @TableField(exist = false) private String materialFile; diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/mapper/SchBaseVehiclematerialgroupMapper.xml b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/mapper/SchBaseVehiclematerialgroupMapper.xml index 897fa13..f9b638e 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/mapper/SchBaseVehiclematerialgroupMapper.xml +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/dao/mapper/SchBaseVehiclematerialgroupMapper.xml @@ -173,7 +173,9 @@ sbv.order_code, sbv.material_id, sbv.vehicle_path, - sbv.material_path + sbv.material_path, + sbv.material_qty, + sbv.due_date FROM sch_base_vehiclematerialgroup sbv WHERE sbv.vehicle_code IN diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java index d0834ea..155b708 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/group/service/impl/SchBaseVehiclematerialgroupServiceImpl.java @@ -223,7 +223,33 @@ public class SchBaseVehiclematerialgroupServiceImpl extends ServiceImpl schBaseVehiclematerialgroups = vehiclematerialgroupMapper.selectList(Wrappers.lambdaQuery(SchBaseVehiclematerialgroup.class) .eq(SchBaseVehiclematerialgroup::getVehicle_code, entity.getString("vehicle_code")) .ne(SchBaseVehiclematerialgroup::getGroup_id, entity.getString("group_id"))); + + // 根据vehicle_code、region_code、job_name、order_code、material_id进行合并 if (ObjectUtil.isNotEmpty(schBaseVehiclematerialgroups)) { + // 使用Map存储合并后的结果,key是合并条件的组合 + Map mergedMap = new HashMap<>(); + + for (SchBaseVehiclematerialgroup group : schBaseVehiclematerialgroups) { + // 创建合并条件的key + String key = group.getVehicle_code() + ":" + + group.getRegion_code() + ":" + + group.getJob_name() + ":" + + group.getOrder_code() + ":" + + group.getMaterial_id(); + + if (mergedMap.containsKey(key)) { + // 如果已存在,累加material_qty + SchBaseVehiclematerialgroup existingGroup = mergedMap.get(key); + existingGroup.setMaterial_qty(existingGroup.getMaterial_qty() + group.getMaterial_qty()); + } else { + // 如果不存在,添加到Map中 + mergedMap.put(key, group); + } + } + + // 将Map转换为List + schBaseVehiclematerialgroups = new ArrayList<>(mergedMap.values()); + schBaseVehiclematerialgroups.forEach(item -> { if (StrUtil.isEmpty(item.getRegion_code())) { item.setRegion_code("未知"); diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/ISchBasePointService.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/ISchBasePointService.java index 600bb02..b9c8b21 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/ISchBasePointService.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/ISchBasePointService.java @@ -127,7 +127,7 @@ public interface ISchBasePointService extends IService { * @param region_code * @return */ - List getStructList(String region_code, String vehicle_type); + List getStructList(String pointCode, String vehicle_type, String searchKey); /** diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.java index 63218e5..8435cfc 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.java @@ -27,7 +27,12 @@ public interface SchBasePointMapper extends BaseMapper { List getStructList(@Param("region_code") String region_code, @Param("due_date")String due_date); - List getStructList1(@Param("region_code") String region_code,@Param("due_date")String due_date); + List getStructListNoLock(@Param("region_code") String region_code, @Param("due_date")String due_date, @Param("searchKey") String searchKey); + + List getStructList1NoLock(@Param("region_code") String region_code, @Param("due_date")String due_date, @Param("searchKey") String searchKey); + + + List getStructList1(@Param("region_code") String region_code, @Param("due_date")String due_date); List selectByRegionCode(@Param("region_code") String region_code); diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.xml b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.xml index 3ea6a2e..8187ce6 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.xml +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch/point/service/dao/mapper/SchBasePointMapper.xml @@ -54,6 +54,81 @@ AND sch_base_vehiclematerialgroup.due_date IS NULL + +