From 7d31f04772e404af7603e768444c536ad9b7acf5 Mon Sep 17 00:00:00 2001 From: "HUOJIN\\92525" Date: Fri, 19 Dec 2025 18:06:14 +0800 Subject: [PATCH] no message --- .../org/jeecg/common/aspect/DictAspect.java | 120 +++--- .../service/impl/AgvTaskServiceImpl.java | 2 + .../base/controller/ItemController.java | 1 + .../base/controller/PointController.java | 31 +- .../base/controller/StockController.java | 1 + .../org/cpte/modules/base/entity/Point.java | 8 +- .../modules/base/mapper/ItemKeyMapper.java | 2 - .../modules/base/mapper/xml/ItemKeyMapper.xml | 8 - .../modules/base/service/IItemKeyService.java | 21 +- .../base/service/impl/ItemKeyServiceImpl.java | 19 + .../base/service/impl/ItemServiceImpl.java | 2 + .../base/service/impl/StockServiceImpl.java | 2 + .../modules/constant/enums/AsnStatusEnum.java | 2 + .../constant/enums/BusinessTypeEnum.java | 4 + .../constant/enums/InventoryStatusEnum.java | 6 +- .../impl/IConveyorLineServiceImpl.java | 5 +- .../{ => processor}/ScanTrayProcessor.java | 32 +- .../controller/InventoryController.java | 252 +++++++------ .../modules/inventory/entity/Inventory.java | 51 ++- .../inventory/mapper/InventoryMapper.java | 17 + .../inventory/mapper/xml/InventoryMapper.xml | 8 + .../inventory/service/IInventoryService.java | 7 + .../service/impl/InventoryServiceImpl.java | 11 +- .../service/IInventoryLogService.java | 4 +- .../service/impl/InventoryLogServiceImpl.java | 13 +- .../modules/receive/entity/ReceiveRecord.java | 6 + .../receive/mapper/AsnDetailMapper.java | 2 - .../receive/mapper/ReceiveRecordMapper.java | 1 + .../modules/receive/service/IAsnService.java | 7 - .../service/impl/AsnDetailServiceImpl.java | 1 + .../receive/service/impl/AsnServiceImpl.java | 143 +------- .../processor/ReceiveBackProcessor.java | 177 +++++++++ .../{ => processor}/ReceiveProcessor.java | 115 +++--- .../saiWms/controller/SaiWmsController.java | 9 + .../saiWms/request/CallAgvRequest.java | 19 + .../modules/saiWms/service/ISMOMService.java | 6 + .../saiWms/service/impl/ISMOMServiceImpl.java | 37 +- .../service/processor/CallAgvProcessor.java | 97 +++++ .../{ => processor}/InBoundTaskProcessor.java | 2 +- .../OutBoundTaskProcessor.java | 2 +- .../{ => processor}/SyncStockProcessor.java | 2 +- .../org/cpte/modules/saiWms/vo/CallData.java | 12 + .../shipping/controller/PickController.java | 3 + .../cpte/modules/shipping/entity/Task.java | 1 + .../shipping/service/IPickDetailService.java | 8 + .../shipping/service/IPickService.java | 13 +- .../shipping/service/ITaskService.java | 8 +- .../service/impl/PickDetailServiceImpl.java | 21 +- .../service/impl/PickServiceImpl.java | 265 +------------- .../service/impl/TaskServiceImpl.java | 107 ++---- .../{ => processor}/AllocateProcessor.java | 206 ++++++++--- .../CancelAllocateProcessor.java | 4 +- .../service/processor/PickBackProcessor.java | 197 ++++++++++ .../service/processor/PickProcessor.java | 345 ++++++++++++++++++ .../cpte/modules/shipping/vo/PickData.java | 20 + .../service/impl/ITesAgvServiceImpl.java | 13 +- .../org/cpte/modules/utils/BatchUtil.java | 55 ++- .../java/org/cpte/modules/utils/test.java | 4 + 58 files changed, 1657 insertions(+), 880 deletions(-) rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/{ => processor}/ScanTrayProcessor.java (95%) create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/{ => processor}/ReceiveProcessor.java (62%) create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/CallAgvRequest.java create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/CallAgvProcessor.java rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/{ => processor}/InBoundTaskProcessor.java (99%) rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/{ => processor}/OutBoundTaskProcessor.java (99%) rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/{ => processor}/SyncStockProcessor.java (98%) create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/vo/CallData.java rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/{ => processor}/AllocateProcessor.java (78%) rename cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/{ => processor}/CancelAllocateProcessor.java (99%) create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickProcessor.java create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/PickData.java diff --git a/cpte-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java b/cpte-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java index 7076c8e..f08cb00 100644 --- a/cpte-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java +++ b/cpte-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java @@ -49,25 +49,35 @@ public class DictAspect { private static final String JAVA_UTIL_DATE = "java.util.Date"; + /** + * 定义切点Pointcut + */ +/* @Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " + + "@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " + + "&& execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..)) || execution(public * org.cpte..*.*Controller.*(..))") + public void excudeService() { + }*/ + /** * 定义切点Pointcut */ @Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " + "@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " + - "&& execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..))") + "&& (execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..)) || " + + "execution(public org.jeecg.common.api.vo.Result org.cpte..*.*(..)))") public void excudeService() { } @Around("excudeService()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { - long time1 = System.currentTimeMillis(); + long time1=System.currentTimeMillis(); Object result = pjp.proceed(); - long time2 = System.currentTimeMillis(); - log.debug("获取JSON数据 耗时:" + (time2 - time1) + "ms"); - long start = System.currentTimeMillis(); - result = this.parseDictText(result); - long end = System.currentTimeMillis(); - log.debug("注入字典到JSON数据 耗时" + (end - start) + "ms"); + long time2=System.currentTimeMillis(); + log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms"); + long start=System.currentTimeMillis(); + result=this.parseDictText(result); + long end=System.currentTimeMillis(); + log.debug("注入字典到JSON数据 耗时"+(end-start)+"ms"); return result; } @@ -77,21 +87,20 @@ public class DictAspect { * 示例为SysUser 字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text,已字段名称加_dictText形式返回到前端 * 例输入当前返回值的就会多出一个sex_dictText字段 * { - * sex:1, - * sex_dictText:"男" + * sex:1, + * sex_dictText:"男" * } * 前端直接取值sext_dictText在table里面无需再进行前端的字典转换了 - * customRender:function (text) { - * if(text==1){ - * return "男"; - * }else if(text==2){ - * return "女"; - * }else{ - * return text; - * } - * } - * 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用 - * + * customRender:function (text) { + * if(text==1){ + * return "男"; + * }else if(text==2){ + * return "女"; + * }else{ + * return text; + * } + * } + * 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用 * @param result */ private Object parseDictText(Object result) { @@ -105,24 +114,24 @@ public class DictAspect { // 字典数据列表, key = 字典code,value=数据列表 Map> dataListMap = new HashMap<>(5); //取出结果集 - List records = ((IPage) ((Result) result).getResult()).getRecords(); + List records=((IPage) ((Result) result).getResult()).getRecords(); //update-begin--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回----- - Boolean hasDict = checkHasDict(records); - if (!hasDict) { + Boolean hasDict= checkHasDict(records); + if(!hasDict){ return result; } - log.debug(" __ 进入字典翻译切面 DictAspect —— "); + log.debug(" __ 进入字典翻译切面 DictAspect —— " ); //update-end--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回----- for (Object record : records) { - String json = "{}"; + String json="{}"; try { //update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错----- //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat - json = objectMapper.writeValueAsString(record); + json = objectMapper.writeValueAsString(record); //update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错----- } catch (JsonProcessingException e) { - log.error("json解析失败" + e.getMessage(), e); + log.error("json解析失败"+e.getMessage(),e); } //update-begin--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 ----- JSONObject item = JSONObject.parseObject(json, Feature.OrderedField); @@ -136,7 +145,7 @@ public class DictAspect { if (oConvertUtils.isEmpty(value)) { continue; } - //update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ + //update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ if (field.getAnnotation(Dict.class) != null) { if (!dictFieldList.contains(field)) { dictFieldList.add(field); @@ -160,8 +169,8 @@ public class DictAspect { //date类型默认转换string格式化日期 //update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错----- //if (JAVA_UTIL_DATE.equals(field.getType().getName())&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){ - //SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - // item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName())))); + //SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName())))); //} //update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错----- } @@ -191,7 +200,7 @@ public class DictAspect { String value = record.getString(field.getName()); if (oConvertUtils.isNotEmpty(value)) { List dictModels = translText.get(fieldDictCode); - if (dictModels == null || dictModels.size() == 0) { + if(dictModels==null || dictModels.size()==0){ continue; } @@ -230,7 +239,6 @@ public class DictAspect { * 一次性把所有的字典都翻译了 * 1. 所有的普通数据字典的所有数据只执行一次SQL * 2. 表字典相同的所有数据只执行一次SQL - * * @param dataListMap * @return */ @@ -298,13 +306,13 @@ public class DictAspect { log.debug("translateDictFromTableByKeys.dictCode:" + dictCode); log.debug("translateDictFromTableByKeys.values:" + values); //update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------ - + //update-begin---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串--- - if (null == dataSource) { + if(null == dataSource){ dataSource = ""; } //update-end---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串--- - + List texts = commonApi.translateDictFromTableByKeys(table, text, code, values, dataSource); //update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------ log.debug("translateDictFromTableByKeys.result:" + texts); @@ -382,8 +390,7 @@ public class DictAspect { } /** - * 翻译字典文本 - * + * 翻译字典文本 * @param code * @param text * @param table @@ -392,39 +399,39 @@ public class DictAspect { */ @Deprecated private String translateDictValue(String code, String text, String table, String key) { - if (oConvertUtils.isEmpty(key)) { - return null; - } - StringBuffer textValue = new StringBuffer(); + if(oConvertUtils.isEmpty(key)) { + return null; + } + StringBuffer textValue=new StringBuffer(); String[] keys = key.split(","); for (String k : keys) { String tmpValue = null; - log.debug(" 字典 key : " + k); + log.debug(" 字典 key : "+ k); if (k.trim().length() == 0) { continue; //跳过循环 } //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题----- - if (!StringUtils.isEmpty(table)) { - log.debug("--DictAspect------dicTable=" + table + " ,dicText= " + text + " ,dicCode=" + code); - String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]", table, text, code, k.trim()); - if (redisTemplate.hasKey(keyString)) { + if (!StringUtils.isEmpty(table)){ + log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code); + String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim()); + if (redisTemplate.hasKey(keyString)){ try { tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); } catch (Exception e) { log.warn(e.getMessage()); } - } else { - tmpValue = commonApi.translateDictFromTable(table, text, code, k.trim()); + }else { + tmpValue= commonApi.translateDictFromTable(table,text,code,k.trim()); } - } else { - String keyString = String.format("sys:cache:dict::%s:%s", code, k.trim()); - if (redisTemplate.hasKey(keyString)) { + }else { + String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim()); + if (redisTemplate.hasKey(keyString)){ try { tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); } catch (Exception e) { - log.warn(e.getMessage()); + log.warn(e.getMessage()); } - } else { + }else { tmpValue = commonApi.translateDict(code, k.trim()); } } @@ -443,12 +450,11 @@ public class DictAspect { /** * 检测返回结果集中是否包含Dict注解 - * * @param records * @return */ - private Boolean checkHasDict(List records) { - if (oConvertUtils.isNotEmpty(records) && records.size() > 0) { + private Boolean checkHasDict(List records){ + if(oConvertUtils.isNotEmpty(records) && records.size()>0){ for (Field field : oConvertUtils.getAllFields(records.get(0))) { if (oConvertUtils.isNotEmpty(field.getAnnotation(Dict.class))) { return true; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java index 4e3ea52..261fb03 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/agvTask/service/impl/AgvTaskServiceImpl.java @@ -1,6 +1,7 @@ package org.cpte.modules.agvTask.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.apache.shiro.SecurityUtils; import org.cpte.modules.agvTask.entity.AgvTask; import org.cpte.modules.agvTask.mapper.AgvTaskMapper; @@ -73,6 +74,7 @@ public class AgvTaskServiceImpl extends ServiceImpl impl priority = 3; } return AgvTask.builder() + .id(IdWorker.getId()) .businessDetailId(businessDetailId) .carrierCode(carrierCode) .type(type) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/ItemController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/ItemController.java index c81ad8d..de49b6c 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/ItemController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/ItemController.java @@ -81,6 +81,7 @@ public class ItemController extends JeecgController { if (StringUtils.isNotBlank(keyword)) { queryWrapper.and(wrapper -> wrapper.likeRight("item_code", keyword).or().likeRight("item_name", keyword)); } + queryWrapper.orderByAsc("item_code"); Page page = new Page(pageNo, pageSize); IPage pageList = itemService.page(page, queryWrapper); return Result.OK(pageList); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/PointController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/PointController.java index 0d1bc4c..3a2b4f9 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/PointController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/PointController.java @@ -12,11 +12,11 @@ import java.net.URLDecoder; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; +import org.cpte.modules.base.entity.Area; +import org.cpte.modules.base.service.IAreaService; import org.jeecg.common.api.vo.Result; -import org.jeecg.common.aspect.annotation.AutoDict; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryRuleEnum; -import org.jeecg.common.util.oConvertUtils; import org.cpte.modules.base.entity.Point; import org.cpte.modules.base.service.IPointService; @@ -25,18 +25,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; -import org.jeecgframework.poi.excel.ExcelImportUtil; -import org.jeecgframework.poi.excel.def.NormalExcelConstants; -import org.jeecgframework.poi.excel.entity.ExportParams; -import org.jeecgframework.poi.excel.entity.ImportParams; -import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.jeecg.common.system.base.controller.JeecgController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; + import org.springframework.web.servlet.ModelAndView; -import com.alibaba.fastjson.JSON; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import org.jeecg.common.aspect.annotation.AutoLog; @@ -56,6 +49,9 @@ public class PointController extends JeecgController { @Autowired private IPointService pointService; + @Autowired + private IAreaService areaService; + /** * 分页列表查询 * @@ -71,17 +67,18 @@ public class PointController extends JeecgController { public Result> queryPageList(Point point, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, - @RequestParam(name = "keyword", required = false) String keyword, + @RequestParam(name = "keyword", required = false) String keyword, HttpServletRequest req) { - // 自定义查询规则 + // 自定义查询规则 Map customeRuleMap = new HashMap<>(); customeRuleMap.put("pointCode", QueryRuleEnum.RIGHT_LIKE); QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(point, req.getParameterMap(), customeRuleMap); - // 如果提供了 keyword,则同时对 pointCode 模糊搜索 - if (StringUtils.isNotBlank(keyword)) { - queryWrapper.and(wrapper -> wrapper.likeRight("point_code", keyword)); - } + // 如果提供了 keyword,则同时对 pointCode 模糊搜索 + if (StringUtils.isNotBlank(keyword)) { + queryWrapper.and(wrapper -> wrapper.likeRight("point_code", keyword)); + } + queryWrapper.orderByAsc("point_code"); Page page = new Page(pageNo, pageSize); IPage pageList = pointService.page(page, queryWrapper); return Result.OK(pageList); @@ -162,6 +159,8 @@ public class PointController extends JeecgController { if (point == null) { return Result.error("未找到对应数据"); } + Area area = areaService.getById(point.getAreaId()); + point.setAreaId_dictText(area.getAreaName()); return Result.OK(point); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/StockController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/StockController.java index 5745fe2..d29012a 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/StockController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/controller/StockController.java @@ -80,6 +80,7 @@ public class StockController extends JeecgController { if (StringUtils.isNotBlank(keyword)) { queryWrapper.and(wrapper -> wrapper.likeRight("stock_code", keyword)); } + queryWrapper.orderByAsc("stock_code"); Page page = new Page(pageNo, pageSize); IPage pageList = stockService.page(page, queryWrapper); return Result.OK(pageList); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java index 5f1086f..976b94f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java @@ -2,10 +2,7 @@ package org.cpte.modules.base.entity; import java.io.Serializable; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.Data; @@ -47,6 +44,9 @@ public class Point implements Serializable { @Dict(dictTable = "base_area", dicCode = "id", dicText = "area_name") @JsonSerialize(using = ToStringSerializer.class) private java.lang.Long areaId; + + @TableField(exist = false) + private String areaId_dictText; /** * 库位编码 */ diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/ItemKeyMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/ItemKeyMapper.java index 9ed70bd..f7d1a42 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/ItemKeyMapper.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/ItemKeyMapper.java @@ -30,8 +30,6 @@ public interface ItemKeyMapper extends BaseMapper { @Param("project") String project, @Param("taskNo") String taskNo, @Param("propC1") String propC1, @Param("propC3") String propC3); - List queryItemKeyByIds(@Param("itemKeyIds") List itemKeyIds); - List queryItemKeys(@Param("itemIds") List itemIds, @Param("whCodeList") List whCodeList, @Param("projectList") List projectList, @Param("taskNoList") List taskNoList, @Param("propC1List") List propC1List, @Param("propC3List") List propC3List); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/xml/ItemKeyMapper.xml b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/xml/ItemKeyMapper.xml index e85c331..f2d826d 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/xml/ItemKeyMapper.xml +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/xml/ItemKeyMapper.xml @@ -46,14 +46,6 @@ - - + + + DELETE FROM data_inventory + WHERE stock_id IN + + #{stockId} + + \ No newline at end of file diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java index f92a3f7..03bfbd1 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java @@ -46,4 +46,11 @@ public interface IInventoryService extends IService { * @return Map */ Map queryByInventoryIdsToMap(List inventoryIds); + + /** + * 根据容器ID删除库存 + * + * @param stockIds 容器ID + */ + void deleteByStockIds(List stockIds); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java index 74e1546..c5b14e9 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java @@ -33,8 +33,8 @@ public class InventoryServiceImpl extends ServiceImpl stockIds) { + this.baseMapper.deleteByStockIds(stockIds); + } + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/IInventoryLogService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/IInventoryLogService.java index a1a2474..a9e8045 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/IInventoryLogService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/IInventoryLogService.java @@ -46,7 +46,6 @@ public interface IInventoryLogService extends IService { void addInboundInventoryLog(Inventory inventory, Long srcPointId, BigDecimal changeQty, String businessNo, Long businessDetailId, String description); - /** * 添加出库库存日志 * @@ -88,12 +87,13 @@ public interface IInventoryLogService extends IService { * 添加拣货库存日志 * * @param inventory 库存 + * @param dstPointId 目标库位 * @param changeQty 变动数量 * @param businessNo 业务单号 * @param businessDetailId 业务明细ID * @param description 描述 */ - void addPickInventoryLog(Inventory inventory, BigDecimal changeQty, String businessNo, Long businessDetailId, String description); + void addPickInventoryLog(Inventory inventory, Long dstPointId, BigDecimal changeQty, String businessNo, Long businessDetailId, String description); /** * 添加退拣库存日志-拣货后取消,库存回退 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/impl/InventoryLogServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/impl/InventoryLogServiceImpl.java index 6f40725..f4d2244 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/impl/InventoryLogServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventoryLog/service/impl/InventoryLogServiceImpl.java @@ -93,23 +93,25 @@ public class InventoryLogServiceImpl extends ServiceImpl { @Select("select * from data_asn_detail where stock_id = #{stockId} and status = #{status} ") List queryByStockCode(@Param("stockId") Long stockId, @Param("status") Integer status); - @Select("select MAX(line_no) from data_asn_detail where asn_id = #{asnId} ") - Integer queryMaxLineNoByAsnId(@Param("asnId") Long asnId); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/ReceiveRecordMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/ReceiveRecordMapper.java index 843b63c..689234d 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/ReceiveRecordMapper.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/ReceiveRecordMapper.java @@ -4,4 +4,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.cpte.modules.receive.entity.ReceiveRecord; public interface ReceiveRecordMapper extends BaseMapper { + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java index 48d66a7..c40f044 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/IAsnService.java @@ -82,11 +82,4 @@ public interface IAsnService extends IService { */ void receiveAsn(Long asnId, String pointCode); - /** - * 入库任务回传 - * - * @param asn 入库单 - * @param stock 容器 - */ - void receiveCallback(Asn asn, Stock stock); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnDetailServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnDetailServiceImpl.java index bb4ae87..7a447db 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnDetailServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnDetailServiceImpl.java @@ -81,6 +81,7 @@ public class AsnDetailServiceImpl extends ServiceImpl implements IAsnS try { lockValue = redissonLock.tryLock(lockKey, 10); if (StringUtils.isEmpty(lockValue)) { - throw new RuntimeException("入库处理中,请稍后重试"); + throw new RuntimeException("入库单创建中,请稍后重试"); } processorSaveMain(asn, asnDetailList); + } catch (Exception e) { + log.error("入库单创建异常", e); + throw e; } finally { if (StringUtils.isNotEmpty(lockValue)) { redissonLock.unlock(lockKey, lockValue); @@ -230,7 +211,6 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS } - @Override public void receiveAsn(Long asnId, String pointCode) { String lockKey = "asn:" + asnId; @@ -242,121 +222,12 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS } receiveProcessor.receiveAsn(asnId, pointCode); } catch (Exception e) { - throw new RuntimeException(e); + log.error("收货处理异常", e); + throw e; } finally { if (StringUtils.isNotEmpty(lockValue)) { redissonLock.unlock(lockKey, lockValue); } } } - - - /** - * 入库任务回传JSON - */ - private String receiveCallbackJson(Asn asn, Stock stock, String ticket) { - - SMOMRequest.Task task = new SMOMRequest.Task(); - task.setNo(asn.getNo()); - task.setOrderNo(asn.getThirdOrderNo()); - task.setState(5); - task.setLpn(stock.getStockCode()); - task.setErpKey(asn.getNo()); - task.setCode(""); - task.setName(""); - task.setInfkey(asn.getNo()); - task.setIsDelete(false); - task.setLastUpdateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); - - SMOMRequest.ParameterValue1 parameterValue1 = new SMOMRequest.ParameterValue1(); - parameterValue1.setValue(List.of(task)); - - SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); - parameterValue2.setValue(1); - - SMOMRequest.Context context = new SMOMRequest.Context(); - context.setInvOrgId(1); - context.setTicket(ticket); - - SMOMRequest saiWmsRequest = new SMOMRequest(); - saiWmsRequest.setApiType("SmomWebApiController"); - saiWmsRequest.setParameters(List.of(parameterValue1, parameterValue2)); - saiWmsRequest.setMethod("AutomatedWarehouseTasks"); - saiWmsRequest.setContext(context); - - return JSON.toJSONString(saiWmsRequest); - } - - @Override - public void receiveCallback(Asn asn, Stock stock) { - - // 检查接口开关, 未开启则返回 - if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) { - updateAsnDetailResponse(asn, GeneralConstant.SMOM_FAIL_CODE, "接口未开启"); - return; - } - - if (PickStatusEnum.CLOSED.getValue().equals(asn.getStatus())) { - return; - } - try { - Map authInfo = swmsLoginUtil.Login(); - if (authInfo == null || authInfo.isEmpty()) { - throw new RuntimeException("登录认证信息为空"); - } - String ticket = authInfo.get("Ticket"); - String authorization = authInfo.get("authorization"); - String json = receiveCallbackJson(asn, stock, ticket); - String url = openApiMapper.getRequestUrl(GeneralConstant.INBOUND_CALLBACK).getOriginUrl(); - JSONObject jsonObject = swmsLoginUtil.sendSMOMResponse(json, url, authorization); - String code = validateResponse(jsonObject); - updateAsnDetailResponse(asn, code, jsonObject.toJSONString()); - } catch (Exception e) { - updateAsnDetailResponse(asn, GeneralConstant.SMOM_FAIL_CODE, e.getMessage()); - } - } - - /** - * 验证响应数据 - * - * @param jsonObject 响应数据 - * @return 状态码 - */ - private String validateResponse(JSONObject jsonObject) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data == null) { - throw new RuntimeException("数据格式错误:缺少data字段"); - } - JSONObject Result = data.getJSONObject("Result"); - if (Result == null) { - throw new RuntimeException("数据格式错误:缺少Result字段"); - } - JSONArray jsonArray = Result.getJSONArray("ErpErrorDatas"); - return jsonArray.isEmpty() ? GeneralConstant.SMOM_SUCCESS_CODE : GeneralConstant.SMOM_FAIL_CODE; - } - - /** - * 更新任务状态 - * - * @param asn 入库单 - * @param code 状态码 - * @param message 信息 - */ - private void updateAsnDetailResponse(Asn asn, String code, String message) { - List updateToAsnDetail = new ArrayList<>(); - if (GeneralConstant.SMOM_SUCCESS_CODE.equals(code)) { - asn.setStatus(AsnStatusEnum.CLOSED.getValue()); - List asnDetails = asnDetailMapper.selectByMainId(asn.getId()); - for (AsnDetail asnDetail : asnDetails) { - asnDetail.setStatus(AsnStatusEnum.CLOSED.getValue()); - updateToAsnDetail.add(asnDetail); - } - } - asn.setResMessage(message); - asn.setResTime(new Date()); - this.baseMapper.updateById(asn); - if (CollectionUtils.isNotEmpty(updateToAsnDetail)) { - asnDetailMapper.updateById(updateToAsnDetail); - } - } } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java new file mode 100644 index 0000000..064d5c4 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java @@ -0,0 +1,177 @@ +package org.cpte.modules.receive.service.processor; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.constant.GeneralConstant; +import org.cpte.modules.constant.enums.AsnStatusEnum; +import org.cpte.modules.constant.enums.InventoryStatusEnum; +import org.cpte.modules.constant.enums.PickStatusEnum; +import org.cpte.modules.inventory.entity.Inventory; +import org.cpte.modules.inventory.mapper.InventoryMapper; +import org.cpte.modules.receive.entity.Asn; +import org.cpte.modules.receive.entity.AsnDetail; +import org.cpte.modules.receive.mapper.AsnDetailMapper; +import org.cpte.modules.receive.mapper.AsnMapper; +import org.cpte.modules.receive.mapper.ReceiveRecordMapper; +import org.cpte.modules.saiWms.request.SMOMRequest; +import org.cpte.modules.utils.SwmsLoginUtil; +import org.jeecg.modules.openapi.mapper.OpenApiMapper; +import org.jeecg.modules.system.mapper.SysDictMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 收货回传处理 + */ +@Service +@Slf4j +public class ReceiveBackProcessor { + + @Autowired + private AsnMapper asnMapper; + + @Autowired + private AsnDetailMapper asnDetailMapper; + + @Autowired + private InventoryMapper inventoryMapper; + + @Autowired + private OpenApiMapper openApiMapper; + + @Autowired + private SysDictMapper sysDictMapper; + + @Autowired + private SwmsLoginUtil swmsLoginUtil; + + /** + * 入库任务回传JSON + */ + private String receiveBackJson(Asn asn, Stock stock, String ticket) { + + SMOMRequest.Task task = new SMOMRequest.Task(); + task.setNo(asn.getNo()); + task.setOrderNo(asn.getThirdOrderNo()); + task.setState(5); + task.setLpn(stock.getStockCode()); + task.setErpKey(asn.getNo()); + task.setCode(""); + task.setName(""); + task.setInfkey(asn.getNo()); + task.setIsDelete(false); + task.setLastUpdateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + + SMOMRequest.ParameterValue1 parameterValue1 = new SMOMRequest.ParameterValue1(); + parameterValue1.setValue(List.of(task)); + + SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); + parameterValue2.setValue(1); + + SMOMRequest.Context context = new SMOMRequest.Context(); + context.setInvOrgId(1); + context.setTicket(ticket); + + SMOMRequest saiWmsRequest = new SMOMRequest(); + saiWmsRequest.setApiType("SmomWebApiController"); + saiWmsRequest.setParameters(List.of(parameterValue1, parameterValue2)); + saiWmsRequest.setMethod("AutomatedWarehouseTasks"); + saiWmsRequest.setContext(context); + + return JSON.toJSONString(saiWmsRequest); + } + + public void receiveBack(Asn asn, Stock stock) { + // 检查接口开关, 未开启则返回 + if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) { + updateAsnDetailResponse(asn, stock, GeneralConstant.SMOM_FAIL_CODE, "接口未开启"); + return; + } + + if (PickStatusEnum.CLOSED.getValue().equals(asn.getStatus())) { + return; + } + try { + Map authInfo = swmsLoginUtil.Login(); + if (authInfo == null || authInfo.isEmpty()) { + throw new RuntimeException("登录认证信息为空"); + } + String ticket = authInfo.get("Ticket"); + String authorization = authInfo.get("authorization"); + String json = receiveBackJson(asn, stock, ticket); + String url = openApiMapper.getRequestUrl(GeneralConstant.INBOUND_CALLBACK).getOriginUrl(); + JSONObject jsonObject = swmsLoginUtil.sendSMOMResponse(json, url, authorization); + String code = validateResponse(jsonObject); + updateAsnDetailResponse(asn, stock, code, jsonObject.toJSONString()); + } catch (Exception e) { + updateAsnDetailResponse(asn, stock, GeneralConstant.SMOM_FAIL_CODE, e.getMessage()); + } + } + + /** + * 更新任务状态 + * + * @param asn 入库单 + * @param code 状态码 + * @param message 信息 + */ + private void updateAsnDetailResponse(Asn asn, Stock stock, String code, String message) { + List updateToAsnDetail = new ArrayList<>(); + List updateToInventory = new ArrayList<>(); + if (GeneralConstant.SMOM_SUCCESS_CODE.equals(code)) { + asn.setStatus(AsnStatusEnum.CLOSED.getValue()); + List asnDetails = asnDetailMapper.selectByMainId(asn.getId()); + for (AsnDetail asnDetail : asnDetails) { + asnDetail.setStatus(AsnStatusEnum.CLOSED.getValue()); + updateToAsnDetail.add(asnDetail); + } + + //更新库存状态 + List inventories = inventoryMapper.queryInventoryByStockId(stock.getId()); + for (Inventory inventory : inventories) { + inventory.setStatus(InventoryStatusEnum.AVAILABLE.getValue()); + updateToInventory.add(inventory); + } + + } + asn.setResMessage(message); + asn.setResTime(new Date()); + asnMapper.updateById(asn); + if (CollectionUtils.isNotEmpty(updateToAsnDetail)) { + asnDetailMapper.updateById(updateToAsnDetail); + } + if (CollectionUtils.isNotEmpty(updateToInventory)) { + inventoryMapper.updateById(updateToInventory); + } + } + + /** + * 验证响应数据 + * + * @param jsonObject 响应数据 + * @return 状态码 + */ + private String validateResponse(JSONObject jsonObject) { + JSONObject data = jsonObject.getJSONObject("data"); + if (data == null) { + throw new RuntimeException("数据格式错误:缺少data字段"); + } + JSONObject Result = data.getJSONObject("Result"); + if (Result == null) { + throw new RuntimeException("数据格式错误:缺少Result字段"); + } + JSONArray jsonArray = Result.getJSONArray("ErpErrorDatas"); + return jsonArray.isEmpty() ? GeneralConstant.SMOM_SUCCESS_CODE : GeneralConstant.SMOM_FAIL_CODE; + } + +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/ReceiveProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveProcessor.java similarity index 62% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/ReceiveProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveProcessor.java index 2c15325..d3e1e9e 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/ReceiveProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveProcessor.java @@ -1,4 +1,4 @@ -package org.cpte.modules.receive.service; +package org.cpte.modules.receive.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -12,7 +12,6 @@ import org.cpte.modules.base.service.IPointService; import org.cpte.modules.base.service.IStockService; import org.cpte.modules.constant.enums.AsnStatusEnum; import org.cpte.modules.inventory.entity.Inventory; -import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.inventory.service.IInventoryService; import org.cpte.modules.inventoryLog.entity.InventoryLog; import org.cpte.modules.inventoryLog.service.IInventoryLogService; @@ -21,9 +20,8 @@ import org.cpte.modules.receive.entity.AsnDetail; import org.cpte.modules.receive.entity.ReceiveRecord; import org.cpte.modules.receive.mapper.AsnDetailMapper; import org.cpte.modules.receive.mapper.AsnMapper; +import org.cpte.modules.receive.service.IAsnDetailService; import org.cpte.modules.receive.vo.ReceiveData; -import org.cpte.modules.shipping.entity.Pick; -import org.cpte.modules.shipping.vo.AllocationData; import org.cpte.modules.utils.BatchUtil; import org.cpte.modules.utils.BigDecimalUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -32,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -54,9 +53,6 @@ public class ReceiveProcessor { @Autowired private AsnDetailMapper asnDetailMapper; - @Autowired - private InventoryMapper inventoryMapper; - @Autowired private IStockService stockService; @@ -75,6 +71,9 @@ public class ReceiveProcessor { @Autowired private IInventoryLogService inventoryLogService; + @Autowired + private ReceiveBackProcessor receiveBackProcessor; + @Autowired private BatchUtil batchUtil; @@ -88,20 +87,17 @@ public class ReceiveProcessor { // 1.数据准备 ReceiveData data = prepareReceiveData(asnId, dstPointCode); - //2.验证托盘 - // validateStock(data.getStock()); - //3.创建数据结构 List updateToAsnDetail = new ArrayList<>(); - List createToReceiveRecord = new ArrayList<>(); - List createToInventory = new ArrayList<>(); - List createToInventoryLog = new ArrayList<>(); + List createRecords = new ArrayList<>(); + Map inventoryMap = new HashMap<>(); + List createInventoryLogs = new ArrayList<>(); //4.处理数据 - receive(data, updateToAsnDetail, createToReceiveRecord, createToInventory, createToInventoryLog); + receive(data, updateToAsnDetail, createRecords, inventoryMap, createInventoryLogs); //5.批量操作 - batchOperation(updateToAsnDetail, createToReceiveRecord, createToInventory, createToInventoryLog); + batchOperation(updateToAsnDetail, createRecords, inventoryMap, createInventoryLogs); //6.刷新入库 refreshData(data); @@ -110,6 +106,7 @@ public class ReceiveProcessor { updateStockAndPoint(data.getStock(), data.getDstPoint()); //8.回传 + receiveBackProcessor.receiveBack(data.getAsn(), data.getStock()); } /** @@ -137,36 +134,29 @@ public class ReceiveProcessor { return data; } - /** - * 验证托盘 - * - * @param stock 托盘 - */ - private void validateStock(Stock stock) { - if (inventoryMapper.exitsStockInventory(stock.getId()) != null) { - throw new RuntimeException("【" + stock.getStockCode() + "】托盘已入库"); - } - } - /** * 处理数据 * - * @param data 数据 - * @param updateToAsnDetail 更新入库单明细 - * @param createToReceiveRecord 创建收货记录 - * @param createToInventory 创建库存 - * @param createToInventoryLog 创建库存日志 + * @param data 数据 + * @param updateToAsnDetail 更新入库单明细 + * @param records 创建收货记录 + * @param inventoryMap 创建库存 + * @param inventoryLogs 创建库存日志 */ private void receive(ReceiveData data, List updateToAsnDetail, - List createToReceiveRecord, - List createToInventory, - List createToInventoryLog) { + List records, + Map inventoryMap, + List inventoryLogs) { Asn asn = data.getAsn(); Point dstPoint = data.getDstPoint(); Stock stock = data.getStock(); for (AsnDetail asnDetail : data.getAsnDetails()) { - BigDecimal receivedQty = BigDecimalUtil.add(asnDetail.getReceivedQty(), asnDetail.getOrderQty(), 0); + BigDecimal unreceivedQty = BigDecimalUtil.subtract(asnDetail.getOrderQty(), asnDetail.getReceivedQty(), 0); + if (unreceivedQty.compareTo(BigDecimal.ZERO) <= 0) { + continue; + } + BigDecimal receivedQty = BigDecimalUtil.add(asnDetail.getReceivedQty(), unreceivedQty, 0); asnDetail.setReceivedQty(receivedQty); //更新明细状态 if (receivedQty.compareTo(asnDetail.getOrderQty()) >= 0) { @@ -181,39 +171,62 @@ public class ReceiveProcessor { //生成入库记录 ReceiveRecord receiveRecord = asnDetailService.buildReceiveRecord(asnDetail, receivedQty, itemKey, dstPoint.getId()); - createToReceiveRecord.add(receiveRecord); + records.add(receiveRecord); // 生成库存 - Inventory inventory = inventoryService.buildInventory(stock.getId(), receivedQty, asn, receiveRecord); - createToInventory.add(inventory); + Inventory inventory = createInventory(asn, receiveRecord, itemKey, stock, receivedQty, inventoryMap); //添加库存日志 - InventoryLog inventoryLog = inventoryLogService.buildInboundInventoryLog(inventory, asnDetail.getToPointId(), receivedQty, asn.getOrderNo(), asnDetail.getId(), asnDetail.getDescription()); - createToInventoryLog.add(inventoryLog); + InventoryLog inventoryLog = inventoryLogService.buildInboundInventoryLog(inventory, asnDetail.getToPointId(),receivedQty, asn.getThirdOrderNo(), receiveRecord.getId(), receiveRecord.getDescription()); + inventoryLogs.add(inventoryLog); } } + + /** + * 创建库存 + * + * @param asn 入库单 + * @param receiveRecord 收货记录 + * @param itemKey 物料属性 + * @param stock 容器 + * @param receivedQty 收货数量 + * @param inventoryMap 创建库存 + */ + private Inventory createInventory(Asn asn, ReceiveRecord receiveRecord, ItemKey itemKey, Stock stock, BigDecimal receivedQty, Map inventoryMap) { + Inventory inventory = inventoryService.buildInventory(stock.getId(), BigDecimal.ZERO, asn, receiveRecord); + //根据itemKey更新库存 + Inventory targetInventory = inventoryMap.getOrDefault(itemKey.getId(), inventory); + BigDecimal newReceivedQty = BigDecimalUtil.add(targetInventory.getQuantity(), receivedQty, 0); + targetInventory.setQuantity(newReceivedQty); + inventoryMap.put(targetInventory.getItemKeyId(), targetInventory); + return targetInventory; + } + + /** * 批量操作 * - * @param updateToAsnDetail 更新入库单明细 - * @param createToReceiveRecord 创建收货记录 - * @param createToInventory 创建库存 - * @param createToInventoryLog 创建库存日志 + * @param updateToAsnDetail 更新入库单明细 + * @param records 创建收货记录 + * @param inventoryMap 创建库存 + * @param inventoryLogs 创建库存日志 */ @Transactional(rollbackFor = Exception.class) - public void batchOperation( List updateToAsnDetail,List createToReceiveRecord , List createToInventory, List createToInventoryLog) { + public void batchOperation(List updateToAsnDetail, List records, + Map inventoryMap, List inventoryLogs) { if (CollectionUtils.isNotEmpty(updateToAsnDetail)) { batchUtil.updateBatchAsnDetail(updateToAsnDetail); } - if (CollectionUtils.isNotEmpty(createToReceiveRecord)) { - batchUtil.saveBatchReceiveRecord(createToReceiveRecord); + if (CollectionUtils.isNotEmpty(records)) { + batchUtil.saveBatchReceiveRecord(records); } - if (CollectionUtils.isNotEmpty(createToInventory)) { + if (inventoryMap != null && !inventoryMap.isEmpty()) { + List createToInventory = new ArrayList<>(inventoryMap.values()); batchUtil.saveBatchInventory(createToInventory); } - if (CollectionUtils.isNotEmpty(createToInventoryLog)) { - batchUtil.saveBatchInventoryLog(createToInventoryLog); + if (CollectionUtils.isNotEmpty(inventoryLogs)) { + batchUtil.saveBatchInventoryLog(inventoryLogs); } } @@ -229,7 +242,7 @@ public class ReceiveProcessor { /** * 更新容器状态和位置 * - * @param stock 托盘 + * @param stock 托盘 * @param dstPoint 目标库位 */ @Transactional(rollbackFor = Exception.class) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java index ed47804..0b82818 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/controller/SaiWmsController.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.cpte.modules.saiWms.request.CallAgvRequest; import org.cpte.modules.saiWms.request.InboundRequest; import org.cpte.modules.saiWms.request.OutboundRequest; import org.cpte.modules.saiWms.request.SyncStockRequest; @@ -38,6 +39,14 @@ public class SaiWmsController { return Result.OK("操作成功!"); } + @AutoLog(value = "呼叫AGV") + @Operation(summary = "赛意WMS-呼叫AGV") + @PostMapping(value = "/callAgv") + public Result callAgv(@RequestBody CallAgvRequest callAgvRequest) { + iSaiWmsService.callAgv(callAgvRequest); + return Result.OK("操作成功!"); + } + /** * 入库任务下发 * diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/CallAgvRequest.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/CallAgvRequest.java new file mode 100644 index 0000000..55f9fb8 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/CallAgvRequest.java @@ -0,0 +1,19 @@ +package org.cpte.modules.saiWms.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class CallAgvRequest { + // 托盘号 + @JsonProperty("stockCode") + private String stockCode; + + // 起点 + @JsonProperty("fromCode") + private String fromCode; + + //终点 + @JsonProperty("toCode") + private String toCode; +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISMOMService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISMOMService.java index d0523cd..5744d1b 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISMOMService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/ISMOMService.java @@ -1,5 +1,6 @@ package org.cpte.modules.saiWms.service; +import org.cpte.modules.saiWms.request.CallAgvRequest; import org.cpte.modules.saiWms.request.InboundRequest; import org.cpte.modules.saiWms.request.OutboundRequest; import org.cpte.modules.saiWms.request.SyncStockRequest; @@ -24,4 +25,9 @@ public interface ISMOMService { * 容器同步 */ void syncStock(SyncStockRequest syncStockRequest); + + /** + * 呼叫AGV + */ + void callAgv(CallAgvRequest callAgvRequest); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISMOMServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISMOMServiceImpl.java index 4af6962..c08d284 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISMOMServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISMOMServiceImpl.java @@ -1,16 +1,22 @@ package org.cpte.modules.saiWms.service.impl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.cpte.modules.saiWms.request.CallAgvRequest; import org.cpte.modules.saiWms.request.InboundRequest; import org.cpte.modules.saiWms.request.OutboundRequest; import org.cpte.modules.saiWms.request.SyncStockRequest; import org.cpte.modules.saiWms.service.ISMOMService; -import org.cpte.modules.saiWms.service.InBoundTaskProcessor; -import org.cpte.modules.saiWms.service.OutBoundTaskProcessor; -import org.cpte.modules.saiWms.service.SyncStockProcessor; +import org.cpte.modules.saiWms.service.processor.CallAgvProcessor; +import org.cpte.modules.saiWms.service.processor.InBoundTaskProcessor; +import org.cpte.modules.saiWms.service.processor.OutBoundTaskProcessor; +import org.cpte.modules.saiWms.service.processor.SyncStockProcessor; +import org.cpte.modules.utils.RedisDistributedLockUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service +@Slf4j public class ISMOMServiceImpl implements ISMOMService { @Autowired @@ -22,6 +28,11 @@ public class ISMOMServiceImpl implements ISMOMService { @Autowired private SyncStockProcessor syncStockProcessor; + @Autowired + private CallAgvProcessor callAgvProcessor; + + @Autowired + private RedisDistributedLockUtil redissonLock; @Override public void inBoundTask(InboundRequest inboundRequest) { @@ -37,6 +48,26 @@ public class ISMOMServiceImpl implements ISMOMService { public void syncStock(SyncStockRequest syncStockRequest) { syncStockProcessor.syncStock(syncStockRequest); } + + @Override + public void callAgv(CallAgvRequest callAgvRequest) { + String lockKey = "stock:" + callAgvRequest.getStockCode(); + String lockValue = null; + try { + lockValue = redissonLock.tryLock(lockKey, 10); + if (StringUtils.isEmpty(lockValue)) { + throw new RuntimeException("AGV呼叫中,请稍后重试"); + } + callAgvProcessor.callAgv(callAgvRequest); + } catch (Exception e) { + log.error("AGV呼叫异常", e); + throw e; + } finally { + if (StringUtils.isNotEmpty(lockValue)) { + redissonLock.unlock(lockKey, lockValue); + } + } + } } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/CallAgvProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/CallAgvProcessor.java new file mode 100644 index 0000000..7eedcf7 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/CallAgvProcessor.java @@ -0,0 +1,97 @@ +package org.cpte.modules.saiWms.service.processor; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.cpte.modules.agvTask.mapper.AgvTaskMapper; +import org.cpte.modules.agvTask.service.IAgvTaskService; +import org.cpte.modules.base.entity.Point; +import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.base.service.IPointService; +import org.cpte.modules.base.service.IStockService; +import org.cpte.modules.constant.enums.AgvVendorEnum; +import org.cpte.modules.constant.enums.AsnOrderTypeEnum; +import org.cpte.modules.constant.enums.BusinessTypeEnum; +import org.cpte.modules.saiWms.request.CallAgvRequest; +import org.cpte.modules.saiWms.request.InboundRequest; +import org.cpte.modules.saiWms.vo.CallData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 呼叫AGV处理 + */ +@Service +@Slf4j +public class CallAgvProcessor { + + @Autowired + private AgvTaskMapper agvTaskMapper; + + @Autowired + private IStockService stockService; + + @Autowired + private IPointService pointService; + + @Autowired + private IAgvTaskService agvTaskService; + + public void callAgv(CallAgvRequest callAgvRequest) { + // 1.参数校验 + validateParams(callAgvRequest); + + //2.数据准备 + CallData callData = validateData(callAgvRequest); + + //3.生成AGV任务 + generateAgvTask(callData); + } + + /** + * 呼叫参数校验 + * + * @param callAgvRequest 呼叫参数 + */ + private void validateParams(CallAgvRequest callAgvRequest) { + if (StringUtils.isBlank(callAgvRequest.getStockCode())) { + throw new RuntimeException("托盘号(stockCode)必填"); + } + if (StringUtils.isBlank(callAgvRequest.getFromCode())) { + throw new RuntimeException("起点(fromCode)必填"); + } + if (StringUtils.isBlank(callAgvRequest.getToCode())) { + throw new RuntimeException("终点(toCode)必填"); + } + } + + private CallData validateData(CallAgvRequest callAgvRequest) { + CallData callData = new CallData(); + //1.获取托盘 + Stock stock = stockService.validateStock(callAgvRequest.getStockCode()); + callData.setStock(stock); + + //2.获取起点 + Point fromPoint = pointService.validatePoint(callAgvRequest.getFromCode()); + callData.setFromPoint(fromPoint); + + callData.setToCode(callAgvRequest.getToCode()); + return callData; + } + + /** + * 生成AGV任务 + * + * @param callData 呼叫参数 + */ + private void generateAgvTask(CallData callData) { + String stockCode = callData.getStock().getStockCode(); + if (agvTaskMapper.existsByStockCode(stockCode, AgvVendorEnum.HIK.getValue()) != null) { + throw new RuntimeException("【" + stockCode + "】容器已生成AGV任务,请勿重复操作! "); + } + agvTaskService.createAgvTask(null, stockCode, callData.getFromPoint().getPointCode(), callData.getToCode(), null, BusinessTypeEnum.TRANSPORT.getValue(), 0, AgvVendorEnum.HIK.getValue()); + } +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/InBoundTaskProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java similarity index 99% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/InBoundTaskProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java index 8117ae3..b02fc81 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/InBoundTaskProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java @@ -1,4 +1,4 @@ -package org.cpte.modules.saiWms.service; +package org.cpte.modules.saiWms.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/OutBoundTaskProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/OutBoundTaskProcessor.java similarity index 99% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/OutBoundTaskProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/OutBoundTaskProcessor.java index ae57cfd..0407547 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/OutBoundTaskProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/OutBoundTaskProcessor.java @@ -1,4 +1,4 @@ -package org.cpte.modules.saiWms.service; +package org.cpte.modules.saiWms.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/SyncStockProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/SyncStockProcessor.java similarity index 98% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/SyncStockProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/SyncStockProcessor.java index ca0307e..48aece7 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/SyncStockProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/SyncStockProcessor.java @@ -1,4 +1,4 @@ -package org.cpte.modules.saiWms.service; +package org.cpte.modules.saiWms.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/vo/CallData.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/vo/CallData.java new file mode 100644 index 0000000..8392cf6 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/vo/CallData.java @@ -0,0 +1,12 @@ +package org.cpte.modules.saiWms.vo; + +import lombok.Data; +import org.cpte.modules.base.entity.Point; +import org.cpte.modules.base.entity.Stock; + +@Data +public class CallData { + private Stock stock; + private Point fromPoint; + private String toCode; +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java index d3e6191..680311b 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/controller/PickController.java @@ -12,6 +12,7 @@ import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.serialNumber.PickSerialNumberRule; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.service.ITaskService; +import org.jeecg.common.system.query.QueryRuleEnum; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; @@ -80,6 +81,8 @@ public class PickController { @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(pick, req.getParameterMap()); + List status = Arrays.stream(req.getParameterMap().get("status[]")).toList(); + queryWrapper.in("status", status); Page page = new Page(pageNo, pageSize); IPage pageList = pickService.page(page, queryWrapper); return Result.OK(pageList); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java index dc85fbb..c56b075 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/entity/Task.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.*; import com.fasterxml.jackson.annotation.JsonFormat; +import org.jeecg.common.aspect.annotation.Dict; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickDetailService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickDetailService.java index e78fbc8..46e8be0 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickDetailService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickDetailService.java @@ -30,6 +30,14 @@ public interface IPickDetailService extends IService { */ Map queryByPickIdsToMap(List pickIds); + /** + * 根据出库单明细ID查询出库单明细Map + * + * @param pickDetailIds 出库单明细ID集合 + * @return Map + */ + Map queryByPickDetailIdsToMap(List pickDetailIds); + /** * 刷新出库单 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java index a439d65..4885032 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/IPickService.java @@ -89,17 +89,6 @@ public interface IPickService extends IService { * * @param tasks 任务 */ - void pickTask(List tasks, Point endPoint); - - /** - * 出库任务回传 - * - * @param pick 出库单 - * @param pickDetail 出库明细 - * @param task 出库任务 - * @param state 回传状态 最后一托任务给完工。5,其余执行中.7 - */ - void pickTaskCallback(Pick pick, PickDetail pickDetail, Task task, Integer state); - + void pickTask(List tasks); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java index d02ea04..69b23f2 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java @@ -58,12 +58,10 @@ public interface ITaskService extends IService { void generateAgvTask(); /** - * 根据需要移位的库位生成Task任务 + * 根据主表ID查询任务 * - * @param movePointIds 库位 - * @return Task + * @param id 主表ID + * @return List */ - List bulidMoveTask(List movePointIds); - List queryTaskByMainId(Long id); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickDetailServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickDetailServiceImpl.java index ae12350..a4dbc4b 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickDetailServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickDetailServiceImpl.java @@ -49,7 +49,26 @@ public class PickDetailServiceImpl extends ServiceImpl queryByPickDetailIdsToMap(List pickDetailIds) { + if (CollectionUtils.isEmpty(pickDetailIds)) { + return Collections.emptyMap(); + } + Map pickDetailMap = new HashMap<>(); + List pickDetails = this.baseMapper.selectByIds(pickDetailIds); + for (PickDetail pickDetail : pickDetails) { + pickDetailMap.put(pickDetail.getId(), pickDetail); + } + return pickDetailMap; + } + + + /** * 刷新出库单状态 * * @param pick 出库单 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java index 06c868d..b0887af 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/PickServiceImpl.java @@ -9,13 +9,10 @@ import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.base.entity.Item; -import org.cpte.modules.base.entity.Point; import org.cpte.modules.constant.enums.*; import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.service.IInventoryService; import org.cpte.modules.inventoryLog.service.IInventoryLogService; -import org.cpte.modules.receive.entity.Asn; -import org.cpte.modules.receive.entity.AsnDetail; import org.cpte.modules.saiWms.request.OutboundRequest; import org.cpte.modules.saiWms.request.SMOMRequest; import org.cpte.modules.serialNumber.PickSerialNumberRule; @@ -25,10 +22,11 @@ import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.PickDetailMapper; import org.cpte.modules.shipping.mapper.PickMapper; import org.cpte.modules.shipping.mapper.TaskMapper; -import org.cpte.modules.shipping.service.AllocateProcessor; -import org.cpte.modules.shipping.service.CancelAllocateProcessor; +import org.cpte.modules.shipping.service.processor.AllocateProcessor; +import org.cpte.modules.shipping.service.processor.CancelAllocateProcessor; import org.cpte.modules.shipping.service.IPickDetailService; import org.cpte.modules.shipping.service.IPickService; +import org.cpte.modules.shipping.service.processor.PickProcessor; import org.cpte.modules.utils.BatchUtil; import org.cpte.modules.utils.BigDecimalUtil; import org.cpte.modules.utils.RedisDistributedLockUtil; @@ -62,50 +60,20 @@ public class PickServiceImpl extends ServiceImpl implements IP @Autowired private PickDetailMapper pickDetailMapper; @Autowired - private TaskMapper taskMapper; - @Autowired - private SysDictMapper sysDictMapper; - @Autowired - private OpenApiMapper openApiMapper; - @Autowired private IPickDetailService pickDetailService; @Autowired - private IInventoryService inventoryService; - @Autowired - private IInventoryLogService inventoryLogService; - @Autowired private BaseCommonService baseCommonService; @Autowired - private SwmsLoginUtil swmsLoginUtil; - @Autowired - private BatchUtil batchUtils; - @Autowired private PickSerialNumberRule pickSerialNumberRule; @Autowired private AllocateProcessor allocateProcessor; @Autowired private CancelAllocateProcessor cancelAllocateProcessor; @Autowired + private PickProcessor pickProcessor; + @Autowired private RedisDistributedLockUtil redissonLock; - /** - * 获取出库单明细Map - * - * @param pickDetailIds 出库单明细id - * @return 出库单明细Map - */ - private Map queryByPickDetailIdsToMap(List pickDetailIds) { - if (CollectionUtils.isEmpty(pickDetailIds)) { - return Collections.emptyMap(); - } - Map pickDetailMap = new HashMap<>(); - List pickDetails = pickDetailMapper.selectByIds(pickDetailIds); - for (PickDetail pickDetail : pickDetails) { - pickDetailMap.put(pickDetail.getId(), pickDetail); - } - return pickDetailMap; - } - @Override public void saveMain(Pick pick, List pickDetailList) { @@ -114,9 +82,12 @@ public class PickServiceImpl extends ServiceImpl implements IP try { lockValue = redissonLock.tryLock(lockKey, 10); if (StringUtils.isEmpty(lockValue)) { - throw new RuntimeException("出库处理中,请稍后重试"); + throw new RuntimeException("出库单创建中,请稍后重试"); } processorSaveMain(pick, pickDetailList); + } catch (Exception e) { + log.error("出库单创建异常", e); + throw e; } finally { if (StringUtils.isNotEmpty(lockValue)) { redissonLock.unlock(lockKey, lockValue); @@ -281,222 +252,8 @@ public class PickServiceImpl extends ServiceImpl implements IP } @Override - @Transactional(rollbackFor = Exception.class) - public void pickTask(List tasks, Point endPoint) { - - // ================= 1. 数据准备 (批量查询) ================= - // 1.1 获取出库单 - List pickIds = tasks.stream().map(Task::getPickId).distinct().toList(); - List pickDetailIds = tasks.stream().map(Task::getPickDetailId).distinct().toList(); - List inventoryIds = tasks.stream().map(Task::getInventoryId).distinct().toList(); - - // 1.2 构建映射 Map - Map pickMap = pickDetailService.queryByPickIdsToMap(pickIds); - Map pickDetailMap = queryByPickDetailIdsToMap(pickDetailIds); - Map inventoryMap = inventoryService.queryByInventoryIdsToMap(inventoryIds); - - // -------------------------- 2. 创建更新列表--------------------------- - List updateToPickDetail = new ArrayList<>(); - List updateToTask = new ArrayList<>(); - List updateToInventory = new ArrayList<>(); - List deleteToInventoryIds = new ArrayList<>(); - - // -------------------------- 3. 循环拣货 ------------------- - for (Task task : tasks) { - BigDecimal pickedQty = BigDecimalUtil.subtract(task.getPlanQty(), task.getMoveQty(), 0); - if (pickedQty.compareTo(BigDecimal.ZERO) <= 0) { - continue; - } - Pick pick = pickMap.get(task.getPickId()); - PickDetail pickDetail = pickDetailMap.get(task.getPickDetailId()); - - // 更新拣货数量,状态 - pickDetail.setPickedQty(BigDecimalUtil.add(pickDetail.getPickedQty(), pickedQty, 0)); - Integer status = pickedQty.compareTo(pickDetail.getOrderQty()) >= 0 ? PickStatusEnum.PICKED.getValue() : PickStatusEnum.PICKING.getValue(); - pickDetail.setStatus(status); - updateToPickDetail.add(pickDetail); - - // 更新任务 - task.setMoveQty(pickedQty); - task.setTaskStatus(TaskStatusEnum.COMPLETED.getValue()); - updateToTask.add(task); - - //扣减库存 - Inventory inventory = inventoryMap.get(task.getInventoryId()); - inventory.setQuantity(BigDecimalUtil.subtract(inventory.getQuantity(), pickedQty, 0)); - inventory.setQueuedQty(BigDecimalUtil.subtract(inventory.getQueuedQty(), pickedQty, 0)); - inventory.setPointId(endPoint.getId()); - updateToInventory.add(inventory); - - //库存为0,删除库存 - if (inventory.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { - deleteToInventoryIds.add(inventory.getId()); - } - - inventoryLogService.addPickInventoryLog(inventory, pickedQty, pick.getOrderNo(), task.getPickDetailId(), null); - } - - // -------------------------- 4. 批量操作 -------------------------- - if (CollectionUtils.isNotEmpty(updateToPickDetail)) { - batchUtils.updateBatchPickDetail(updateToPickDetail); - } - if (CollectionUtils.isNotEmpty(updateToTask)) { - batchUtils.updateBatchTask(updateToTask); - } - if (CollectionUtils.isNotEmpty(updateToInventory)) { - batchUtils.updateBatchInventory(updateToInventory); - } - if (CollectionUtils.isNotEmpty(deleteToInventoryIds)) { - inventoryService.removeByIds(deleteToInventoryIds); - } - - // -------------------------- 6. 出库回传 -------------------------- - Map> pickDetailsCache = new HashMap<>(); - for (Task task : tasks) { - Pick pick = pickMap.get(task.getPickId()); - PickDetail pickDetail = pickDetailMap.get(task.getPickDetailId()); - - // 缓存查询结果,避免重复查询 - Long pickId = pick.getId(); - List pickDetails = pickDetailsCache.computeIfAbsent(pickId, - id -> pickDetailMapper.selectByMainId(id)); - - List closedPickDetails = pickDetails.stream() - .filter(detail -> PickStatusEnum.CLOSED.getValue().equals(detail.getStatus())) - .toList(); - - int state = pickDetails.size() - closedPickDetails.size() == 1 ? 5 : 7; - - try { - pickTaskCallback(pick, pickDetail, task, state); - } catch (Exception e) { - log.error("出库任务回传失败,任务ID: {}, 错误信息: {}", task.getId(), e.getMessage(), e); - } - - // 刷新时重新查询最新的数据 - List latestPickDetails = pickDetailMapper.selectByMainId(pick.getId()); - pickDetailsCache.put(pickId, latestPickDetails); // 更新缓存 - pickDetailService.refreshPick(pick, latestPickDetails); - } - - } - - /** - * 出库库任务回传JSON - */ - private String pickTaskCallbackJson(Pick pick, PickDetail pickDetail, Task task, Integer state, String ticket) { - SMOMRequest.Task taskReq = new SMOMRequest.Task(); - taskReq.setNo(pick.getNo()); - taskReq.setOrderNo(pick.getThirdOrderNo()); - taskReq.setState(state); - - SMOMRequest.ShipmentFeedbackDetail shipmentFeedbackDetail = new SMOMRequest.ShipmentFeedbackDetail(); - shipmentFeedbackDetail.setLineNo(String.valueOf(pickDetail.getLineNo())); - shipmentFeedbackDetail.setLpn(task.getStockCode()); - shipmentFeedbackDetail.setQty(task.getPlanQty().intValue()); - shipmentFeedbackDetail.setIsTakeDown(task.getIzAll() == 0); - shipmentFeedbackDetail.setProject(pickDetail.getProject()); - shipmentFeedbackDetail.setTaskNo(pickDetail.getTaskNo()); - shipmentFeedbackDetail.setLotAtt04(pickDetail.getPropC1()); - shipmentFeedbackDetail.setLotAtt010(pickDetail.getPropC3()); - shipmentFeedbackDetail.setErpKey(pick.getNo()); - shipmentFeedbackDetail.setIsDelete(false); - String lastUpdateDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - shipmentFeedbackDetail.setLastUpdateDate(lastUpdateDate); - taskReq.setShipmentFeedbackDetails(List.of(shipmentFeedbackDetail)); - - taskReq.setErpKey(pick.getNo()); - taskReq.setInfkey(pick.getNo()); - taskReq.setIsDelete(false); - taskReq.setLastUpdateDate(lastUpdateDate); - - - SMOMRequest.ParameterValue1 parameterValue1 = new SMOMRequest.ParameterValue1(); - parameterValue1.setValue(List.of(taskReq)); - - SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); - parameterValue2.setValue(1); - - SMOMRequest.Context context = new SMOMRequest.Context(); - context.setInvOrgId(1); - context.setTicket(ticket); - - SMOMRequest saiWmsRequest = new SMOMRequest(); - saiWmsRequest.setApiType("SmomWebApiController"); - saiWmsRequest.setParameters(List.of(parameterValue1, parameterValue2)); - saiWmsRequest.setMethod("OutboundTaskCallbackInterface"); - saiWmsRequest.setContext(context); - - return JSON.toJSONString(saiWmsRequest); - } - - @Override - public void pickTaskCallback(Pick pick, PickDetail pickDetail, Task task, Integer state) { - // 检查接口开关, 未开启则返回 - if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) { - updatePickDetailResponse(pickDetail, task, GeneralConstant.SMOM_FAIL_CODE, "接口未开启"); - return; - } - - if (TaskStatusEnum.CLOSED.getValue().equals(task.getTaskStatus())) { - return; - } - - try { - Map authInfo = swmsLoginUtil.Login(); - if (authInfo == null || authInfo.isEmpty()) { - throw new RuntimeException("登录认证信息为空"); - } - - String ticket = authInfo.get("Ticket"); - String authorization = authInfo.get("authorization"); - String json = pickTaskCallbackJson(pick, pickDetail, task, state, ticket); - String url = openApiMapper.getRequestUrl(GeneralConstant.OUTBOUND_CALLBACK).getOriginUrl(); - JSONObject jsonObject = swmsLoginUtil.sendSMOMResponse(json, url, authorization); - String code = validateResponse(jsonObject); - updatePickDetailResponse(pickDetail, task, code, jsonObject.toJSONString()); - } catch (Exception e) { - updatePickDetailResponse(pickDetail, task, GeneralConstant.SMOM_FAIL_CODE, e.getMessage()); - } - } - - /** - * 验证响应数据 - * - * @param jsonObject 响应数据 - * @return 状态码 - */ - private String validateResponse(JSONObject jsonObject) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data == null) { - throw new RuntimeException("数据格式错误:缺少data字段"); - } - JSONObject Result = data.getJSONObject("Result"); - if (Result == null) { - throw new RuntimeException("数据格式错误:缺少Result字段"); - } - JSONArray jsonArray = Result.getJSONArray("ErpErrorDatas"); - return jsonArray.isEmpty() ? GeneralConstant.SMOM_SUCCESS_CODE : GeneralConstant.SMOM_FAIL_CODE; - } - - - /** - * 更新任务状态 - * - * @param task 出库任务 - * @param message 信息 - */ - private void updatePickDetailResponse(PickDetail pickDetail, Task task, String code, String message) { - if (GeneralConstant.SMOM_SUCCESS_CODE.equals(code)) { - if (PickStatusEnum.PICKED.getValue().equals(pickDetail.getStatus())) { - pickDetail.setStatus(PickStatusEnum.CLOSED.getValue()); - pickDetailMapper.updateById(pickDetail); - } - task.setTaskStatus(TaskStatusEnum.CLOSED.getValue()); - } - task.setResMessage(message); - task.setResTime(new Date()); - taskMapper.updateById(task); + public void pickTask(List tasks) { + pickProcessor.pick(tasks); } } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java index 001cbf5..9e6a4af 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/impl/TaskServiceImpl.java @@ -1,22 +1,15 @@ package org.cpte.modules.shipping.service.impl; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.shiro.SecurityUtils; import org.cpte.modules.agvTask.entity.AgvTask; import org.cpte.modules.agvTask.service.IAgvTaskService; -import org.cpte.modules.base.entity.Item; -import org.cpte.modules.base.entity.Point; -import org.cpte.modules.base.entity.Stock; -import org.cpte.modules.base.mapper.PointMapper; -import org.cpte.modules.base.service.IItemService; -import org.cpte.modules.base.service.IPointService; -import org.cpte.modules.base.service.IStockService; -import org.cpte.modules.constant.GeneralConstant; +import org.cpte.modules.base.entity.*; import org.cpte.modules.constant.enums.*; import org.cpte.modules.inventory.entity.Inventory; -import org.cpte.modules.inventory.mapper.InventoryMapper; -import org.cpte.modules.serialNumber.MoveSerialNumberRule; +import org.cpte.modules.inventory.service.IInventoryService; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.TaskMapper; import org.cpte.modules.shipping.service.ITaskService; @@ -30,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -43,19 +37,7 @@ import java.util.stream.Collectors; public class TaskServiceImpl extends ServiceImpl implements ITaskService { @Autowired - private PointMapper pointMapper; - - @Autowired - private InventoryMapper inventoryMapper; - - @Autowired - private IItemService iItemService; - - @Autowired - private IPointService iPointService; - - @Autowired - private IStockService iStockService; + private IInventoryService iInventoryService; @Autowired private IAgvTaskService agvTaskService; @@ -63,8 +45,6 @@ public class TaskServiceImpl extends ServiceImpl implements IT @Autowired private BatchUtil batchUtils; - @Autowired - private MoveSerialNumberRule moveSerialNumberRule; @Override @Transactional(rollbackFor = Exception.class) @@ -103,7 +83,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT } @Override - public Task bulidTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId,Long itemKeyId, Long inventoryId, BigDecimal planQty, Integer izAll) { + public Task bulidTask(String taskNo, Integer taskType, Item item, Point fromPoint, Point toPoint, Stock stock, Long pickId, Long pickDetailId, Long itemKeyId, Long inventoryId, BigDecimal planQty, Integer izAll) { LoginUser sysUser = null; try { sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); @@ -111,6 +91,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT log.error("获取登录用户信息失败"); } return Task.builder() + .id(IdWorker.getId()) .taskNo(taskNo) .itemId(item.getId()) .itemCode(item.getItemCode()) @@ -137,14 +118,17 @@ public class TaskServiceImpl extends ServiceImpl implements IT } @Override - @Transactional(rollbackFor = Exception.class) public void generateAgvTask() { List taskList = this.baseMapper.queryUnallocatedTask(); if (CollectionUtils.isEmpty(taskList)) { return; } - //根据stockCode、fromPointCode、toPointCode 分组 + //1.获取库存 + List inventoryIds = taskList.stream().map(Task::getInventoryId).distinct().toList(); + Map inventoryMap = iInventoryService.queryByInventoryIdsToMap(inventoryIds); + + //2.根据stockCode、fromPointCode、toPointCode 分组 Map> taskGroupMap = taskList.stream() .sorted(Comparator.comparing(Task::getCreateTime)) .collect(Collectors.groupingBy(task -> TaskGroupKey.of( @@ -153,7 +137,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT task.getToPointCode() ))); - //批量创建AGV任务 + //3.批量创建AGV任务 List createToAgvTaskList = new ArrayList<>(); Map groupToAgvTaskMap = new HashMap<>(); for (Map.Entry> entry : taskGroupMap.entrySet()) { @@ -162,8 +146,10 @@ public class TaskServiceImpl extends ServiceImpl implements IT boolean allSplit = tasks.stream().allMatch(task -> task != null && task.getIzAll() == 1); Integer izAll = allSplit ? 1 : 0; log.info("任务分组:{}", key); + String businessType = tasks.get(0).getTaskType() == 1 ? BusinessTypeEnum.OUTBOUND.getValue() : BusinessTypeEnum.MOVE.getValue(); + if (!groupToAgvTaskMap.containsKey(key)) { - AgvTask agvTask = agvTaskService.bulidAgvTask(null, key.getStockCode(), key.getFromPointCode(), key.getToPointCode(), null, BusinessTypeEnum.OUTBOUND.getValue(), izAll, AgvVendorEnum.TES.getValue()); + AgvTask agvTask = agvTaskService.bulidAgvTask(null, key.getStockCode(), key.getFromPointCode(), key.getToPointCode(), null, businessType, izAll, AgvVendorEnum.TES.getValue()); createToAgvTaskList.add(agvTask); groupToAgvTaskMap.put(key, agvTask); // 建立映射 log.info("创建AGV任务:{}", agvTask); @@ -175,6 +161,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT //批量更新任务 List updateToTaskList = new ArrayList<>(); + List inventoryList = new ArrayList<>(); for (Map.Entry> entry : taskGroupMap.entrySet()) { TaskGroupKey key = entry.getKey(); AgvTask agvTask = groupToAgvTaskMap.get(key); // 通过key获取 @@ -182,68 +169,30 @@ public class TaskServiceImpl extends ServiceImpl implements IT for (Task task : list) { task.setAgvTaskId(agvTask.getId()); updateToTaskList.add(task); + Inventory inventory = inventoryMap.get(task.getInventoryId()); + if (inventory != null) { + Integer status = TaskTypeEnum.PICK.getValue().equals(task.getTaskType()) ? InventoryStatusEnum.OUTBOUND.getValue() : InventoryStatusEnum.MOVE.getValue(); + inventory.setStatus(status); + inventoryList.add(inventory); + } } } if (CollectionUtils.isNotEmpty(updateToTaskList)) { batchUtils.updateBatchTask(updateToTaskList); } - List inventoryIdList = taskList.stream().map(Task::getInventoryId).distinct().toList(); - List inventoryList = inventoryMapper.selectByIds(inventoryIdList); - for (Inventory inventory : inventoryList) { - inventory.setStatus(InventoryStatusEnum.OUTBOUND.getValue()); - } + if (CollectionUtils.isNotEmpty(inventoryList)) { - batchUtils.updateBatchInventory(inventoryList); + Map distinctInventoryMap = inventoryList.stream() + .collect(Collectors.toMap(Inventory::getId, + Function.identity(), (existing, replacement) -> existing)); + batchUtils.updateBatchInventory(new ArrayList<>(distinctInventoryMap.values())); } } - @Override - public List bulidMoveTask(List movePointIds) { - List moveList = new ArrayList<>(); - List moveInventoryList = inventoryMapper.queryByPointIds(movePointIds); - - //移位物料 - List moveItemIds = moveInventoryList.stream().map(Inventory::getItemId).distinct().toList(); - Map moveItemMap = iItemService.queryByItemIdsToMap(moveItemIds); - - //移位库位 - List fromPointIds = moveInventoryList.stream().map(Inventory::getPointId).distinct().toList(); - Map fromPointMap = iPointService.queryByPointIdsToMap(fromPointIds); - - //移位容器 - List stockIds = moveInventoryList.stream().map(Inventory::getStockId).distinct().toList(); - Map stockMap = iStockService.queryByStockIdsToMap(stockIds); - - for (Inventory inv : moveInventoryList) { - - //判读改点位是否有出库任务 - Item moveItem = moveItemMap.get(inv.getItemId()); - Point fromPoint = fromPointMap.get(inv.getPointId()); - Stock stock = stockMap.get(inv.getStockId()); - String taskNo = moveSerialNumberRule.generateSerialNumber(GeneralConstant.MOVE_ORDER_NO); - //根据算法找到最优的目标库位 - Point toPoint=null; - Task moveTask = this.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null,inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0); - moveList.add(moveTask); - log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity()); - inv.setStatus(InventoryStatusEnum.TRANSFER.getValue()); - inventoryMapper.updateById(inv); - } - return moveList; - } - @Override public List queryTaskByMainId(Long id) { return this.baseMapper.queryTaskByMainId(id); } - /** - * 选择最优移位目标 - */ - private Point findBestMovePoint(){ - // 1. 获取所有可用库位 - //List availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode); - return null; - } } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/AllocateProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java similarity index 78% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/AllocateProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java index 13bfbe6..030a525 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/AllocateProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java @@ -1,24 +1,28 @@ -package org.cpte.modules.shipping.service; +package org.cpte.modules.shipping.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.cpte.modules.base.entity.Item; -import org.cpte.modules.base.entity.ItemKey; -import org.cpte.modules.base.entity.Point; -import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.base.entity.*; +import org.cpte.modules.base.mapper.AreaMapper; import org.cpte.modules.base.mapper.ItemKeyMapper; +import org.cpte.modules.base.service.IItemKeyService; import org.cpte.modules.base.service.IItemService; import org.cpte.modules.base.service.IPointService; import org.cpte.modules.base.service.IStockService; +import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.constant.enums.*; +import org.cpte.modules.conveyorLine.service.processor.ScanTrayProcessor; import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.inventoryLog.service.IInventoryLogService; +import org.cpte.modules.serialNumber.MoveSerialNumberRule; import org.cpte.modules.shipping.entity.Pick; import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.PickDetailMapper; +import org.cpte.modules.shipping.service.IPickDetailService; +import org.cpte.modules.shipping.service.ITaskService; import org.cpte.modules.shipping.vo.AllocationData; import org.cpte.modules.shipping.vo.InventoryScore; import org.cpte.modules.shipping.vo.ItemGroupKey; @@ -28,6 +32,7 @@ import org.cpte.modules.utils.RedisDistributedLockUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -39,6 +44,9 @@ import java.util.stream.Collectors; @Slf4j public class AllocateProcessor { + @Autowired + private AreaMapper areaMapper; + @Autowired private PickDetailMapper pickDetailMapper; @@ -57,6 +65,9 @@ public class AllocateProcessor { @Autowired private IPointService pointService; + @Autowired + private IItemKeyService itemKeyService; + @Autowired private IPickDetailService pickDetailService; @@ -66,12 +77,19 @@ public class AllocateProcessor { @Autowired private IInventoryLogService inventoryLogService; + @Autowired + private ScanTrayProcessor scanTrayProcessor; + + @Autowired + private MoveSerialNumberRule moveSerialNumberRule; + @Autowired private BatchUtil batchUtil; @Autowired private RedisDistributedLockUtil redissonLock; + /** * 分配出库单 * @@ -94,14 +112,18 @@ public class AllocateProcessor { Map inventoryUpdateMap = new HashMap<>(); Map pickDetailUpdateMap = new HashMap<>(); List createToTask = new ArrayList<>(); + List movePoints = new ArrayList<>(); //4.分配 - allocate(data, inventoryUpdateMap, pickDetailUpdateMap, createToTask, errorMsgSet); + allocate(data, inventoryUpdateMap, pickDetailUpdateMap, createToTask, movePoints, errorMsgSet); - //5.批量操作 + //5.生成移位任务 + moveTask(createToTask, movePoints); + + //6.批量操作 batchOperation(inventoryUpdateMap, pickDetailUpdateMap, createToTask); - //6.刷新出库单 + //7.刷新出库单 refreshData(data); return new ArrayList<>(errorMsgSet); @@ -199,13 +221,12 @@ public class AllocateProcessor { /** * 分配 */ - private void allocate(AllocationData data, Map inventoryUpdateMap, Map pickDetailUpdateMap, List createToTask, Set errorMsgSet) { + private void allocate(AllocationData data, Map inventoryUpdateMap, Map pickDetailUpdateMap, List createToTask, List movePoints, Set errorMsgSet) { for (PickDetail pickDetail : data.getPickDetails()) { try { - allocatePickDetail(pickDetail, data, errorMsgSet, inventoryUpdateMap, pickDetailUpdateMap, createToTask); + allocatePickDetail(pickDetail, data, errorMsgSet, inventoryUpdateMap, pickDetailUpdateMap, createToTask, movePoints); } catch (Exception e) { - log.error("分配明细失败,明细ID: {}", pickDetail.getId(), e); - errorMsgSet.add(String.format("分配明细失败,明细ID:%s,原因:%s", + errorMsgSet.add(String.format("分配异常,明细ID:%s,原因:%s", pickDetail.getId(), e.getMessage())); } } @@ -223,7 +244,7 @@ public class AllocateProcessor { */ private void allocatePickDetail(PickDetail pickDetail, AllocationData data, Set errorMsgSet, Map inventoryUpdateMap, - Map pickDetailUpdateMap, List createToTask) { + Map pickDetailUpdateMap, List createToTask, List movePoints) { Pick pick = data.getPickMap().get(pickDetail.getPickId()); Item item = data.getItemMap().get(pickDetail.getItemId()); @@ -239,21 +260,23 @@ public class AllocateProcessor { return; } - String lockKey = String.valueOf(pickDetail.getId()); + // 分配库存 + String lockKey = "allocate:" + pickDetail.getId(); String lockValue = null; try { lockValue = redissonLock.tryLock(lockKey, 10); if (StringUtils.isEmpty(lockValue)) { - return; + throw new RuntimeException("分配处理中,请稍后重试"); } - // 分配库存 allocateInventory(pickDetail, item, pick, matchedInventories, inventoryUpdateMap, pickDetailUpdateMap, - createToTask, data, unAllocatedQty, errorMsgSet); + createToTask, movePoints, data, unAllocatedQty, errorMsgSet); + } catch (Exception e) { + log.error("分配异常,明细ID: {}", pickDetail.getId(), e); + throw e; } finally { if (StringUtils.isNotEmpty(lockValue)) { redissonLock.unlock(lockKey, lockValue); } - } @@ -314,13 +337,12 @@ public class AllocateProcessor { */ private void allocateInventory(PickDetail pickDetail, Item item, Pick pick, List matchedInventories, Map inventoryUpdateMap, - Map pickDetailUpdateMap, List createToTask, + Map pickDetailUpdateMap, List createToTask, List movePoints, AllocationData data, BigDecimal totalUnAllocatedQty, Set errorMsgSet) { // 智能排序库存 List scoredInventories = scoreInventories(matchedInventories); //未分配数量 BigDecimal remainingQty = totalUnAllocatedQty; - String requestId = UUID.randomUUID().toString(); for (InventoryScore inventoryScore : scoredInventories) { if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) { break; @@ -342,6 +364,9 @@ public class AllocateProcessor { // 创建任务 createPickTask(pickDetail, pick, item, inventory, inventoryScore, allocateQty, createToTask, data); + // 获取需要移位的库位 + getMovePoints(inventoryScore, movePoints); + // 记录分配日志 inventoryLogService.addAllocInventoryLog(inventory, inventoryScore.getOutPoint().getId(), allocateQty, pick.getOrderNo(), pickDetail.getId(), pickDetail.getDescription()); @@ -500,31 +525,11 @@ public class AllocateProcessor { */ private void updateInventoryAllocation(Inventory inventory, BigDecimal allocateQty, Map inventoryUpdateMap) { - - Inventory inventoryToUpdate = inventoryUpdateMap.computeIfAbsent( - inventory.getId(), id -> { - // 2. 用Builder实现拷贝 - return Inventory.builder() - .id(inventory.getId()) - .itemId(inventory.getItemId()) - .itemKeyId(inventory.getItemKeyId()) - .pointId(inventory.getPointId()) - .stockId(inventory.getStockId()) - .quantity(inventory.getQuantity()) - .queuedQty(BigDecimal.ZERO) - .receiveRecordId(inventory.getReceiveRecordId()) - .status(inventory.getStatus()) - .description(inventory.getDescription()) - .sysOrgCode(inventory.getSysOrgCode()) - .tenantId(inventory.getTenantId()) - .createBy(inventory.getCreateBy()) - .createTime(inventory.getCreateTime()) - .build(); - }); - - BigDecimal newQueuedQty = BigDecimalUtil.add(inventoryToUpdate.getQueuedQty(), allocateQty, 0); - inventoryToUpdate.setQueuedQty(newQueuedQty); - inventoryToUpdate.setStatus(InventoryStatusEnum.ALLOCATED.getValue()); + Inventory targetInventory = inventoryUpdateMap.getOrDefault(inventory.getId(), inventory); + BigDecimal newQueuedQty = BigDecimalUtil.add(targetInventory.getQueuedQty(), allocateQty, 0); + targetInventory.setQueuedQty(newQueuedQty); + targetInventory.setStatus(InventoryStatusEnum.ALLOCATED.getValue()); + inventoryUpdateMap.put(targetInventory.getId(), targetInventory); } /** @@ -536,8 +541,15 @@ public class AllocateProcessor { */ private void updatePickDetailAllocation(PickDetail pickDetail, BigDecimal allocateQty, Map pickDetailUpdateMap) { + PickDetail targetPickDetail = pickDetailUpdateMap.getOrDefault(pickDetail.getId(), pickDetail); + BigDecimal newAllocatedQty = BigDecimalUtil.add(targetPickDetail.getAllocatedQty(), allocateQty, 0); + Integer status = newAllocatedQty.compareTo(targetPickDetail.getOrderQty()) >= 0 ? + PickStatusEnum.ASSIGNED.getValue() : PickStatusEnum.PARTIAL.getValue(); + targetPickDetail.setAllocatedQty(newAllocatedQty); + targetPickDetail.setStatus(status); + pickDetailUpdateMap.put(targetPickDetail.getId(), targetPickDetail); - PickDetail detailToUpdate = pickDetailUpdateMap.computeIfAbsent( +/* PickDetail detailToUpdate = pickDetailUpdateMap.computeIfAbsent( pickDetail.getId(), id -> { // 2. 用Builder实现拷贝 return PickDetail.builder() @@ -568,7 +580,7 @@ public class AllocateProcessor { // 更新状态 Integer status = newAllocatedQty.compareTo(detailToUpdate.getOrderQty()) >= 0 ? PickStatusEnum.ASSIGNED.getValue() : PickStatusEnum.PARTIAL.getValue(); - detailToUpdate.setStatus(status); + detailToUpdate.setStatus(status);*/ } /** @@ -611,6 +623,7 @@ public class AllocateProcessor { task.getTaskNo(), stock.getStockCode(), fromPoint.getPointCode(), izAll, allocateQty); } + } /** @@ -637,6 +650,105 @@ public class AllocateProcessor { errorMsgSet.add(failInfo); } + /** + * 获取移位库位 + * + * @param inventoryScore 库位评分 + * @param movePoints 移位库位 + */ + private void getMovePoints(InventoryScore inventoryScore, List movePoints) { + if (CollectionUtils.isNotEmpty(inventoryScore.getMovePoints())) { + for (Point movePoint : inventoryScore.getMovePoints()) { + if (!movePoints.contains(movePoint)) { + movePoints.add(movePoint); + } + } + } else { + log.info("无移位库位"); + } + } + + /** + * 移位任务 + * + * @param createToTask 创建的出库任务 + * @param movePoints 移位库位 + */ + void moveTask(List createToTask, List movePoints) { + + if (CollectionUtils.isNotEmpty(movePoints)) { + Set createTaskIds = createToTask.stream() + .map(Task::getFromPointId) + .collect(Collectors.toSet()); + List pointsToMove = movePoints.stream() + .filter(point -> !createTaskIds.contains(point.getId())) + .toList(); + if (CollectionUtils.isNotEmpty(pointsToMove)) { + List moveToTask = bulidMoveTask(pointsToMove); + if (CollectionUtils.isNotEmpty(moveToTask)) { + createToTask.addAll(moveToTask); + } + } + + } + } + + /** + * 创建移位任务 + * + * @param movePoints 移位库位 + * @return 移位任务 + */ + public List bulidMoveTask(List movePoints) { + List moveList = new ArrayList<>(); + + //库存 + List pointIds = movePoints.stream().map(Point::getId).toList(); + List moveInventoryList = inventoryMapper.queryByPointIds(pointIds); + + //物料 + List itemIds = moveInventoryList.stream().map(Inventory::getItemId).distinct().toList(); + Map moveItemMap = itemService.queryByItemIdsToMap(itemIds); + + //物料属性 + List itemKeyIds = moveInventoryList.stream().map(Inventory::getItemKeyId).distinct().toList(); + Map itemKeyMap = itemKeyService.queryByIdsToMap(itemKeyIds); + + //库位 + Map fromPointMap = movePoints.stream().collect(Collectors.toMap(Point::getId, point -> point)); + + //容器 + List stockIds = moveInventoryList.stream().map(Inventory::getStockId).distinct().toList(); + Map stockMap = stockService.queryByStockIdsToMap(stockIds); + + for (Inventory inv : moveInventoryList) { + Item moveItem = moveItemMap.get(inv.getItemId()); + Point fromPoint = fromPointMap.get(inv.getPointId()); + Stock stock = stockMap.get(inv.getStockId()); + String taskNo = moveSerialNumberRule.generateSerialNumber(GeneralConstant.MOVE_ORDER_NO); + //根据算法找到最优的目标库位 + Point toPoint = allocatePoint(fromPoint, itemKeyMap.get(inv.getItemKeyId())); + Task moveTask = taskService.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null, inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0); + moveList.add(moveTask); + log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity()); + } + return moveList; + } + + /** + * 智能分配移位库位 + * + * @param currentPoint 当前库位 + * @return 目标库位 + */ + private Point allocatePoint(Point currentPoint, ItemKey itemKey) { + Area area = areaMapper.selectById(currentPoint.getAreaId()); + String areaCode = area.getAreaCode(); + List itemKeyIds = Collections.singletonList(itemKey); + return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode); + } + + /** * 批量操作 * diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/CancelAllocateProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/CancelAllocateProcessor.java similarity index 99% rename from cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/CancelAllocateProcessor.java rename to cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/CancelAllocateProcessor.java index baeb29f..2e8daee 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/CancelAllocateProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/CancelAllocateProcessor.java @@ -1,4 +1,4 @@ -package org.cpte.modules.shipping.service; +package org.cpte.modules.shipping.service.processor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -12,6 +12,7 @@ import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.PickDetailMapper; import org.cpte.modules.shipping.mapper.TaskMapper; +import org.cpte.modules.shipping.service.IPickDetailService; import org.cpte.modules.shipping.vo.CancelAllocateData; import org.cpte.modules.utils.BatchUtil; import org.cpte.modules.utils.BigDecimalUtil; @@ -196,7 +197,6 @@ public class CancelAllocateProcessor { .stockId(inventory.getStockId()) .quantity(inventory.getQuantity()) .queuedQty(inventory.getQueuedQty()) - .receiveRecordId(inventory.getReceiveRecordId()) .status(inventory.getStatus()) .description(inventory.getDescription()) .sysOrgCode(inventory.getSysOrgCode()) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java new file mode 100644 index 0000000..92ec6dc --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java @@ -0,0 +1,197 @@ +package org.cpte.modules.shipping.service.processor; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.cpte.modules.constant.GeneralConstant; +import org.cpte.modules.constant.enums.PickStatusEnum; +import org.cpte.modules.constant.enums.TaskStatusEnum; +import org.cpte.modules.saiWms.request.SMOMRequest; +import org.cpte.modules.shipping.entity.Pick; +import org.cpte.modules.shipping.entity.PickDetail; +import org.cpte.modules.shipping.entity.Task; +import org.cpte.modules.shipping.mapper.PickDetailMapper; +import org.cpte.modules.shipping.mapper.TaskMapper; +import org.cpte.modules.shipping.vo.PickData; +import org.cpte.modules.utils.SwmsLoginUtil; +import org.jeecg.modules.openapi.mapper.OpenApiMapper; +import org.jeecg.modules.system.mapper.SysDictMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 出库回传 + */ +@Service +@Slf4j +public class PickBackProcessor { + + @Autowired + private PickDetailMapper pickDetailMapper; + + @Autowired + private TaskMapper taskMapper; + + @Autowired + private OpenApiMapper openApiMapper; + + @Autowired + private SysDictMapper sysDictMapper; + + @Autowired + private SwmsLoginUtil swmsLoginUtil; + + + /** + * 出库库任务回传JSON + */ + private String pickTaskCallbackJson(Pick pick, PickDetail pickDetail, Task task, Integer state, String ticket) { + SMOMRequest.Task taskReq = new SMOMRequest.Task(); + taskReq.setNo(pick.getNo()); + taskReq.setOrderNo(pick.getThirdOrderNo()); + taskReq.setState(state); + + SMOMRequest.ShipmentFeedbackDetail shipmentFeedbackDetail = new SMOMRequest.ShipmentFeedbackDetail(); + shipmentFeedbackDetail.setLineNo(String.valueOf(pickDetail.getLineNo())); + shipmentFeedbackDetail.setLpn(task.getStockCode()); + shipmentFeedbackDetail.setQty(task.getPlanQty().intValue()); + shipmentFeedbackDetail.setIsTakeDown(task.getIzAll() == 0); + shipmentFeedbackDetail.setProject(pickDetail.getProject()); + shipmentFeedbackDetail.setTaskNo(pickDetail.getTaskNo()); + shipmentFeedbackDetail.setLotAtt04(pickDetail.getPropC1()); + shipmentFeedbackDetail.setLotAtt010(pickDetail.getPropC3()); + shipmentFeedbackDetail.setErpKey(pick.getNo()); + shipmentFeedbackDetail.setIsDelete(false); + String lastUpdateDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + shipmentFeedbackDetail.setLastUpdateDate(lastUpdateDate); + taskReq.setShipmentFeedbackDetails(List.of(shipmentFeedbackDetail)); + + taskReq.setErpKey(pick.getNo()); + taskReq.setInfkey(pick.getNo()); + taskReq.setIsDelete(false); + taskReq.setLastUpdateDate(lastUpdateDate); + + + SMOMRequest.ParameterValue1 parameterValue1 = new SMOMRequest.ParameterValue1(); + parameterValue1.setValue(List.of(taskReq)); + + SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); + parameterValue2.setValue(1); + + SMOMRequest.Context context = new SMOMRequest.Context(); + context.setInvOrgId(1); + context.setTicket(ticket); + + SMOMRequest saiWmsRequest = new SMOMRequest(); + saiWmsRequest.setApiType("SmomWebApiController"); + saiWmsRequest.setParameters(List.of(parameterValue1, parameterValue2)); + saiWmsRequest.setMethod("OutboundTaskCallbackInterface"); + saiWmsRequest.setContext(context); + + return JSON.toJSONString(saiWmsRequest); + } + + /** + * 出库任务回传 + * + * @param data 数据 + * @param tasks 任务 + */ + public void pickBack(PickData data, List tasks) { + Map> pickDetailsCache = new HashMap<>(); + for (Task task : tasks) { + Pick pick = data.getPickMap().get(task.getPickId()); + PickDetail pickDetail = data.getPickDetailMap().get(task.getPickDetailId()); + Long pickId = pick.getId(); + try { + // 缓存查询结果,避免重复查询 + List pickDetails = pickDetailsCache.computeIfAbsent(pickId, id -> pickDetailMapper.selectByMainId(id)); + + //已关闭的出库单 + List closedPickDetails = pickDetails.stream().filter(detail -> PickStatusEnum.CLOSED.getValue().equals(detail.getStatus())).toList(); + + int state = pickDetails.size() - closedPickDetails.size() == 1 ? 5 : 7; + + pickBackProcessor(pick, pickDetail, task, state); + } catch (Exception e) { + log.error("出库任务回传失败,任务ID: {}, 错误信息: {}", task.getId(), e.getMessage(), e); + } + List latestPickDetails = pickDetailMapper.selectByMainId(pickId); + pickDetailsCache.put(pickId, latestPickDetails); // 更新缓存 + } + } + + private void pickBackProcessor(Pick pick, PickDetail pickDetail, Task task, Integer state) { + // 检查接口开关, 未开启则返回 + if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) { + updatePickDetailResponse(pickDetail, task, GeneralConstant.SMOM_FAIL_CODE, "接口未开启"); + return; + } + + if (TaskStatusEnum.CLOSED.getValue().equals(task.getTaskStatus())) { + return; + } + + try { + Map authInfo = swmsLoginUtil.Login(); + if (authInfo == null || authInfo.isEmpty()) { + throw new RuntimeException("登录认证信息为空"); + } + + String ticket = authInfo.get("Ticket"); + String authorization = authInfo.get("authorization"); + String json = pickTaskCallbackJson(pick, pickDetail, task, state, ticket); + String url = openApiMapper.getRequestUrl(GeneralConstant.OUTBOUND_CALLBACK).getOriginUrl(); + JSONObject jsonObject = swmsLoginUtil.sendSMOMResponse(json, url, authorization); + String code = validateResponse(jsonObject); + updatePickDetailResponse(pickDetail, task, code, jsonObject.toJSONString()); + } catch (Exception e) { + updatePickDetailResponse(pickDetail, task, GeneralConstant.SMOM_FAIL_CODE, e.getMessage()); + } + } + + /** + * 验证响应数据 + * + * @param jsonObject 响应数据 + * @return 状态码 + */ + private String validateResponse(JSONObject jsonObject) { + JSONObject data = jsonObject.getJSONObject("data"); + if (data == null) { + throw new RuntimeException("数据格式错误:缺少data字段"); + } + JSONObject Result = data.getJSONObject("Result"); + if (Result == null) { + throw new RuntimeException("数据格式错误:缺少Result字段"); + } + JSONArray jsonArray = Result.getJSONArray("ErpErrorDatas"); + return jsonArray.isEmpty() ? GeneralConstant.SMOM_SUCCESS_CODE : GeneralConstant.SMOM_FAIL_CODE; + } + + /** + * 更新任务状态 + * + * @param task 出库任务 + * @param message 信息 + */ + private void updatePickDetailResponse(PickDetail pickDetail, Task task, String code, String message) { + if (GeneralConstant.SMOM_SUCCESS_CODE.equals(code)) { + if (PickStatusEnum.PICKED.getValue().equals(pickDetail.getStatus())) { + pickDetail.setStatus(PickStatusEnum.CLOSED.getValue()); + pickDetailMapper.updateById(pickDetail); + } + task.setTaskStatus(TaskStatusEnum.CLOSED.getValue()); + } + task.setResMessage(message); + task.setResTime(new Date()); + taskMapper.updateById(task); + } +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickProcessor.java new file mode 100644 index 0000000..baca892 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickProcessor.java @@ -0,0 +1,345 @@ +package org.cpte.modules.shipping.service.processor; + +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.base.service.IStockService; +import org.cpte.modules.constant.enums.CommonStatusEnum; +import org.cpte.modules.constant.enums.PickStatusEnum; +import org.cpte.modules.constant.enums.TaskStatusEnum; +import org.cpte.modules.inventory.entity.Inventory; +import org.cpte.modules.inventory.service.IInventoryService; +import org.cpte.modules.inventoryLog.service.IInventoryLogService; +import org.cpte.modules.shipping.entity.Pick; +import org.cpte.modules.shipping.entity.PickDetail; +import org.cpte.modules.shipping.entity.Task; +import org.cpte.modules.shipping.mapper.PickDetailMapper; +import org.cpte.modules.shipping.service.IPickDetailService; +import org.cpte.modules.shipping.vo.PickData; +import org.cpte.modules.utils.BatchUtil; +import org.cpte.modules.utils.BigDecimalUtil; +import org.cpte.modules.utils.RedisDistributedLockUtil; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 拣货处理 + */ +@Service +@Slf4j +public class PickProcessor { + + @Autowired + private PickDetailMapper pickDetailMapper; + + @Autowired + private IStockService stockService; + + @Autowired + private IPickDetailService pickDetailService; + + @Autowired + private IInventoryService inventoryService; + + @Autowired + private IInventoryLogService inventoryLogService; + + @Autowired + private BaseCommonService baseCommonService; + + @Autowired + private BatchUtil batchUtil; + + @Autowired + private PickBackProcessor pickBackProcessor; + + @Autowired + private RedisDistributedLockUtil redissonLock; + + /** + * 拣货 + * + * @param tasks 任务 + */ + public void pick(List tasks) { + // 1.数据准备 + PickData data = preparePickData(tasks); + + //2.创建数据结构 + List deleteToInventory = new ArrayList<>(); + Map pickDetailUpdateMap = new HashMap<>(); + List updateToTask = new ArrayList<>(); + List updateToStock = new ArrayList<>(); + + //3.拣货 + pickTask(data, pickDetailUpdateMap, updateToTask, deleteToInventory, updateToStock); + + //4.批量操作 + batchOperation(deleteToInventory, pickDetailUpdateMap, updateToTask, updateToStock); + + //5.刷新出库单 + refreshData(data); + + //6.回传 + pickBackProcessor.pickBack(data, updateToTask); + } + + /** + * 数据准备 + * + * @param tasks 任务 + * @return PickData + */ + private PickData preparePickData(List tasks) { + PickData data = new PickData(); + data.setTasks(tasks); + + //查询出库单 + List pickIds = tasks.stream().map(Task::getPickId).distinct().toList(); + Map pickMap = pickDetailService.queryByPickIdsToMap(pickIds); + data.setPickMap(pickMap); + + //查询出库单明细 + List pickDetailIds = tasks.stream().map(Task::getPickDetailId).distinct().toList(); + Map pickDetailMap = pickDetailService.queryByPickDetailIdsToMap(pickDetailIds); + data.setPickDetailMap(pickDetailMap); + + //查询库存 + List inventoryIds = tasks.stream().map(Task::getInventoryId).distinct().toList(); + Map inventoryMap = inventoryService.queryByInventoryIdsToMap(inventoryIds); + data.setInventoryMap(inventoryMap); + + //库存容器 + List stockIds = inventoryMap.values().stream().map(Inventory::getStockId).distinct().toList(); + Map stockMap = stockService.queryByStockIdsToMap(stockIds); + data.setStockMap(stockMap); + return data; + } + + /** + * 拣货 + * + * @param data 数据 + */ + private void pickTask(PickData data, Map pickDetailUpdateMap, List updateToTask, List deleteToInventory, List updateToStock) { + for (Task task : data.getTasks()) { + try { + processorTaskLock(data, task, pickDetailUpdateMap, updateToTask, deleteToInventory, updateToStock); + } catch (Exception e) { + log.error("拣货异常", e); + //记录拣货异常日志 + baseCommonService.addLog("出库任务拣货:" + "\n" + task.getTaskNo() + e, CommonConstant.LOG_TYPE_4, CommonConstant.OPERATE_TYPE_4); + } + } + } + + /** + * 处理任务 + * + * @param data 数据 + * @param task 任务 + * @param pickDetailUpdateMap 拣货明细更新集合 + * @param updateToTask 更新任务集合 + * @param deleteToInventory 删除库存集合 + * @param updateToStock 更新容器状态集合 + */ + private void processorTaskLock(PickData data, Task task, Map pickDetailUpdateMap, List updateToTask, List deleteToInventory, List updateToStock) { + // 拣货处理 + String lockKey = "task:" + task.getId(); + String lockValue = null; + try { + lockValue = redissonLock.tryLock(lockKey, 10); + if (StringUtils.isEmpty(lockValue)) { + throw new RuntimeException("拣货处理中,请稍后重试"); + } + processorTask(data, task, pickDetailUpdateMap, updateToTask, deleteToInventory, updateToStock); + } catch (Exception e) { + log.error("拣货异常", e); + throw e; + } finally { + if (StringUtils.isNotEmpty(lockValue)) { + redissonLock.unlock(lockKey, lockValue); + } + } + } + + + /** + * 处理任务 + * + * @param data 数据 + * @param task 任务 + * @param pickDetailUpdateMap 拣货明细更新集合 + * @param updateToTask 更新任务集合 + * @param deleteToInventory 删除库存集合 + * @param updateToStock 更新容器状态集合 + */ + private void processorTask(PickData data, Task task, Map pickDetailUpdateMap, List updateToTask, List deleteToInventory, List updateToStock) { + + BigDecimal pickedQty = BigDecimalUtil.subtract(task.getPlanQty(), task.getMoveQty(), 0); + if (pickedQty.compareTo(BigDecimal.ZERO) <= 0) { + return; + } + + //扣减库存 + /*Inventory inventory = data.getInventoryMap().get(task.getInventoryId()); + updateInventory(inventory, pickedQty,inventoryUpdateMap);*/ + + // 更新拣货数量,状态 + updatePickDetail(data, task, pickedQty, pickDetailUpdateMap); + + //更新task + updateTask(task, pickedQty, updateToTask); + + //删除库存 + deleteInventory(data, task, deleteToInventory); + + //更新容器状态 + updateToStock(data, task, updateToStock); + + //添加库存日志 + addInventoryLog(data, task, pickedQty); + } + + /** + * 更新库存 + * + * @param inventory 库存 + * @param pickedQty 拣货数量 + * @param inventoryUpdateMap 库更新集合 + */ + private void updateInventory(Inventory inventory, BigDecimal pickedQty, + Map inventoryUpdateMap) { + Inventory targetInventory = inventoryUpdateMap.getOrDefault(inventory.getId(), inventory); + BigDecimal quantity = BigDecimalUtil.subtract(targetInventory.getQuantity(), pickedQty, 0); + BigDecimal queuedQty = BigDecimalUtil.subtract(targetInventory.getQueuedQty(), pickedQty, 0); + targetInventory.setQuantity(quantity); + targetInventory.setQueuedQty(queuedQty); + inventoryUpdateMap.put(targetInventory.getId(), targetInventory); + } + + /** + * 删除库存 + * + * @param data 数据 + * @param deleteToInventory 删除集合 + */ + private void deleteInventory(PickData data, Task task, List deleteToInventory) { + Inventory inventory = data.getInventoryMap().get(task.getInventoryId()); + if (!deleteToInventory.contains(inventory)) { + deleteToInventory.add(inventory); + } + } + + /** + * 更新出库明细 + * + * @param data 数据 + * @param pickedQty 拣货数量 + * @param pickDetailUpdateMap 拣货明细更新集合 + */ + private void updatePickDetail(PickData data, Task task, BigDecimal pickedQty, + Map pickDetailUpdateMap) { + //出库明细 + PickDetail pickDetail = data.getPickDetailMap().get(task.getPickDetailId()); + //获取map最新的出库明细 + PickDetail targetPickDetail = pickDetailUpdateMap.getOrDefault(pickDetail.getId(), pickDetail); + //拣货数量 + BigDecimal newPickedQty = BigDecimalUtil.add(targetPickDetail.getPickedQty(), pickedQty, 0); + //状态 + Integer status = newPickedQty.compareTo(targetPickDetail.getOrderQty()) >= 0 ? PickStatusEnum.PICKED.getValue() : PickStatusEnum.PICKING.getValue(); + targetPickDetail.setPickedQty(newPickedQty); + targetPickDetail.setStatus(status); + pickDetailUpdateMap.put(targetPickDetail.getId(), targetPickDetail); + } + + /** + * 更新出库明细 + * + * @param task 出库任务 + * @param pickedQty 拣货数量 + * @param updateToTask 拣货明细更新集合 + */ + private void updateTask(Task task, BigDecimal pickedQty, List updateToTask) { + // 更新任务 + task.setMoveQty(pickedQty); + task.setTaskStatus(TaskStatusEnum.COMPLETED.getValue()); + updateToTask.add(task); + } + + /** + * 更新容器状态 + * + * @param data 数据 + * @param updateToStock 容器更新集合 + */ + private void updateToStock(PickData data, Task task, List updateToStock) { + Stock stock = data.getStockMap().get(task.getStockId()); + if (!updateToStock.contains(stock)) { + stock.setPointId(null); + stock.setStatus(CommonStatusEnum.FREE.getValue()); + updateToStock.add(stock); + } + } + + /** + * 添加库存日志 + * + * @param data 数据 + * @param task 任务 + * @param pickedQty 拣货数量 + */ + private void addInventoryLog(PickData data, Task task, BigDecimal pickedQty) { + Inventory inventory = data.getInventoryMap().get(task.getInventoryId()); + Pick pick = data.getPickMap().get(task.getPickId()); + inventoryLogService.addPickInventoryLog(inventory, task.getToPointId(), pickedQty, pick.getOrderNo(), task.getId(), null); + } + + /** + * 批量操作 + * + * @param deleteToInventory 删除库存 + * @param pickDetailUpdateMap 更新出库明细 + * @param updateToTask 创建出库任务 + */ + @Transactional(rollbackFor = Exception.class) + public void batchOperation(List deleteToInventory, Map pickDetailUpdateMap, List updateToTask, List updateToStock) { + if (CollectionUtils.isNotEmpty(deleteToInventory)) { + List deleteToInventoryIds = deleteToInventory.stream().map(Inventory::getId).toList(); + inventoryService.removeByIds(deleteToInventoryIds); + } + List updateToPickDetail = new ArrayList<>(pickDetailUpdateMap.values()); + if (CollectionUtils.isNotEmpty(updateToPickDetail)) { + batchUtil.updateBatchPickDetail(updateToPickDetail); + } + if (CollectionUtils.isNotEmpty(updateToTask)) { + batchUtil.updateBatchTask(updateToTask); + } + if (CollectionUtils.isNotEmpty(updateToStock)) { + stockService.updateBatchById(updateToStock); + } + } + + /** + * 刷新出库单 + * + * @param data 数据 + */ + private void refreshData(PickData data) { + for (Map.Entry entry : data.getPickMap().entrySet()) { + pickDetailService.refreshPick(entry.getValue(), pickDetailMapper.selectByMainId(entry.getKey())); + } + } + +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/PickData.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/PickData.java new file mode 100644 index 0000000..2932782 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/vo/PickData.java @@ -0,0 +1,20 @@ +package org.cpte.modules.shipping.vo; + +import lombok.Data; +import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.inventory.entity.Inventory; +import org.cpte.modules.shipping.entity.Pick; +import org.cpte.modules.shipping.entity.PickDetail; +import org.cpte.modules.shipping.entity.Task; + +import java.util.List; +import java.util.Map; + +@Data +public class PickData { + private List tasks; + private Map stockMap; + private Map pickMap; + private Map pickDetailMap; + private Map inventoryMap; +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java index ec946ea..453ea26 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java @@ -48,12 +48,6 @@ public class ITesAgvServiceImpl implements ITesAgvService { @Autowired private OpenApiMapper openApiMapper; - @Autowired - private IPointService pointService; - - @Autowired - private IStockService stockService; - @Autowired private IAsnService asnService; @@ -232,10 +226,9 @@ public class ITesAgvServiceImpl implements ITesAgvService { asnService.receiveAsn(asnId, agvTask.getEndCode()); } else if (BusinessTypeEnum.OUTBOUND.getValue().equals(agvTask.getType())) { //拣货 - Point endPoint = pointService.validatePoint(agvTask.getEndCode()); List tasks = taskMapper.queryByAgvTask(agvTask.getId()); - pickService.pickTask(tasks, endPoint); - Point startPoint = pointService.validatePoint(agvTask.getStartCode()); + pickService.pickTask(tasks); + /* Point startPoint = pointService.validatePoint(agvTask.getStartCode()); Stock stock = stockService.validateStock(agvTask.getCarrierCode()); pointService.unbindPoint(startPoint); @@ -246,7 +239,7 @@ public class ITesAgvServiceImpl implements ITesAgvService { //查询电梯口点位作为目标点位 String endCode = pointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX); agvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue()); - } + }*/ } agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue()); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java index dd3c439..a29578f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java @@ -1,6 +1,5 @@ package org.cpte.modules.utils; -import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.cpte.modules.agvTask.entity.AgvTask; import org.cpte.modules.base.entity.Item; import org.cpte.modules.base.entity.Point; @@ -15,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.sql.Date; @@ -86,7 +84,7 @@ public class BatchUtil { String sql = "INSERT INTO base_item (id,item_code,item_name,unit,iz_active, del_flag,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, items, (ps, item) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, item.getId()); ps.setString(2, item.getItemCode()); ps.setString(3, item.getItemName()); ps.setString(4, item.getUnit()); @@ -130,7 +128,7 @@ public class BatchUtil { String sql = "INSERT INTO base_point (id,area_id, point_code,status,row_num,col_num,layer_num,description,iz_active,del_flag,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, points, (ps, point) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, point.getId()); ps.setLong(2, point.getAreaId()); ps.setString(3, point.getPointCode()); ps.setInt(4, point.getStatus()); @@ -183,7 +181,7 @@ public class BatchUtil { String sql = "INSERT INTO base_stock (id,stock_code, stock_type, status, del_flag, iz_active,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, stocks, (ps, stock) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, stock.getId()); ps.setString(2, stock.getStockCode()); ps.setString(3, stock.getStockType()); ps.setInt(4, stock.getStatus()); @@ -259,23 +257,24 @@ public class BatchUtil { */ @Transactional public void saveBatchReceiveRecord(List receiveRecords) { - String sql = "INSERT INTO data_receive_record (id,asn_detail_id,stock_id,from_point_id,to_point_id, item_id,item_key_id,received_qty,description,sys_org_code,tenant_id,create_by,create_time) " + - "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + String sql = "INSERT INTO data_receive_record (id,asn_id,asn_detail_id,stock_id,from_point_id,to_point_id, item_id,item_key_id,received_qty,description,sys_org_code,tenant_id,create_by,create_time) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, receiveRecords, (ps, record) -> { try { ps.setLong(1, record.getId()); - ps.setLong(2, record.getAsnDetailId()); - ps.setLong(3, record.getStockId()); - ps.setLong(4, record.getFromPointId()); - ps.setLong(5, record.getToPointId()); - ps.setLong(6, record.getItemId()); - ps.setLong(7, record.getItemKeyId()); - ps.setBigDecimal(8, record.getReceivedQty()); - ps.setString(9, record.getDescription()); - ps.setString(10, record.getSysOrgCode()); - ps.setLong(11, record.getTenantId()); - ps.setString(12, record.getCreateBy()); - ps.setDate(13, new Date(record.getCreateTime().getTime())); + ps.setLong(2, record.getAsnId()); + ps.setLong(3, record.getAsnDetailId()); + ps.setLong(4, record.getStockId()); + ps.setLong(5, record.getFromPointId()); + ps.setLong(6, record.getToPointId()); + ps.setLong(7, record.getItemId()); + ps.setLong(8, record.getItemKeyId()); + ps.setBigDecimal(9, record.getReceivedQty()); + ps.setString(10, record.getDescription()); + ps.setString(11, record.getSysOrgCode()); + ps.setLong(12, record.getTenantId()); + ps.setString(13, record.getCreateBy()); + ps.setDate(14, new Date(record.getCreateTime().getTime())); } catch (SQLException e) { throw new RuntimeException(e); } @@ -291,7 +290,7 @@ public class BatchUtil { "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, tasks, (ps, task) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, task.getId()); ps.setString(2, task.getTaskNo()); ps.setLong(3, task.getItemId()); ps.setString(4, task.getItemCode()); @@ -348,9 +347,7 @@ public class BatchUtil { "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, agvTasks, (ps, agvTask) -> { try { - long id = IdWorker.getId(); - agvTask.setId(IdWorker.getId()); // 关键:将生成的ID赋值给对象,解决null问题 - ps.setLong(1, id); + ps.setLong(1, agvTask.getId()); ps.setObject(2, agvTask.getBusinessDetailId()); ps.setString(3, agvTask.getCarrierCode()); ps.setString(4, agvTask.getCarrierType()); @@ -377,7 +374,7 @@ public class BatchUtil { */ @Transactional public void saveBatchInventory(List inventories) { - String sql = "INSERT INTO data_inventory (id,item_key_id,item_id,point_id,stock_id,receive_record_id,quantity,queued_qty,status,description,sys_org_code,tenant_id,create_by,create_time) " + + String sql = "INSERT INTO data_inventory (id,item_key_id,item_id,point_id,stock_id,quantity,queued_qty,status,order_no,description,sys_org_code,tenant_id,create_by,create_time) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, inventories, (ps, inventory) -> { try { @@ -386,10 +383,10 @@ public class BatchUtil { ps.setLong(3, inventory.getItemId()); ps.setLong(4, inventory.getPointId()); ps.setLong(5, inventory.getStockId()); - ps.setObject(6, inventory.getReceiveRecordId()); - ps.setBigDecimal(7, inventory.getQuantity()); - ps.setBigDecimal(8, inventory.getQueuedQty()); - ps.setInt(9, inventory.getStatus()); + ps.setBigDecimal(6, inventory.getQuantity()); + ps.setBigDecimal(7, inventory.getQueuedQty()); + ps.setInt(8, inventory.getStatus()); + ps.setString(9, inventory.getOrderNo()); ps.setString(10, inventory.getDescription()); ps.setString(11, inventory.getSysOrgCode()); ps.setLong(12, inventory.getTenantId()); @@ -429,7 +426,7 @@ public class BatchUtil { "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, inventoryLogs, (ps, inventoryLog) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, inventoryLog.getId()); ps.setInt(2, inventoryLog.getLogType()); ps.setString(3, inventoryLog.getBusinessNo()); ps.setObject(4, inventoryLog.getBusinessDetailId()); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/test.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/test.java index 7ba5447..ce7d253 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/test.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/test.java @@ -4,6 +4,8 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class test { public static void main(String[] args) { @@ -29,8 +31,10 @@ public class test { System.out.println("======================================================================================="); System.out.println("agv-timestamp:" + timestamp); System.out.println("agv-signature:" + md5(agvMap.get("ak")+ agvMap.get("sk") + timestamp)); + } + public static String md5(String sourceStr) { String result = ""; try {