自动化立体仓库 - WMS系统
Administrator
2025-06-27 f910377a07c3ab8e428f094b4bb4d2b03ea1d1a8
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -30,11 +30,13 @@
import com.zy.system.mapper.ConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -1135,57 +1137,88 @@
        return "入库成功";
    }
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    @Transactional
    public R kthl(KthlParam param) {
        String barcode = param.getBarcode();
        String lockKey = "kthl:lock:" + barcode;
        String lockVal = UUID.randomUUID().toString(); // 防止误删他人锁
        // 获取模式为电脑模式,无任务的堆垛机列表:防止分配到堆垛机不可用
        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().eq("crn_sts",3)
                .eq("wrk_no",0).eq("in_enable","Y").eq("out_enable","Y"));
        if (basCrnps.isEmpty()) {
            // 都有任务则获取电脑模式的堆垛机列表
            basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().eq("crn_sts",3).eq("in_enable","Y")
                    .eq("out_enable","Y"));
        // 分布式锁,5秒过期
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, lockVal, 5, TimeUnit.SECONDS);
        if (locked == null || !locked) {
            return R.error("重复提交:该托盘已在处理,请勿重复操作");
        }
        if (basCrnps.isEmpty()) {
            throw new CoolException("没有可用堆垛机,堆垛机停止或异常或禁用");
        }
        // 可用堆垛机列表
        List<Integer> crnNoList = basCrnps.stream().map(BasCrnp::getCrnNo).collect(Collectors.toList());
        Integer crnNo = crnNoList.get(0);
        int workNo = commonService.getWorkNo(5);
        Date now = new Date();
        // 生成工作档
        WrkMast wrkMast = new WrkMast();
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(new Date());
        wrkMast.setWrkSts(1L); //
        wrkMast.setIoType(3); // 站到站
        wrkMast.setIoPri(14D); // 优先级
        wrkMast.setCrnNo(crnNo);
        wrkMast.setSourceStaNo(secondFloorIn[crnNo]);
        wrkMast.setStaNo(secondFloorOut[crnNo]);
        wrkMast.setLocNo("");
        wrkMast.setBarcode(param.getBarcode()); // 托盘码
        wrkMast.setFullPlt("N"); // 满板:Y
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setEmptyMk("Y"); // 空板
        wrkMast.setLinkMis("Y");
        wrkMast.setCtnType(1); // 容器类型
        // 操作人员数据
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
        boolean res = wrkMastService.insert(wrkMast);
        if (!res) {
            throw new CoolException("保存工作档失败");
        }
        // 返回GWCS目标信息
        pushStaNoToGwcs(param.getPalletizingNo(),wrkMast.getSourceStaNo(),workNo,param.getBarcode(),"二楼空托回流推送gwcs");
        try {
            // 获取空闲堆垛机(电脑模式、无任务)
            List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>()
                    .eq("crn_sts", 3).eq("wrk_no", 0)
                    .eq("in_enable", "Y").eq("out_enable", "Y"));
        return R.ok("空托回流请求成功");
            // 如果没有空闲堆垛机,尝试所有可用堆垛机
            if (basCrnps.isEmpty()) {
                basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>()
                        .eq("crn_sts", 3)
                        .eq("in_enable", "Y").eq("out_enable", "Y"));
            }
            if (basCrnps.isEmpty()) {
                throw new CoolException("没有可用堆垛机,堆垛机停止或异常或禁用");
            }
            // 获取第一个可用堆垛机
            List<Integer> crnNoList = basCrnps.stream()
                    .map(BasCrnp::getCrnNo)
                    .collect(Collectors.toList());
            Integer crnNo = crnNoList.get(0);
            int workNo = commonService.getWorkNo(5);
            Date now = new Date();
            // 生成工作档
            WrkMast wrkMast = new WrkMast();
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(1L);
            wrkMast.setIoType(3); // 站到站
            wrkMast.setIoPri(14D);
            wrkMast.setCrnNo(crnNo);
            wrkMast.setSourceStaNo(secondFloorIn[crnNo]);
            wrkMast.setStaNo(secondFloorOut[crnNo]);
            wrkMast.setLocNo("");
            wrkMast.setBarcode(barcode);
            wrkMast.setFullPlt("N");
            wrkMast.setPicking("N");
            wrkMast.setExitMk("N");
            wrkMast.setEmptyMk("Y");
            wrkMast.setLinkMis("Y");
            wrkMast.setCtnType(1);
            wrkMast.setAppeTime(now);
            wrkMast.setModiTime(now);
            boolean res = wrkMastService.insert(wrkMast);
            if (!res) {
                throw new CoolException("保存工作档失败");
            }
            // 推送站点到GWCS
            pushStaNoToGwcs(param.getPalletizingNo(), wrkMast.getSourceStaNo(), workNo, barcode, "二楼空托回流推送gwcs");
            return R.ok("空托回流请求成功");
        } finally {
            // 解锁,确保只释放自己加的锁
            String val = redisTemplate.opsForValue().get(lockKey);
            if (lockVal.equals(val)) {
                redisTemplate.delete(lockKey);
            }
        }
    }
    @Override
    public R tb(TbParam param) {
@@ -1490,8 +1523,14 @@
            wrkMastService.updateById(wrkMast);
        }
        // 出库上报推送mes记录
        ckjgsbPushMes(wrkMast,wrkDetls);
        if(!wrkDetls.get(0).getMatnr().equals("空箱")){
            // 出库上报推送mes记录
            ckjgsbPushMes(wrkMast,wrkDetls);
        }else{
            wrkMast.setWrkSts(14L);
            wrkMastService.updateById(wrkMast);
        }
        return "出库结果上报成功";
    }
@@ -2005,6 +2044,15 @@
                materialDetail.setRollNo(wrkDetl.getModel());
                materialDetail.setBoxNo(wrkDetl.getUnit());
                materialDetail.setSpecs(wrkDetl.getMatnr());
                materialDetail.setBoxType(wrkDetl.getColor());
                materialDetail.setCoreType(wrkDetl.getManu());
                materialDetail.setWidth(wrkDetl.getSku());
                materialDetail.setThickness(wrkDetl.getItemNum());
                materialDetail.setWeight(wrkDetl.getWeight());
                materialDetail.setLength(wrkDetl.getLength());
                materialDetail.setVolume(wrkDetl.getVolume());
                materialDetail.setCustomerName(wrkDetl.getSupp());
                materialDetail.setMemo(wrkDetl.getMemo());
                material.setBoxPos(wrkDetl.getOrigin()); // 托盘上木箱位置
                materialDetailList.add(materialDetail);
            }
@@ -2014,14 +2062,15 @@
                Order order = orderService.selectOne(new EntityWrapper<Order>().eq("order_no", wrkDetl.getOrderNo()));
                if (order != null) {
                    material.setOrderNo(order.getOrderNo());
                    material.setMemo(order.getMemo());
                    material.setCustomerName(order.getCstmrName());
//                    material.setMemo(order.getMemo());
//                    material.setCustomerName(order.getCstmrName());
                    List<OrderStatisticsDto> unfulfilledOrders = orderMapper.getUnfulfilledOrders(order.getOrderNo());
                    if (unfulfilledOrders.size() == 1) {
                        OrderStatisticsDto orderStatisticsDto = unfulfilledOrders.get(0);
                        material.setSum(orderStatisticsDto.getSum());
                        material.setToShipQuantity(orderStatisticsDto.getToShipQuantity());
                        material.setWorkQuantity(orderStatisticsDto.getWorkQuantity());
                        material.setCompleteQuantity(orderStatisticsDto.getCompletedQuantity());
                    }
                }
            }
@@ -2087,7 +2136,7 @@
    public boolean pushStaNoToGwcs(Integer palletizingNo, Integer staNo, Integer workNo, String barcode, String message) {
        int maxRetry = 3;       // 最多重试 3 次
        long retryDelay = 3000; // 重试间隔 3 秒
        long retryDelay = 10000; // 重试间隔 10 秒
        boolean finalSuccess = false;
        Map<String, Object> headers = getHeaders();
@@ -2109,13 +2158,25 @@
                        .setPath(MesConstant.GWCS_FPKW_URL)
                        .setHeaders(headers)
                        .setJson(body)
                        .setTimeout(30, TimeUnit.SECONDS) // 设置连接 + 读取超时为30秒
                        .build()
                        .doPost();
                if (!Cools.isEmpty(response)) {
                    success = true;
                    finalSuccess = true;
                    log.info("{} 成功,响应:{}", attemptMsg, response);
                    try {
                        JSONObject resJson = JSON.parseObject(response);
                        int code = resJson.getIntValue("code"); // 视具体接口而定
                        if (code == 200) {
                            success = true;
                            finalSuccess = true;
                            log.info("{} 成功,响应:{}", attemptMsg, response);
                        } else {
                            log.warn("{} 响应失败,返回code={},完整响应:{}", attemptMsg, code, response);
                        }
                    } catch (Exception parseEx) {
                        log.warn("{} 响应解析失败,内容:{}", attemptMsg, response);
                    }
                } else {
                    log.warn("{} 失败,响应为空", attemptMsg);
                }
@@ -2155,6 +2216,7 @@
    }
    Map<String, Object> getHeaders(){
        Map<String,Object> headers = new HashMap<>();
        headers.put("digi-type","sync ");