Browse Source

更新

master
常熟吴彦祖 7 months ago
parent
commit
46abfe0bbd
  1. 71
      src/main/java/com/gaotao/modules/automatedWarehouse/controller/WcsIntegrationController.java
  2. 49
      src/main/java/com/gaotao/modules/automatedWarehouse/entity/BufferZoneConfig.java
  3. 58
      src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsIntegrationMapper.java
  4. 28
      src/main/java/com/gaotao/modules/automatedWarehouse/service/WcsIntegrationService.java
  5. 173
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java
  6. 96
      src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml

71
src/main/java/com/gaotao/modules/automatedWarehouse/controller/WcsIntegrationController.java

@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/wcsIntegration")
@ -52,5 +53,75 @@ public class WcsIntegrationController {
return R.ok();
}
// ==================== 打托相关接口 - AI制作 ====================
/**
* 检查栈板是否存在并获取位置信息 - AI制作
*/
@PostMapping(value="/checkPalletExists")
@ResponseBody
public R checkPalletExists(@RequestBody Map<String, Object> params) {
try {
Map<String, Object> result = wcsIntegrationService.checkPalletExists(params);
return R.ok().put("positions", result.get("positions")).put("palletType", result.get("palletType"));
} catch (Exception e) {
return R.error(e.getMessage());
}
}
/**
* 获取栈板明细 - AI制作
*/
@PostMapping(value="/getPalletDetails")
@ResponseBody
public R getPalletDetails(@RequestBody Map<String, Object> params) {
try {
List<Map<String, Object>> details = wcsIntegrationService.getPalletDetails(params);
return R.ok().put("details", details);
} catch (Exception e) {
return R.error(e.getMessage());
}
}
/**
* 根据位置获取层数 - AI制作
*/
@PostMapping(value="/getLayersByPosition")
@ResponseBody
public R getLayersByPosition(@RequestBody Map<String, Object> params) {
try {
List<Integer> layers = wcsIntegrationService.getLayersByPosition(params);
return R.ok().put("layers", layers);
} catch (Exception e) {
return R.error(e.getMessage());
}
}
/**
* 保存栈板明细扫进 - AI制作
*/
@PostMapping(value="/savePalletDetail")
@ResponseBody
public R savePalletDetail(@RequestBody Map<String, Object> params) {
try {
wcsIntegrationService.savePalletDetail(params);
return R.ok();
} catch (Exception e) {
return R.error(e.getMessage());
}
}
/**
* 删除栈板明细扫出 - AI制作
*/
@PostMapping(value="/deletePalletDetail")
@ResponseBody
public R deletePalletDetail(@RequestBody Map<String, Object> params) {
try {
wcsIntegrationService.deletePalletDetail(params);
return R.ok();
} catch (Exception e) {
return R.error(e.getMessage());
}
}
}

49
src/main/java/com/gaotao/modules/automatedWarehouse/entity/BufferZoneConfig.java

@ -0,0 +1,49 @@
package com.gaotao.modules.automatedWarehouse.entity;
/**
* 缓冲区配置枚举类 - AI制作
* 用于定义缓冲区专用的仓库和库位
*/
public enum BufferZoneConfig {
/**
* 缓冲区仓库ID
*/
BUFFER_WAREHOUSE_ID("liku"),
/**
* 缓冲区库位ID
*/
BUFFER_LOCATION_ID("A1");
private final String value;
BufferZoneConfig(String value) {
this.value = value;
}
public String getValue() {
return value;
}
/**
* 检查是否为缓冲区仓库
*/
public static boolean isBufferWarehouse(String warehouseId) {
return BUFFER_WAREHOUSE_ID.getValue().equals(warehouseId);
}
/**
* 检查是否为缓冲区库位
*/
public static boolean isBufferLocation(String locationId) {
return BUFFER_LOCATION_ID.getValue().equals(locationId);
}
/**
* 检查是否为缓冲区标签
*/
public static boolean isBufferLabel(String warehouseId, String locationId) {
return isBufferWarehouse(warehouseId) && isBufferLocation(locationId);
}
}

58
src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsIntegrationMapper.java

@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface WcsIntegrationMapper {
@ -17,5 +18,62 @@ public interface WcsIntegrationMapper {
void batchSaveTransportTask(@Param("list") List<WmsTransportTask> transportTaskList);
// ==================== 打托相关方法 - AI制作 ====================
/**
* 检查栈板是否存在 - AI制作
*/
Map<String, Object> getPalletInfo(@Param("site") String site, @Param("palletId") String palletId);
/**
* 获取栈板类型的位置信息 - AI制作
*/
List<String> getPalletTypePositions(@Param("site") String site, @Param("palletType") String palletType);
/**
* 获取栈板明细 - AI制作
*/
List<Map<String, Object>> getPalletDetails(@Param("site") String site, @Param("palletId") String palletId,
@Param("position") String position, @Param("layer") Integer layer);
/**
* 根据位置获取层数 - AI制作
*/
List<Integer> getLayersByPosition(@Param("site") String site, @Param("palletId") String palletId,
@Param("position") String position);
/**
* 验证标签 - AI制作
*/
Map<String, Object> validateLabel(@Param("site") String site, @Param("serialNo") String serialNo);
/**
* 获取栈板类型区域信息用于校验层级规则 - AI制作
*/
List<Map<String, Object>> getPalletTypeAreaInfo(@Param("site") String site, @Param("palletType") String palletType);
/**
* 获取栈板指定层的明细统计 - AI制作
*/
List<Map<String, Object>> getPalletLayerStatistics(@Param("site") String site, @Param("palletId") String palletId,
@Param("layer") Integer layer);
/**
* 保存栈板明细 - AI制作
*/
void savePalletDetail(@Param("site") String site, @Param("palletId") String palletId,
@Param("position") String position, @Param("layer") Integer layer,
@Param("serialNo") String serialNo, @Param("partNo") String partNo,
@Param("createBy") String createBy);
/**
* 根据标签查找栈板信息 - AI制作
*/
Map<String, Object> findPalletByLabel(@Param("site") String site, @Param("serialNo") String serialNo);
/**
* 删除栈板明细 - AI制作
*/
void deletePalletDetail(@Param("site") String site, @Param("palletId") String palletId,
@Param("serialNo") String serialNo);
}

28
src/main/java/com/gaotao/modules/automatedWarehouse/service/WcsIntegrationService.java

@ -4,9 +4,37 @@ import com.gaotao.modules.automatedWarehouse.entity.WmsLabelAndPalletData;
import com.gaotao.modules.automatedWarehouse.entity.PartPalletData;
import java.util.List;
import java.util.Map;
public interface WcsIntegrationService {
List<WmsLabelAndPalletData> palletListForPartNo(PartPalletData inData);
void callPalletFromWcs(List<WmsLabelAndPalletData> data);
// ==================== 打托相关方法 - AI制作 ====================
/**
* 检查栈板是否存在并获取位置信息 - AI制作
*/
Map<String, Object> checkPalletExists(Map<String, Object> params) throws Exception;
/**
* 获取栈板明细 - AI制作
*/
List<Map<String, Object>> getPalletDetails(Map<String, Object> params) throws Exception;
/**
* 根据位置获取层数 - AI制作
*/
List<Integer> getLayersByPosition(Map<String, Object> params) throws Exception;
/**
* 保存栈板明细扫进 - AI制作
*/
void savePalletDetail(Map<String, Object> params) throws Exception;
/**
* 删除栈板明细扫出 - AI制作
*/
void deletePalletDetail(Map<String, Object> params) throws Exception;
}

173
src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java

@ -1,6 +1,7 @@
package com.gaotao.modules.automatedWarehouse.service.impl;
import com.gaotao.modules.api.service.WcsApiService;
import com.gaotao.modules.automatedWarehouse.entity.BufferZoneConfig;
import com.gaotao.modules.automatedWarehouse.entity.PartPalletData;
import com.gaotao.modules.automatedWarehouse.entity.WmsLabelAndPalletData;
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask;
@ -14,10 +15,10 @@ import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@ -93,4 +94,172 @@ public class WcsIntegrationServiceImpl implements WcsIntegrationService {
// TODO: 这里可以调用WCS接口通知立库执行运输任务
wcsApiService.pushAgvTaskApi(saveList);
}
// ==================== 打托相关方法实现 - AI制作 ====================
@Override
public Map<String, Object> checkPalletExists(Map<String, Object> params) throws Exception {
String site = (String) params.get("site");
String palletId = (String) params.get("palletId");
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId)) {
throw new Exception("参数不能为空");
}
// 检查栈板是否存在
Map<String, Object> palletInfo = wcsIntegrationMapper.getPalletInfo(site, palletId);
if (palletInfo == null) {
throw new Exception("栈板不存在");
}
// 获取栈板类型的位置信息
String palletType = (String) palletInfo.get("pallet_type");
List<String> positions = wcsIntegrationMapper.getPalletTypePositions(site, palletType);
Map<String, Object> result = new HashMap<>();
result.put("positions", positions);
result.put("palletType", palletType);
return result;
}
@Override
public List<Map<String, Object>> getPalletDetails(Map<String, Object> params) throws Exception {
String site = (String) params.get("site");
String palletId = (String) params.get("palletId");
String position = (String) params.get("position");
Integer layer = null;
if (params.get("layer") != null && !params.get("layer").equals("")) {
layer = Integer.valueOf(params.get("layer").toString());
}
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId)) {
throw new Exception("参数不能为空");
}
return wcsIntegrationMapper.getPalletDetails(site, palletId, position, layer);
}
@Override
public List<Integer> getLayersByPosition(Map<String, Object> params) throws Exception {
String site = (String) params.get("site");
String palletId = (String) params.get("palletId");
String position = (String) params.get("position");
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) || !StringUtils.hasText(position)) {
throw new Exception("参数不能为空");
}
return wcsIntegrationMapper.getLayersByPosition(site, palletId, position);
}
@Override
@Transactional
public void savePalletDetail(Map<String, Object> params) throws Exception {
String site = (String) params.get("site");
String palletId = (String) params.get("palletId");
String position = (String) params.get("position");
Integer layer = Integer.valueOf(params.get("layer").toString());
String serialNo = (String) params.get("serialNo");
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) ||
!StringUtils.hasText(position) || layer == null || !StringUtils.hasText(serialNo)) {
throw new Exception("参数不能为空");
}
// 1. 验证标签
Map<String, Object> labelInfo = wcsIntegrationMapper.validateLabel(site, serialNo);
if (labelInfo == null) {
throw new Exception("标签不存在");
}
String inStockFlag = (String) labelInfo.get("inStockFlag");
String warehouseId = (String) labelInfo.get("warehouseId");
String locationId = (String) labelInfo.get("locationId");
if (!"Y".equals(inStockFlag)) {
throw new Exception("标签不在库状态");
}
if (!BufferZoneConfig.isBufferLabel(warehouseId, locationId)) {
throw new Exception("标签不在缓冲区,无法进行打托操作");
}
// 2. 检查标签是否已在栈板中当前栈板或其他栈板
Map<String, Object> existingPalletInfo = wcsIntegrationMapper.findPalletByLabel(site, serialNo);
if (existingPalletInfo != null) {
String existingPalletId = (String) existingPalletInfo.get("palletId");
// 如果标签在当前栈板提示不要重复扫描
if (palletId.equals(existingPalletId)) {
throw new Exception("该条码已在本栈板上,请不要重复扫描");
}
// 如果标签在其他栈板检查是否在缓冲区
if (BufferZoneConfig.isBufferLabel(warehouseId, locationId)) {
wcsIntegrationMapper.deletePalletDetail(site, existingPalletId, serialNo);
} else {
throw new Exception("该条码不在缓冲区,请先移库");
}
}
// 3. 层级校验如果选择第N+1层必须所有position的第N层都有数据ccl_wms
if (layer > 1) {
// 获取栈板类型信息
Map<String, Object> palletInfo = wcsIntegrationMapper.getPalletInfo(site, palletId);
String palletType = (String) palletInfo.get("pallet_type");
// 获取栈板类型的所有位置
List<String> allPositions = wcsIntegrationMapper.getPalletTypePositions(site, palletType);
// 检查前一层layer-1的所有位置是否都有数据
List<Map<String, Object>> prevLayerStats = wcsIntegrationMapper.getPalletLayerStatistics(site, palletId, layer - 1);
// 将统计结果转换为位置映射
Set<String> prevLayerPositions = prevLayerStats.stream()
.map(stat -> (String) stat.get("position"))
.collect(Collectors.toSet());
// 检查是否所有位置在前一层都有数据
List<String> missingPositions = allPositions.stream()
.filter(pos -> !prevLayerPositions.contains(pos))
.collect(Collectors.toList());
if (!missingPositions.isEmpty()) {
throw new Exception("第" + (layer - 1) + "层以下位置还未放满,请先放满:" + String.join(", ", missingPositions));
}
}
// 4. 保存栈板明细
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
String partNo = (String) labelInfo.get("partNo");
wcsIntegrationMapper.savePalletDetail(site, palletId, position, layer, serialNo, partNo, username);
}
@Override
@Transactional
public void deletePalletDetail(Map<String, Object> params) throws Exception {
String site = (String) params.get("site");
String palletId = (String) params.get("palletId");
String serialNo = (String) params.get("serialNo");
if (!StringUtils.hasText(site) || !StringUtils.hasText(palletId) || !StringUtils.hasText(serialNo)) {
throw new Exception("参数不能为空");
}
// 检查标签是否在本栈板中
Map<String, Object> existingPalletInfo = wcsIntegrationMapper.findPalletByLabel(site, serialNo);
if (existingPalletInfo == null) {
throw new Exception("该条码不在任何栈板上");
}
String existingPalletId = (String) existingPalletInfo.get("palletId");
if (!palletId.equals(existingPalletId)) {
throw new Exception("该条码不在此栈板上");
}
wcsIntegrationMapper.deletePalletDetail(site, palletId, serialNo);
}
}

96
src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gaotao.modules.automatedWarehouse.mapper.WcsIntegrationMapper">
<select id="palletListForPartNo" resultType="WmsLabelAndPalletData">
select b.site,a.pallet_id,b.part_no,sum(b.qty) as qty
from pallet_detail a ,wms_label b
@ -13,15 +15,15 @@
<if test="warehouseId != null and warehouseId != ''">
and b.warehouse_id=#{warehouseId}
</if>
<if test="partNo != null and partNo != ''">
and a.part_no = #{partNo}
</if>
<if test="partNo != null and partNo != ''">
and a.part_no = #{partNo}
</if>
<if test="serialNo != null and serialNo != ''">
and a.serial_no = #{serialNo}
</if>
</if>
<if test="batchNo != null and batchNo != ''">
and b.batch_no = #{batchNo}
</if>
</if>
</where>
group by b.site, a.pallet_id, b.part_no
</select>
@ -56,4 +58,88 @@
</foreach>
</insert>
<!-- ==================== 打托相关SQL - AI制作 ==================== -->
<!-- 检查栈板是否存在并获取栈板信息 - AI制作 -->
<select id="getPalletInfo" resultType="java.util.Map">
SELECT pallet_id, pallet_type, status, location_code, site, warehouse_id
FROM pallet
WHERE site = #{site} AND pallet_id = #{palletId} AND is_deleted = '0'
</select>
<!-- 获取栈板类型的位置信息 - AI制作 -->
<select id="getPalletTypePositions" resultType="java.lang.String">
SELECT position
FROM pallet_type_area
WHERE site = #{site} AND pallet_type = #{palletType}
ORDER BY position
</select>
<!-- 获取栈板明细 - AI制作 -->
<select id="getPalletDetails" resultType="java.util.Map">
SELECT site, pallet_id as palletId, position, layer, serial_no as serialNo, part_no as partNo,
create_date as createDate, create_by as createBy
FROM pallet_detail
WHERE site = #{site} AND pallet_id = #{palletId}
<if test="position != null and position != ''">
AND position = #{position}
</if>
<if test="layer != null">
AND layer = #{layer}
</if>
ORDER BY position, layer, serial_no
</select>
<!-- 根据位置获取层数 - AI制作 -->
<select id="getLayersByPosition" resultType="java.lang.Integer">
SELECT DISTINCT layer
FROM pallet_detail
WHERE site = #{site} AND pallet_id = #{palletId} AND position = #{position}
ORDER BY layer
</select>
<!-- 验证标签 - AI制作 -->
<select id="validateLabel" resultType="java.util.Map">
SELECT site, serial_no as serialNo, part_no as partNo, qty, in_stock_flag as inStockFlag,
label_type as labelType, batch_no as batchNo, warehouse_id as warehouseId,
location_id as locationId, remark, tid, epc
FROM wms_label
WHERE site = #{site} AND serial_no = #{serialNo}
</select>
<!-- 获取栈板类型区域信息(用于校验层级规则) - AI制作 -->
<select id="getPalletTypeAreaInfo" resultType="java.util.Map">
SELECT site, pallet_type as palletType, position, position_desc as positionDesc
FROM pallet_type_area
WHERE site = #{site} AND pallet_type = #{palletType}
ORDER BY position
</select>
<!-- 获取栈板指定层的明细统计 - AI制作 -->
<select id="getPalletLayerStatistics" resultType="java.util.Map">
SELECT position, COUNT(*) as count
FROM pallet_detail
WHERE site = #{site} AND pallet_id = #{palletId} AND layer = #{layer}
GROUP BY position
</select>
<!-- 根据标签查找栈板信息 - AI制作 -->
<select id="findPalletByLabel" resultType="java.util.Map">
SELECT pallet_id as palletId, position, layer
FROM pallet_detail
WHERE site = #{site} AND serial_no = #{serialNo}
</select>
<!-- 保存栈板明细 - AI制作 -->
<insert id="savePalletDetail">
INSERT INTO pallet_detail (site, pallet_id, position, layer, serial_no, part_no, create_date, create_by)
VALUES (#{site}, #{palletId}, #{position}, #{layer}, #{serialNo}, #{partNo}, GETDATE(), #{createBy})
</insert>
<!-- 删除栈板明细 - AI制作 -->
<delete id="deletePalletDetail">
DELETE FROM pallet_detail
WHERE site = #{site} AND pallet_id = #{palletId} AND serial_no = #{serialNo}
</delete>
</mapper>
Loading…
Cancel
Save