From 73b1247ebc691c94bd60d2207f73e7d3fab3b952 Mon Sep 17 00:00:00 2001 From: "HUOJIN\\92525" Date: Thu, 11 Dec 2025 14:17:31 +0800 Subject: [PATCH] no message --- .../java/org/jeecg/common/util/RestUtil.java | 4 +- .../org/cpte/modules/base/entity/Item.java | 17 +- .../modules/base/response/ItemResponse.java | 33 ++++ .../modules/base/service/IItemService.java | 20 +++ .../modules/base/service/IStockService.java | 9 + .../base/service/impl/ItemServiceImpl.java | 169 +++++++++++++++++- .../base/service/impl/StockServiceImpl.java | 32 +++- .../modules/constant/GeneralConstant.java | 18 +- .../service/impl/IHikAgvServiceImpl.java | 4 +- .../service/impl/InventoryServiceImpl.java | 2 + .../service/impl/InventoryLogServiceImpl.java | 1 + .../cpte/modules/quartz/job/AllocateJob.java | 2 - .../cpte/modules/quartz/job/SyncItemJob.java | 103 +++++++++++ .../cpte/modules/quartz/job/TesAgvJob.java | 4 +- .../receive/service/IAsnDetailService.java | 21 ++- .../modules/receive/service/IAsnService.java | 28 ++- .../service/impl/AsnDetailServiceImpl.java | 7 + .../receive/service/impl/AsnServiceImpl.java | 157 +++++++++++----- .../saiWms/request/SyncStockRequest.java | 4 +- .../service/impl/ISaiWmsServiceImpl.java | 158 +++------------- .../shipping/service/IPickService.java | 20 +++ .../service/impl/PickServiceImpl.java | 44 ++++- .../service/impl/ITesAgvServiceImpl.java | 4 +- .../org/cpte/modules/utils/BatchUtil.java | 60 ++++--- .../cpte/modules/utils/CodeGeneratorUtil.java | 2 +- .../org/cpte/modules/utils/HttpGetUtil.java | 75 ++++++++ .../org/cpte/modules/utils/HttpPostUtil.java | 9 +- .../org/cpte/modules/utils/SwmsLoginUtil.java | 117 +++++++++--- .../modules/openapi/mapper/OpenApiMapper.java | 6 +- 29 files changed, 841 insertions(+), 289 deletions(-) create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/response/ItemResponse.java create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/quartz/job/SyncItemJob.java create mode 100644 cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpGetUtil.java diff --git a/cpte-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java b/cpte-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java index 6e0b5ea..9331015 100644 --- a/cpte-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java +++ b/cpte-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java @@ -60,8 +60,8 @@ public class RestUtil { // 使用 Apache HttpClient 避免 JDK HttpURLConnection 的 too many bytes written 问题 HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); //update-end---author:chenrui ---date:20251011 for:[issues/8859]online表单java增强失效------------ - requestFactory.setConnectTimeout(30000); - requestFactory.setReadTimeout(30000); + requestFactory.setConnectTimeout(10000); + requestFactory.setReadTimeout(10000); RT = new RestTemplate(requestFactory); //update-begin---author:chenrui ---date:20251011 for:[issues/8859]online表单java增强失效------------ // 解决乱码问题(替换 StringHttpMessageConverter 为 UTF-8) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Item.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Item.java index 63c7de2..ca57356 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Item.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Item.java @@ -11,15 +11,14 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableLogic; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.*; import org.jeecg.common.constant.ProvinceCityArea; import org.jeecg.common.util.SpringContextUtils; -import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecg.common.aspect.annotation.Dict; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** @@ -28,10 +27,11 @@ import lombok.experimental.Accessors; * @Date: 2025-10-27 * @Version: V1.0 */ -@Data @TableName("base_item") -@Accessors(chain = true) -@EqualsAndHashCode(callSuper = false) +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor @Schema(description = "物料") public class Item implements Serializable { private static final long serialVersionUID = 1L; @@ -55,6 +55,13 @@ public class Item implements Serializable { @Excel(name = "物料名称", width = 15) @Schema(description = "物料名称") private java.lang.String itemName; + + /** + * 单位 + */ + @Excel(name = "单位", width = 15) + @Schema(description = "单位") + private java.lang.String unit; /** * 描述 */ diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/response/ItemResponse.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/response/ItemResponse.java new file mode 100644 index 0000000..27ab8c6 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/response/ItemResponse.java @@ -0,0 +1,33 @@ +package org.cpte.modules.base.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class ItemResponse { + public ReturnData data; + + @Data + public static class ReturnData { + private ReturnResult result; + } + + @Data + public static class ReturnResult { + private List item1; + } + + @Data + public static class MaterialDTO { + // 物料编码 + private String itmreF_0; + // 物料名称 + private String itmdeS1_0; + // 单位 + private String stU_0; + // 启用状态 + private Integer itmstA_0; + } +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IItemService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IItemService.java index 4002298..af9f60f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IItemService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IItemService.java @@ -2,6 +2,8 @@ package org.cpte.modules.base.service; import org.cpte.modules.base.entity.Item; import com.baomidou.mybatisplus.extension.service.IService; +import org.cpte.modules.base.response.ItemResponse; + import java.util.List; import java.util.Map; @@ -44,4 +46,22 @@ public interface IItemService extends IService { */ Map queryByItemIdsToMap(List itemIds); + + /** + * 构建物料信息 + * + * @param material 物料信息 + * @return Item + */ + Item buildItem(ItemResponse.MaterialDTO material); + + /** + * 同步物料信息 + * + * @param sDate 开始时间 + * @param eDate 结束时间 + * @return Boolean + */ + Boolean syncItem(String sDate, String eDate); + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java index a8b16c6..036dec4 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/IStockService.java @@ -4,6 +4,7 @@ import org.cpte.modules.agvTask.entity.AgvTask; import org.cpte.modules.base.entity.Point; import org.cpte.modules.base.entity.Stock; import com.baomidou.mybatisplus.extension.service.IService; +import org.cpte.modules.saiWms.request.SyncStockRequest; import java.util.List; import java.util.Map; @@ -15,6 +16,13 @@ import java.util.Map; * @Version: V1.0 */ public interface IStockService extends IService { + /** + * 构建容器 + * + * @param stockDTO 容器信息 + * @return Stock + */ + Stock buildStocK(SyncStockRequest.StockDTO stockDTO); /** * 验证容器 @@ -25,6 +33,7 @@ public interface IStockService extends IService { /** * 验证容器状态 + * * @param stock 容器 */ void validateStockStatus(Stock stock); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/ItemServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/ItemServiceImpl.java index a2fea7c..e493de2 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/ItemServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/ItemServiceImpl.java @@ -1,19 +1,32 @@ package org.cpte.modules.base.service.impl; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.shiro.SecurityUtils; import org.cpte.modules.base.entity.Item; import org.cpte.modules.base.mapper.ItemMapper; +import org.cpte.modules.base.response.ItemResponse; import org.cpte.modules.base.service.IItemService; +import org.cpte.modules.constant.GeneralConstant; +import org.cpte.modules.utils.BatchUtil; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.util.RestUtil; +import org.jeecg.modules.openapi.mapper.OpenApiMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.*; /** * @Description: 物料 @@ -22,8 +35,17 @@ import java.util.Map; * @Version: V1.0 */ @Service +@Slf4j public class ItemServiceImpl extends ServiceImpl implements IItemService { + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Autowired + private OpenApiMapper openApiMapper; + + @Autowired + private BatchUtil batchUtil; + /** * 验证物料 * @@ -94,4 +116,145 @@ public class ItemServiceImpl extends ServiceImpl implements II } return itemMap; } + + @Override + public Item buildItem(ItemResponse.MaterialDTO material) { + LoginUser sysUser = null; + try { + sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } catch (Exception e) { + log.error("获取登录用户信息失败"); + } + return Item.builder() + .itemCode(material.getItmreF_0()) + .itemName(material.getItmdeS1_0()) + .unit(material.getStU_0()) + .izActive(material.getItmstA_0() == 1 ? 1 : 0) + .delFlag(0) + .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode()) + .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds())) + .createBy(sysUser == null ? "saiWms" : sysUser.getUsername()) + .createTime(new Date()) + .build(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean syncItem(String startDate, String endDate) { + LocalDate sDate = LocalDate.parse(startDate.trim()); + LocalDate eDate = LocalDate.parse(endDate.trim()); + long daysBetween = ChronoUnit.DAYS.between(sDate, eDate); + if (daysBetween > 10) { + throw new RuntimeException("同步物料数据日期范围不能超过10天"); + } + + // 构造请求参数 + JSONObject params = new JSONObject(); + params.put("sDate", sDate.format(DATE_FORMATTER)); + params.put("eDate", eDate.format(DATE_FORMATTER)); + + // 调用接口获取物料数据 + ItemResponse materials = GetProductAddList(params); + if (materials == null || CollectionUtils.isEmpty(materials.getData().getResult().getItem1())) { + return Boolean.TRUE; + } + + // 处理物料数据 + return processMaterials(materials); + + } + + /** + * 获取物料数据 + * + * @param params 请求参数 + * @return ItemResponse + */ + private ItemResponse GetProductAddList(JSONObject params) { + try { + String url = openApiMapper.getRequestUrl(GeneralConstant.SYNC_ITEM).getOriginUrl(); + ResponseEntity response = RestUtil.getNative(url, params, null); + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + return response.getBody().toJavaObject(ItemResponse.class); + } + return null; + } catch (Exception e) { + throw new RuntimeException("获取物料数据失败", e); + } + } + + /** + * 处理物料数据 + * + * @param materials 物料数据 + * @return Boolean + */ + private Boolean processMaterials(ItemResponse materials) { + try { + List itemCodes = materials.getData().getResult().getItem1().stream().map(ItemResponse.MaterialDTO::getItmreF_0).distinct().toList(); + Map itemMap = queryByItemCodesToMap(itemCodes); + + //批量处理 + List insertItems = new ArrayList<>(); + List updateItems = new ArrayList<>(); + Set processedItemCodes = new HashSet<>(); + + for (ItemResponse.MaterialDTO material : materials.getData().getResult().getItem1()) { + String itemCode = material.getItmreF_0(); + + // 去重处理 + if (processedItemCodes.contains(itemCode)) { + continue; + } + processedItemCodes.add(itemCode); + + // 判断新增或更新 + Item existingItem = itemMap.get(itemCode); + if (existingItem == null) { + Item newItem = buildItem(material); + insertItems.add(newItem); + } else { + // 只有字段变化时才更新 + if (isItemChanged(existingItem, material)) { + updateItemFromMaterial(existingItem, material); + updateItems.add(existingItem); + } + } + + log.info("处理物料: {}", itemCode); + } + // 批量保存 + if (CollectionUtils.isNotEmpty(insertItems)) { + batchUtil.saveBatchItem(insertItems); + } + + if (CollectionUtils.isNotEmpty(updateItems)) { + batchUtil.updateBatchItem(updateItems); + } + return Boolean.TRUE; + } catch (Exception e) { + log.error("处理物料数据失败", e); + return Boolean.FALSE; + } + } + + /** + * 检查物料是否发生变化 + */ + private boolean isItemChanged(Item item, ItemResponse.MaterialDTO material) { + return !Objects.equals(item.getItemName(), material.getItmdeS1_0()) || + !Objects.equals(item.getUnit(), material.getStU_0()) || + !Objects.equals(item.getIzActive(), material.getItmstA_0() == 1 ? 1 : 0); + } + + /** + * 更新物料信息 + */ + private void updateItemFromMaterial(Item item, ItemResponse.MaterialDTO material) { + item.setItemName(material.getItmdeS1_0()); + item.setUnit(material.getStU_0()); + item.setIzActive(material.getItmstA_0() == 1 ? 1 : 0); + // 添加更新时间戳 + item.setUpdateTime(new Date()); + } } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java index d6b9041..47dbfea 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/impl/StockServiceImpl.java @@ -3,23 +3,20 @@ package org.cpte.modules.base.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.collect.Maps; import org.apache.commons.collections4.CollectionUtils; +import org.apache.shiro.SecurityUtils; import org.cpte.modules.base.entity.Point; import org.cpte.modules.base.entity.Stock; -import org.cpte.modules.base.entity.Stock; -import org.cpte.modules.base.mapper.StockMapper; import org.cpte.modules.base.mapper.StockMapper; import org.cpte.modules.base.service.IStockService; import org.cpte.modules.constant.enums.CommonStatusEnum; import org.cpte.modules.constant.enums.StockTypeEnum; -import org.springframework.beans.factory.annotation.Autowired; +import org.cpte.modules.saiWms.request.SyncStockRequest; +import org.jeecg.common.system.vo.LoginUser; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * @Description: 容器 @@ -30,6 +27,27 @@ import java.util.Objects; @Service public class StockServiceImpl extends ServiceImpl implements IStockService { + @Override + public Stock buildStocK(SyncStockRequest.StockDTO stockDTO) { + LoginUser sysUser = null; + try { + sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } catch (Exception e) { + log.error("获取登录用户信息失败"); + } + return Stock.builder() + .stockCode(stockDTO.getCode()) + .stockType(StockTypeEnum.TRAY.getValue()) + .izActive(stockDTO.getIzActive()) + .status(CommonStatusEnum.FREE.getValue()) + .delFlag(stockDTO.getDelFlag()) + .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode()) + .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds())) + .createBy(sysUser == null ? "saiWms" : sysUser.getUsername()) + .createTime(new Date()) + .build(); + } + /** * 验证容器 * diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java index 746a691..3f9beb4 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/GeneralConstant.java @@ -9,6 +9,16 @@ public interface GeneralConstant { */ final String OPEN_FLAG = "OPEN"; + /** + * 成功码 + */ + final String SWMS_SUCCESS_CODE = "200"; + + /** + * 失败码 + */ + final String SWMS_FAIL_CODE = "500"; + /** * 成功码 */ @@ -60,6 +70,10 @@ public interface GeneralConstant { */ String MOVE_ORDER_NO = "move_order_no"; + /** + * ERP-物料同步接口 + */ + String SYNC_ITEM = "g9eq4HJn"; /** * TES任务下发接口 */ @@ -81,9 +95,9 @@ public interface GeneralConstant { String HIK_CANCEL_TASK = "gtKsKrUQ"; /** - * 入库回传接口 + * 赛意登录接口 */ - String Login= "7Q7sqpIh"; + String Login = "9EoY51oh"; /** * 入库回传接口 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java index d70a89b..9ddc49a 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/hikAgv/service/impl/IHikAgvServiceImpl.java @@ -90,7 +90,7 @@ public class IHikAgvServiceImpl implements IHikAgvService { updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.AGV_FAIL_CODE); return; } - String url = openApiMapper.getRequestUrl(openApi); + String url = openApiMapper.getRequestUrl(openApi).getOriginUrl(); String code = null; String message = null; @@ -162,7 +162,7 @@ public class IHikAgvServiceImpl implements IHikAgvService { @Override public void cancelAgv(CancelRequest cancelRequest) { AgvTask agvTask = agvTaskMapper.selectById(cancelRequest.getRobotTaskCode()); - String url = openApiMapper.getRequestUrl(GeneralConstant.HIK_CANCEL_TASK); + String url = openApiMapper.getRequestUrl(GeneralConstant.HIK_CANCEL_TASK).getOriginUrl(); String json = generateCancelTaskJson(agvTask); String code = null; String message = null; 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 85bdb8f..74e1546 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 @@ -1,5 +1,6 @@ package org.cpte.modules.inventory.service.impl; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.apache.commons.collections4.CollectionUtils; import org.cpte.modules.constant.enums.InventoryStatusEnum; import org.cpte.modules.inventory.entity.Inventory; @@ -25,6 +26,7 @@ public class InventoryServiceImpl extends ServiceImpl { - /** - * 通过主表id查询子表数据 - * - * @param mainId 主表id - * @return List - */ - public List selectByMainId(Long mainId); + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List + */ + public List selectByMainId(Long mainId); } 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 eb4476a..917e922 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 @@ -1,13 +1,17 @@ package org.cpte.modules.receive.service; +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.receive.entity.AsnDetail; import org.cpte.modules.receive.entity.Asn; import com.baomidou.mybatisplus.extension.service.IService; +import org.cpte.modules.saiWms.request.InboundRequest; import java.io.Serializable; import java.util.Collection; import java.util.List; +import java.util.Map; /** * @Description: 入库单 @@ -47,6 +51,27 @@ public interface IAsnService extends IService { */ public void delBatchMain(Collection idList); + /** + * 构建入库单 + * + * @param inboundRequest 入库请求 + * @return Asn + */ + Asn buildAsn(InboundRequest inboundRequest); + + /** + * 构建入库单明细 + * + * @param inboundDetails 入库单明细 + * @param itemMap 物料信息 + * @param stock 容器 + * @param srcPoint 源库位 + * @param dstPoint 目标库位 + * @return AsnDetail + */ + List buildAsnDetail(List inboundDetails, Map itemMap, Stock stock, Point srcPoint, Point dstPoint); + + /** * 收货操作 * @@ -59,8 +84,7 @@ public interface IAsnService extends IService { * 入库任务回传 * * @param asn 入库单 - * @param asnDetail 入库明细 * @param stock 容器 */ - void receiveCallback(Asn asn, AsnDetail asnDetail, Stock 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 6d67634..d73c8a8 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 @@ -1,9 +1,16 @@ package org.cpte.modules.receive.service.impl; +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.constant.enums.AsnStatusEnum; import org.cpte.modules.receive.entity.AsnDetail; import org.cpte.modules.receive.mapper.AsnDetailMapper; import org.cpte.modules.receive.service.IAsnDetailService; +import org.cpte.modules.saiWms.request.InboundRequest; import org.springframework.stereotype.Service; + +import java.math.BigDecimal; import java.util.List; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java index 81329c5..ea54df8 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/impl/AsnServiceImpl.java @@ -1,11 +1,14 @@ package org.cpte.modules.receive.service.impl; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.util.DateUtils; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; +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; @@ -26,9 +29,10 @@ 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.mapper.ReceiveRecordMapper; import org.cpte.modules.receive.service.IAsnService; +import org.cpte.modules.saiWms.request.InboundRequest; import org.cpte.modules.saiWms.request.SaiWmsRequest; +import org.cpte.modules.serialNumber.AsnSerialNumberRule; import org.cpte.modules.utils.BatchUtil; import org.cpte.modules.utils.BigDecimalUtil; import org.cpte.modules.utils.SwmsLoginUtil; @@ -42,10 +46,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.Serializable; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Collection; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; /** @@ -84,6 +85,8 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS private SwmsLoginUtil swmsLoginUtil; @Autowired private BatchUtil batchUtil; + @Autowired + private AsnSerialNumberRule asnSerialNumberRule; @Override @Transactional(rollbackFor = Exception.class) @@ -103,8 +106,8 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS entity.setLineNo(lineNoCounter.getAndIncrement()); } entity.setAsnId(asn.getId()); - asn.setTenantId(Long.parseLong(sysUser.getRelTenantIds())); - asn.setSysOrgCode(sysUser.getOrgCode()); + entity.setTenantId(Long.parseLong(sysUser.getRelTenantIds())); + entity.setSysOrgCode(sysUser.getOrgCode()); asnDetailMapper.insert(entity); } //刷新入库单 @@ -205,6 +208,46 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS } } + @Override + public Asn buildAsn(InboundRequest inboundRequest) { + String orderNo = asnSerialNumberRule.generateSerialNumber(GeneralConstant.ASN_ORDER_NO); + return Asn.builder() + .orderNo(orderNo) + .thirdOrderNo(inboundRequest.getOrderNo()) + .no(inboundRequest.getNo()) + .whCode(inboundRequest.getWhCode()) + .supplierCode(inboundRequest.getSupplierCode()) + .orderType(inboundRequest.getType()) + .status(AsnStatusEnum.CREATED.getValue()) + .orderDate(new Date()) + .build(); + } + + @Override + public List buildAsnDetail(List inboundDetails, Map itemMap, Stock stock, Point srcPoint, Point dstPoint) { + List newDetailList = new ArrayList<>(); + for (InboundRequest.InboundDetail detail : inboundDetails) { + AsnDetail asnDetail = AsnDetail.builder() + .lineNo(Integer.parseInt(detail.getLineNo())) + .itemId(itemMap.get(detail.getItem()).getId()) + .unit(detail.getUnit()) + .orderQty(BigDecimal.valueOf(detail.getQty())) + .receivedQty(BigDecimal.ZERO) + .stockId(stock.getId()) + .fromPointId(srcPoint == null ? null : srcPoint.getId()) + .toPointId(dstPoint.getId()) + .status(AsnStatusEnum.CREATED.getValue()) + .project(detail.getProject()) + .taskNo(detail.getTaskNo()) + .propC1(detail.getLotAtt04()) + .propC3(detail.getLotAtt010()) + .build(); + newDetailList.add(asnDetail); + } + return newDetailList; + + } + @Override @Transactional(rollbackFor = Exception.class) public void receiveGoods(Long asnId, String pointCode) { @@ -277,29 +320,27 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS iStockService.bindStock(stock, dstPoint); iPointService.bindPoint(dstPoint); - //回传 - // receiveCallback(asn, asnDetail, stock); + receiveCallback(asn, stock); } /** * 入库任务回传JSON */ - private String receiveCallbackJson(Asn asn, AsnDetail asnDetail, Stock stock) { + private String receiveCallbackJson(Asn asn, Stock stock, String ticket) { SaiWmsRequest.Task task = new SaiWmsRequest.Task(); task.setNo(asn.getNo()); task.setOrderNo(asn.getThirdOrderNo()); task.setState(5); task.setLpn(stock.getStockCode()); - task.setErpKey(""); + task.setErpKey(asn.getNo()); task.setCode(""); task.setName(""); - task.setInfkey(""); + task.setInfkey(asn.getNo()); task.setIsDelete(false); - task.setLastUpdateDate(""); - + task.setLastUpdateDate(DateUtils.format(new Date())); SaiWmsRequest.ParameterValue1 parameterValue1 = new SaiWmsRequest.ParameterValue1(); parameterValue1.setValue(List.of(task)); @@ -309,7 +350,7 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS SaiWmsRequest.Context context = new SaiWmsRequest.Context(); context.setInvOrgId(1); - context.setTicket(swmsLoginUtil.Login()); + context.setTicket(ticket); SaiWmsRequest saiWmsRequest = new SaiWmsRequest(); saiWmsRequest.setApiType("SmomWebApiController"); @@ -321,59 +362,78 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS } @Override - public void receiveCallback(Asn asn, AsnDetail asnDetail, Stock stock) { + public void receiveCallback(Asn asn, Stock stock) { // 检查接口开关, 未开启则返回 if (sysDictMapper.queryByDictCode(GeneralConstant.OPEN_FLAG) == null) { - updateAsnDetailResponse(asn, "接口未开启"); + updateAsnDetailResponse(asn, GeneralConstant.SWMS_FAIL_CODE, "接口未开启"); return; } - - Boolean Success = null; - String Message = null; try { - String json = receiveCallbackJson(asn, asnDetail, stock); - String url = openApiMapper.getRequestUrl(GeneralConstant.INBOUND_CALLBACK); - log.info("入库回传请求报文:{}", json); - //String result = HttpPostUtil.sendPostReq(url, json); - String result = "{\n" + - " \"Success\": false,\n" + - " \"Message\": \"入库回传失败\"\n" + - "}"; - if (StringUtils.isEmpty(result)) { - Message = "入库回传返回信息:接口调用失败"; - throw new RuntimeException(Message); + Map authInfo = swmsLoginUtil.Login(); + if (authInfo == null || authInfo.isEmpty()) { + throw new RuntimeException("登录认证信息为空"); } - - JSONObject resulObject = JSON.parseObject(result); - if (resulObject == null) { - Message = "入库回传返回信息:接口返回为空"; - throw new RuntimeException(Message); - } - - Success = resulObject.getBoolean("Success"); - Message = resulObject.getString("Message"); - - if (!Success) { - throw new RuntimeException("入库回传返回信息:" + Message); - } - updateAsnDetailResponse(asn, Message); + 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.sendSWMSResponse(json, url, authorization); + String code = validateResponse(jsonObject); + updateAsnDetailResponse(asn, code, jsonObject.toJSONString()); } catch (Exception e) { - updateAsnDetailResponse(asn, e.getMessage()); + updateAsnDetailResponse(asn, GeneralConstant.SWMS_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.SWMS_SUCCESS_CODE : GeneralConstant.SWMS_FAIL_CODE; + } + /** * 更新任务状态 * * @param asn 入库单 + * @param code 状态码 * @param message 信息 */ - private void updateAsnDetailResponse(Asn asn, String message) { + private void updateAsnDetailResponse(Asn asn, String code, String message) { + + List updateToAsnDetail = new ArrayList<>(); if (asn != null) { + if (AsnStatusEnum.CLOSED.getValue().equals(asn.getStatus())) { + return; + } + if (GeneralConstant.SWMS_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); + } } } @@ -382,6 +442,7 @@ public class AsnServiceImpl extends ServiceImpl implements IAsnS */ public ReceiveRecord buildReceiveRecord(AsnDetail asnDetail, BigDecimal receivedQty, ItemKey itemKey, Long dstPointId) { return ReceiveRecord.builder() + .id(IdWorker.getId()) .asnDetailId(asnDetail.getId()) .stockId(asnDetail.getStockId()) .fromPointId(asnDetail.getToPointId()) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/SyncStockRequest.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/SyncStockRequest.java index 21756b5..bffd2a3 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/SyncStockRequest.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/request/SyncStockRequest.java @@ -8,10 +8,10 @@ import java.util.List; @Data public class SyncStockRequest { @JsonProperty("stocks") - private List stocks; + private List stocks; @Data - public static class Stock { + public static class StockDTO { @JsonProperty("Code") private String code; diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java index f6061b5..a43663a 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/impl/ISaiWmsServiceImpl.java @@ -3,7 +3,6 @@ package org.cpte.modules.saiWms.service.impl; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.SecurityUtils; import org.cpte.modules.agvTask.service.IAgvTaskService; import org.cpte.modules.base.entity.Item; import org.cpte.modules.base.entity.Point; @@ -21,19 +20,15 @@ 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.ISaiWmsService; -import org.cpte.modules.serialNumber.AsnSerialNumberRule; -import org.cpte.modules.serialNumber.PickSerialNumberRule; import org.cpte.modules.shipping.entity.Pick; import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.mapper.PickMapper; import org.cpte.modules.shipping.service.IPickService; import org.cpte.modules.utils.BatchUtil; -import org.jeecg.common.system.vo.LoginUser; 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; @@ -65,12 +60,6 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { @Autowired private IAgvTaskService iAgvTaskService; - @Autowired - private AsnSerialNumberRule asnSerialNumberRule; - - @Autowired - private PickSerialNumberRule pickSerialNumberRule; - @Autowired private BatchUtil batchUtil; @@ -155,10 +144,10 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { List itemCodes = detail.stream().map(InboundRequest.InboundDetail::getItem).toList(); //获取存在的物料 - Map itemMap = itemService.queryByItemCodesToMap(itemCodes); + Map exitItemMap = itemService.queryByItemCodesToMap(itemCodes); //获取数据库不存在的物料集合且去重 - List notExistItemCodes = itemCodes.stream().filter(itemCode -> !itemMap.containsKey(itemCode)).distinct().toList(); + List notExistItemCodes = itemCodes.stream().filter(itemCode -> !exitItemMap.containsKey(itemCode)).distinct().toList(); if (CollectionUtils.isNotEmpty(notExistItemCodes)) { throw new RuntimeException("【" + notExistItemCodes + "】物料不存在"); } @@ -178,16 +167,11 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { Point dstPoint = iPointService.getWorkStationPoint(null, AreaTypeEnum.RK_DOCK.getValue(), GeneralConstant.RK_DOCK_TASK_INDEX); // 创建入库单和明细 - Asn createAsn = buildAsn(inboundRequest); - List createAsnDetails = new ArrayList<>(); - for (InboundRequest.InboundDetail inboundDetail : inboundRequest.getDetails()) { - Item item = itemMap.get(inboundDetail.getItem()); - AsnDetail asnDetail = buildAsnDetail(inboundDetail, srcPoint, dstPoint, item, stock); - createAsnDetails.add(asnDetail); - } + Asn createAsn = asnService.buildAsn(inboundRequest); + List asnDetails = asnService.buildAsnDetail(inboundRequest.getDetails(), exitItemMap, stock, srcPoint, dstPoint); // 保存入库单和入库明细 - asnService.saveMain(createAsn, createAsnDetails); + asnService.saveMain(createAsn, asnDetails); //绑定容器和起点 iStockService.bindStock(stock, srcPoint); @@ -218,13 +202,13 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { //获取不存在的物料 List notExitItemCodes = itemCodes.stream().filter(itemCode -> !exitItemMap.containsKey(itemCode)).toList(); - if (!notExitItemCodes.isEmpty()) { + if (CollectionUtils.isNotEmpty(notExitItemCodes)) { throw new RuntimeException("系统无" + notExitItemCodes + "物料,请维护"); } // 创建出库单和明细 - Pick createPick = buildPick(outboundRequest); - List pickDetails = buildPickDetail(outboundRequest.getDetails(), exitItemMap); + Pick createPick = pickService.buildPick(outboundRequest); + List pickDetails = pickService.buildPickDetail(outboundRequest.getDetails(), exitItemMap); // 保存出库单和出库明细 pickService.saveMain(createPick, pickDetails); @@ -238,7 +222,7 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { } // 校验每个stock项 - for (SyncStockRequest.Stock stock : syncStockRequest.getStocks()) { + for (SyncStockRequest.StockDTO stock : syncStockRequest.getStocks()) { if (StringUtils.isBlank(stock.getCode())) { throw new RuntimeException("容器编码(Code)不能为空"); @@ -272,21 +256,27 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { validateParams(syncStockRequest); //获取所有容器 - List stocks = syncStockRequest.getStocks().stream().map(SyncStockRequest.Stock::getCode).distinct().toList(); + List stocks = syncStockRequest.getStocks().stream().map(SyncStockRequest.StockDTO::getCode).distinct().toList(); Map stocksList = iStockService.queryByStockCodesToMap(stocks); List insertToStock = new ArrayList<>(); List updateToStock = new ArrayList<>(); - - for (SyncStockRequest.Stock stock : syncStockRequest.getStocks()) { - Stock exitStock = stocksList.get(stock.getCode()); + Set processedStockCodes = new HashSet<>(); + for (SyncStockRequest.StockDTO stockDTO : syncStockRequest.getStocks()) { + String stockCode = stockDTO.getCode(); + // 去重处理 + if (processedStockCodes.contains(stockCode)) { + continue; + } + processedStockCodes.add(stockCode); + Stock exitStock = stocksList.get(stockDTO.getCode()); if (exitStock == null) { - Stock createStock = buildStocK(stock); + Stock createStock = iStockService.buildStocK(stockDTO); insertToStock.add(createStock); } else { - exitStock.setIzActive(stock.getIzActive()); - exitStock.setDelFlag(stock.getDelFlag()); + exitStock.setIzActive(stockDTO.getIzActive()); + exitStock.setDelFlag(stockDTO.getDelFlag()); updateToStock.add(exitStock); } } @@ -299,110 +289,6 @@ public class ISaiWmsServiceImpl implements ISaiWmsService { } } - - /** - * 构建容器 - */ - private Stock buildStocK(SyncStockRequest.Stock stock) { - LoginUser sysUser = null; - try { - sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); - } catch (Exception e) { - log.error("获取登录用户信息失败"); - } - return Stock.builder() - .stockCode(stock.getCode()) - .stockType(StockTypeEnum.TRAY.getValue()) - .izActive(stock.getIzActive()) - .status(CommonStatusEnum.FREE.getValue()) - .delFlag(stock.getDelFlag()) - .sysOrgCode(sysUser == null ? "A05" : sysUser.getOrgCode()) - .tenantId(sysUser == null ? 1000L : Long.parseLong(sysUser.getRelTenantIds())) - .createBy(sysUser == null ? "saiWms" : sysUser.getUsername()) - .createTime(new Date()) - .build(); - } - - /** - * 构建入库单 - */ - private Asn buildAsn(InboundRequest inboundRequest) { - String orderNo = asnSerialNumberRule.generateSerialNumber(GeneralConstant.ASN_ORDER_NO); - return Asn.builder() - .orderNo(orderNo) - .thirdOrderNo(inboundRequest.getOrderNo()) - .no(inboundRequest.getNo()) - .whCode(inboundRequest.getWhCode()) - .supplierCode(inboundRequest.getSupplierCode()) - .orderType(inboundRequest.getType()) - .status(AsnStatusEnum.CREATED.getValue()) - .orderDate(new Date()) - .build(); - } - - /** - * 构建入库明细 - */ - private AsnDetail buildAsnDetail(InboundRequest.InboundDetail detail, Point srcPoint, Point dstPoint, Item item, Stock stock) { - // 由于明细只有一条,直接构建单个明细对象 - return AsnDetail.builder() - .lineNo(Integer.parseInt(detail.getLineNo())) - .itemId(item.getId()) - .unit(detail.getUnit()) - .orderQty(BigDecimal.valueOf(detail.getQty())) - .receivedQty(BigDecimal.ZERO) - .stockId(stock.getId()) - .fromPointId(srcPoint == null ? null : srcPoint.getId()) - .toPointId(dstPoint.getId()) - .status(AsnStatusEnum.CREATED.getValue()) - .project(detail.getProject()) - .taskNo(detail.getTaskNo()) - .propC1(detail.getLotAtt04()) - .propC3(detail.getLotAtt010()) - .build(); - } - - - /** - * 构建出库单 - */ - private Pick buildPick(OutboundRequest outboundRequest) { - String orderNo = pickSerialNumberRule.generateSerialNumber(GeneralConstant.PICK_ORDER_NO); - return Pick.builder() - .orderNo(orderNo) - .thirdOrderNo(outboundRequest.getOrderNo()) - .no(outboundRequest.getNo()) - .whCode(outboundRequest.getWhCode()) - .customerCode(outboundRequest.getCustomerCode()) - .orderType(outboundRequest.getType()) - .status(PickStatusEnum.CREATED.getValue()) - .orderDate(new Date()) - .build(); - } - - /** - * 构建出库明细 - */ - private List buildPickDetail(List details, Map exitItemMap) { - List newDetailList = new ArrayList<>(); - for (OutboundRequest.OutboundDetail detail : details) { - PickDetail pickDetail = PickDetail.builder() - .lineNo(Integer.parseInt(detail.getLineNo())) - .itemId(exitItemMap.get(detail.getItem()).getId()) - .unit(detail.getUnit()) - .orderQty(detail.getQty()) - .allocatedQty(BigDecimal.ZERO) - .pickedQty(BigDecimal.ZERO) - .status(PickStatusEnum.CREATED.getValue()) - .project(detail.getProject()) - .taskNo(detail.getTaskNo()) - .propC1(detail.getLotAtt04()) - .propC3(detail.getLotAtt010()) - .build(); - newDetailList.add(pickDetail); - } - return newDetailList; - } } 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 7e644ee..bb01cb9 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 @@ -1,6 +1,8 @@ package org.cpte.modules.shipping.service; +import org.cpte.modules.base.entity.Item; import org.cpte.modules.base.entity.Point; +import org.cpte.modules.saiWms.request.OutboundRequest; import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.entity.Pick; import com.baomidou.mybatisplus.extension.service.IService; @@ -9,6 +11,7 @@ import org.cpte.modules.shipping.entity.Task; import java.io.Serializable; import java.util.Collection; import java.util.List; +import java.util.Map; /** * @Description: 出库单 @@ -48,6 +51,23 @@ public interface IPickService extends IService { */ public void delBatchMain(Collection idList); + /** + * 构建出库单 + * + * @param outboundRequest 出库单请求 + * @return 出库单 + */ + Pick buildPick(OutboundRequest outboundRequest); + + /** + * 构建出库单明细 + * + * @param details 出库单明细 + * @param exitItemMap 物料 + * @return 出库单明细 + */ + List buildPickDetail(List details, Map exitItemMap); + /** * 分配出库单 * 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 5bd737a..5d31dfc 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 @@ -20,6 +20,8 @@ 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.service.IInventoryLogService; +import org.cpte.modules.saiWms.request.OutboundRequest; +import org.cpte.modules.serialNumber.PickSerialNumberRule; import org.cpte.modules.shipping.entity.Pick; import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.entity.Task; @@ -86,7 +88,8 @@ public class PickServiceImpl extends ServiceImpl implements IP private BaseCommonService baseCommonService; @Autowired private BatchUtil batchUtils; - + @Autowired + private PickSerialNumberRule pickSerialNumberRule; /** * 获取出库单Map @@ -299,6 +302,43 @@ public class PickServiceImpl extends ServiceImpl implements IP } } + @Override + public Pick buildPick(OutboundRequest outboundRequest) { + String orderNo = pickSerialNumberRule.generateSerialNumber(GeneralConstant.PICK_ORDER_NO); + return Pick.builder() + .orderNo(orderNo) + .thirdOrderNo(outboundRequest.getOrderNo()) + .no(outboundRequest.getNo()) + .whCode(outboundRequest.getWhCode()) + .customerCode(outboundRequest.getCustomerCode()) + .orderType(outboundRequest.getType()) + .status(PickStatusEnum.CREATED.getValue()) + .orderDate(new Date()) + .build(); + } + + @Override + public List buildPickDetail(List details, Map exitItemMap) { + List newDetailList = new ArrayList<>(); + for (OutboundRequest.OutboundDetail detail : details) { + PickDetail pickDetail = PickDetail.builder() + .lineNo(Integer.parseInt(detail.getLineNo())) + .itemId(exitItemMap.get(detail.getItem()).getId()) + .unit(detail.getUnit()) + .orderQty(detail.getQty()) + .allocatedQty(BigDecimal.ZERO) + .pickedQty(BigDecimal.ZERO) + .status(PickStatusEnum.CREATED.getValue()) + .project(detail.getProject()) + .taskNo(detail.getTaskNo()) + .propC1(detail.getLotAtt04()) + .propC3(detail.getLotAtt010()) + .build(); + newDetailList.add(pickDetail); + } + return newDetailList; + } + @Override @Transactional(rollbackFor = Exception.class) public List allocatePick(List pickIds) { @@ -824,7 +864,7 @@ public class PickServiceImpl extends ServiceImpl implements IP } String json = pickTaskCallbackJson(pick, pickDetail, task, state); - String url = openApiMapper.getRequestUrl(GeneralConstant.OUTBOUND_CALLBACK); + String url = openApiMapper.getRequestUrl(GeneralConstant.OUTBOUND_CALLBACK).getOriginUrl(); log.info("出库回传请求报文:{}", json); Boolean Success = null; String Message = null; 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 61b0293..718a674 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 @@ -100,7 +100,7 @@ public class ITesAgvServiceImpl implements ITesAgvService { updateAgvTaskResponse(agvTask, "接口未开启", GeneralConstant.TES_FAIL_CODE); return; } - String url = openApiMapper.getRequestUrl(openApi); + String url = openApiMapper.getRequestUrl(openApi).getOriginUrl(); Integer returnCode = null; String returnMsg = null; @@ -181,7 +181,7 @@ public class ITesAgvServiceImpl implements ITesAgvService { @Override public void cancelTes(CancelTaskRequest cancelTask) { AgvTask agvTask = agvTaskMapper.selectById(cancelTask.getTaskID()); - String url = openApiMapper.getRequestUrl(GeneralConstant.TES_CANCEL_TASK); + String url = openApiMapper.getRequestUrl(GeneralConstant.TES_CANCEL_TASK).getOriginUrl(); String json = generateCancelTaskJson(agvTask); Integer returnCode = null; String returnMsg = null; 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 3b38223..afee71f 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 @@ -82,18 +82,19 @@ public class BatchUtil { */ @Transactional public void saveBatchItem(List items) { - String sql = "INSERT INTO base_item (item_code,item_name,description,iz_active, del_flag,sys_org_code,tenant_id,create_by,create_time) VALUES (?,?,?,?,?,?,?,?,?)"; + 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.setString(1, item.getItemCode()); - ps.setString(2, item.getItemName()); - ps.setString(3, item.getDescription()); - ps.setInt(4, item.getIzActive()); - ps.setInt(5, item.getDelFlag()); - ps.setString(6, item.getSysOrgCode()); - ps.setLong(7, item.getTenantId()); - ps.setString(8, item.getCreateBy()); - ps.setDate(9, new Date(item.getCreateTime().getTime())); + ps.setLong(1, IdWorker.getId()); + ps.setString(2, item.getItemCode()); + ps.setString(3, item.getItemName()); + ps.setString(4, item.getUnit()); + ps.setInt(5, item.getIzActive()); + ps.setInt(6, item.getDelFlag()); + ps.setString(7, item.getSysOrgCode()); + ps.setLong(8, item.getTenantId()); + ps.setString(9, item.getCreateBy()); + ps.setDate(10, new Date(item.getCreateTime().getTime())); } catch (SQLException e) { throw new RuntimeException(e); } @@ -105,12 +106,12 @@ public class BatchUtil { */ @Transactional public void updateBatchItem(List items) { - String sql = "UPDATE base_item SET item_code = ?, item_name = ?, description = ?, iz_active = ?, del_flag = ? WHERE id = ?"; + String sql = "UPDATE base_item SET item_code = ?, item_name = ?, unit = ?, iz_active = ?, del_flag = ? WHERE id = ?"; batchUpdate(sql, items, (ps, item) -> { try { ps.setString(1, item.getItemCode()); ps.setString(2, item.getItemName()); - ps.setString(3, item.getDescription()); + ps.setString(3, item.getUnit()); ps.setInt(4, item.getIzActive()); ps.setInt(5, item.getDelFlag()); ps.setLong(6, item.getId()); @@ -125,22 +126,23 @@ public class BatchUtil { */ @Transactional public void saveBatchPoint(List points) { - String sql = "INSERT INTO base_point (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 (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + 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, point.getAreaId()); - ps.setString(2, point.getPointCode()); - ps.setInt(3, point.getStatus()); - ps.setString(4, point.getRowNum()); - ps.setString(5, point.getColNum()); - ps.setString(6, point.getLayerNum()); - ps.setString(7, point.getDescription()); - ps.setInt(8, point.getIzActive()); - ps.setInt(9, point.getDelFlag()); - ps.setString(10, point.getSysOrgCode()); - ps.setLong(11, point.getTenantId()); - ps.setString(12, point.getCreateBy()); - ps.setDate(13, new Date(point.getCreateTime().getTime())); + ps.setLong(1, IdWorker.getId()); + ps.setLong(2, point.getAreaId()); + ps.setString(3, point.getPointCode()); + ps.setInt(4, point.getStatus()); + ps.setString(5, point.getRowNum()); + ps.setString(6, point.getColNum()); + ps.setString(7, point.getLayerNum()); + ps.setString(8, point.getDescription()); + ps.setInt(9, point.getIzActive()); + ps.setInt(10, point.getDelFlag()); + ps.setString(11, point.getSysOrgCode()); + ps.setLong(12, point.getTenantId()); + ps.setString(13, point.getCreateBy()); + ps.setDate(14, new Date(point.getCreateTime().getTime())); } catch (SQLException e) { throw new RuntimeException(e); } @@ -260,7 +262,7 @@ public class BatchUtil { "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, receiveRecords, (ps, record) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, record.getId()); ps.setLong(2, record.getAsnDetailId()); ps.setLong(3, record.getStockId()); ps.setLong(4, record.getFromPointId()); @@ -377,12 +379,12 @@ public class BatchUtil { "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; batchInsert(sql, inventories, (ps, inventory) -> { try { - ps.setLong(1, IdWorker.getId()); + ps.setLong(1, inventory.getId()); ps.setLong(2, inventory.getItemKeyId()); ps.setLong(3, inventory.getItemId()); ps.setLong(4, inventory.getPointId()); ps.setLong(5, inventory.getStockId()); - ps.setLong(6, inventory.getReceiveRecordId()); + ps.setObject(6, inventory.getReceiveRecordId()); ps.setBigDecimal(7, inventory.getQuantity()); ps.setBigDecimal(8, inventory.getQueuedQty()); ps.setInt(9, inventory.getStatus()); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/CodeGeneratorUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/CodeGeneratorUtil.java index d18baf1..2038222 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/CodeGeneratorUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/CodeGeneratorUtil.java @@ -12,8 +12,8 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.List; -@Service @Slf4j +@Service public class CodeGeneratorUtil { @Autowired diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpGetUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpGetUtil.java new file mode 100644 index 0000000..e6bb21a --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpGetUtil.java @@ -0,0 +1,75 @@ +package org.cpte.modules.utils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +@Slf4j +public class HttpGetUtil { + + /** + * 发送GET请求 + * + * @param apiUrl 请求地址 + * @param authorization 可选的认证信息 + * @return 响应内容字符串,出错时返回null + */ + public static String sendGetReq(String apiUrl, String authorization) { + HttpURLConnection connection = null; + try { + // 创建URL对象并建立连接 + URL url = new URL(apiUrl); + connection = (HttpURLConnection) url.openConnection(); + + // 配置连接参数 + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.setUseCaches(false); + connection.setRequestMethod("GET"); + + // 设置HTTP头 + connection.setRequestProperty("Accept", "application/json"); + if (StringUtils.isNotBlank(authorization)) { + connection.setRequestProperty("Authorization", authorization); + } + + // 处理响应 + int responseCode = connection.getResponseCode(); + if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) { + // 错误处理 + try (InputStream errorStream = connection.getErrorStream()) { + String errorResponse = ""; + if (errorStream != null) { + errorResponse = new String(IOUtils.toByteArray(errorStream), StandardCharsets.UTF_8); + } + log.error("HTTP GET请求失败: 状态码={}, 错误响应={}", responseCode, errorResponse); + return null; + } + } + + // 读取正常响应 + try (InputStream inputStream = connection.getInputStream()) { + String response = new String(IOUtils.toByteArray(inputStream), StandardCharsets.UTF_8); + if (response.trim().isEmpty()) { + log.warn("HTTP GET请求返回空响应"); + } + return response; + } + + } catch (IOException e) { + log.error("HTTP GET请求异常: {}", e.getMessage(), e); + return null; + } finally { + // 确保连接断开 + if (connection != null) { + connection.disconnect(); + } + } + } +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpPostUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpPostUtil.java index 125d1ee..8b5aff3 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpPostUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/HttpPostUtil.java @@ -2,6 +2,7 @@ package org.cpte.modules.utils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.io.InputStream; @@ -12,7 +13,7 @@ import java.nio.charset.StandardCharsets; @Slf4j public class HttpPostUtil { - public static String sendPostReq(String apiUrl, String jsonRequest) { + public static String sendPostReq(String apiUrl, String jsonRequest, String authorization) { HttpURLConnection connection = null; try { // 创建URL对象并建立连接 @@ -21,7 +22,7 @@ public class HttpPostUtil { // 配置连接参数 connection.setConnectTimeout(5000); - connection.setReadTimeout(10000); + connection.setReadTimeout(5000); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); @@ -30,6 +31,10 @@ public class HttpPostUtil { // 设置HTTP头 connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); connection.setRequestProperty("Accept", "application/json"); + if (StringUtils.isNotBlank(authorization)) { + connection.setRequestProperty("Authorization", authorization); + } + // 写入请求体 byte[] requestData = jsonRequest.getBytes(StandardCharsets.UTF_8); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java index d7fa66e..6b3bf35 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java @@ -1,20 +1,23 @@ package org.cpte.modules.utils; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.saiWms.request.SaiWmsRequest; +import org.jeecg.modules.openapi.entity.OpenApi; 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.util.HashMap; import java.util.List; +import java.util.Map; -@Service @Slf4j +@Service public class SwmsLoginUtil { @Autowired @@ -40,39 +43,95 @@ public class SwmsLoginUtil { return JSON.toJSONString(saiWmsRequest); } - public String Login() { - String url = openApiMapper.getRequestUrl(GeneralConstant.Login); + public Map Login() { + Map map = new HashMap<>(); + OpenApi openApi = openApiMapper.getRequestUrl(GeneralConstant.Login); + if (openApi == null) { + throw new RuntimeException("接口未配置"); + } + + String url = openApi.getOriginUrl(); + String headersJson = openApi.getHeadersJson(); + JSONArray headersArray = JSON.parseArray(headersJson); + + if (headersArray == null || headersArray.isEmpty()) { + throw new RuntimeException("请设置请求头参数"); + } + + JSONObject headerObj = headersArray.getJSONObject(0); + String authorization = headerObj.getString("defaultValue"); String json = loginJson(); - log.info("登录请求报文:{}", json); - Boolean Success = null; - String Message = null; - //String result = HttpPostUtil.sendPostReq(url, json); - String result = "{\n" + - " \"Success\": false,\n" + - " \"Message\": \"账号[SysAdmin ]不存在或密码错误\",\n" + - " \"Result\": null,\n" + - " \"Context\": {\n" + - " \"Ticket\": \"123123\"\n" + - " }\n" + - "}"; - if (StringUtils.isEmpty(result)) { - Message = "登录返回信息:接口调用失败"; - throw new RuntimeException(Message); + JSONObject resultObject = sendSWMSLoginResponse(json, url, authorization); + + JSONObject data = resultObject.getJSONObject("data"); + if (data == null) { + throw new RuntimeException("接口数据返回为空"); } - JSONObject resulObject = JSON.parseObject(result); - if (resulObject == null) { - Message = "登录返回信息:接口返回为空"; - throw new RuntimeException(Message); + JSONObject data2 = data.getJSONObject("data"); + if (data2 == null) { + throw new RuntimeException("接口数据返回为空"); } - Success = resulObject.getBoolean("Success"); - Message = resulObject.getString("Message"); - - if (!Success) { - throw new RuntimeException("登录返回信息:" + Message); + JSONObject context = data2.getJSONObject("Context"); + if (context == null) { + throw new RuntimeException("内容数据返回为空"); } - return resulObject.getJSONObject("Context").getString("Ticket"); + map.put("Ticket", context.getString("Ticket")); + map.put("authorization", authorization); + return map; } + + public JSONObject sendSWMSLoginResponse(String json, String url, String authorization) { + // 发送请求 + String result = HttpPostUtil.sendPostReq(url, json, authorization); + log.info("请求路径:{} - 请求参数:{} - 响应结果:{}", url, json, result); + + if (StringUtils.isBlank(result)) { + throw new RuntimeException("接口调用失败"); + } + + JSONObject resultObject = JSON.parseObject(result); + if (resultObject == null) { + throw new RuntimeException("接口返回为空"); + } + + JSONObject data = resultObject.getJSONObject("data"); + if (data == null) { + throw new RuntimeException("接口数据返回为空"); + } + String code = data.getString("code"); + String message = data.getString("message"); + + if (!GeneralConstant.SWMS_SUCCESS_CODE.equals(code)) { + throw new RuntimeException(message); + } + return resultObject; + } + + public JSONObject sendSWMSResponse(String json, String url, String authorization) { + // 发送请求 + String result = HttpPostUtil.sendPostReq(url, json, authorization); + log.info("请求路径:{} - 请求参数:{} - 响应结果:{}", url, json, result); + + if (StringUtils.isBlank(result)) { + throw new RuntimeException("接口调用失败"); + } + + JSONObject resultObject = JSON.parseObject(result); + if (resultObject == null) { + throw new RuntimeException("接口返回为空"); + } + String code = resultObject.getString("code"); + String message = resultObject.getString("message"); + + if (!GeneralConstant.SWMS_SUCCESS_CODE.equals(code)) { + throw new RuntimeException(message); + } + + return resultObject; + } + + } diff --git a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java index b242c6e..6f9693b 100644 --- a/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java +++ b/cpte-module-system/cpte-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java @@ -16,7 +16,7 @@ public interface OpenApiMapper extends BaseMapper { * @param requestUrl 接口地址 * @return String */ - @Select("select origin_url from open_api where request_url = #{requestUrl}") - @Cacheable(value =CacheConstant.SYS_DICT_CACHE ,key = "#requestUrl", unless = "#result == null ") - String getRequestUrl(@Param("requestUrl") String requestUrl); + @Select("select id,origin_url,headers_json,params_json from open_api where request_url = #{requestUrl}") + @Cacheable(value = CacheConstant.SYS_DICT_CACHE, key = "#requestUrl", unless = "#result == null ") + OpenApi getRequestUrl(@Param("requestUrl") String requestUrl); }