自动化立体仓库 - WMS系统
zwl
4 天以前 5b00928c8570a3ba21a1170b4642ef88635d90da
1.对入库拍照功能解耦
1个文件已添加
7个文件已修改
155 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/InboundCameraCaptureService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/WrkMastService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/InboundCameraCaptureServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WrkMastServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/InboundCameraCaptureScheduler.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -5,6 +5,7 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -18,6 +19,11 @@
    List<WrkMast> selectToBeHistoryData();
    List<WrkMast> selectPendingInboundCameraCapture(@Param("pending") String pending, @Param("running") String running);
    @Update("update asr_wrk_mast set memo = #{next}, modi_time = getdate() where wrk_no = #{wrkNo} and memo = #{current}")
    int updateMemoIfCurrent(@Param("wrkNo") Integer wrkNo, @Param("current") String current, @Param("next") String next);
    @Select("select count(1) from asr_wrk_mast where 1=1 and io_type = #{ioType} and sta_no = #{staNo}")
    int selectWrkMastBareBoardStaNo(Integer ioType,Integer staNo);
src/main/java/com/zy/asrs/service/InboundCameraCaptureService.java
@@ -1,11 +1,20 @@
package com.zy.asrs.service;
import com.zy.asrs.entity.WrkMast;
import java.util.List;
public interface InboundCameraCaptureService {
    String CAPTURE_PENDING = "CAMERA_PENDING";
    String CAPTURE_RUNNING = "CAMERA_RUNNING";
    String CAPTURE_DONE = "CAMERA_DONE";
    String CAPTURE_FAILED = "CAMERA_FAILED";
    String capture(Integer sourceStaNo, String locNo, String barcode);
    void processPendingCapture(WrkMast wrkMast);
    List<String> resolvePicUrls(String pic);
    List<String> resolveLocPicUrls(String locNo);
src/main/java/com/zy/asrs/service/WrkMastService.java
@@ -14,6 +14,10 @@
    List<WrkMast> selectToBeHistoryData();
    List<WrkMast> selectPendingInboundCameraCapture();
    boolean updateMemoIfCurrent(Integer wrkNo, String current, String next);
    WrkMast selectByBarcode(String barcode);
    /**
src/main/java/com/zy/asrs/service/impl/InboundCameraCaptureServiceImpl.java
@@ -6,8 +6,14 @@
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.WrkDetl;
import com.zy.asrs.entity.WrkDetlLog;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.InboundCameraCaptureService;
import com.zy.asrs.service.LocDetlService;
import com.zy.asrs.service.WrkDetlLogService;
import com.zy.asrs.service.WrkDetlService;
import com.zy.asrs.service.WrkMastService;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
@@ -44,6 +50,15 @@
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private WrkDetlService wrkDetlService;
    @Autowired
    private WrkDetlLogService wrkDetlLogService;
    @Override
    public String capture(Integer sourceStaNo, String locNo, String barcode) {
@@ -83,6 +98,33 @@
    }
    @Override
    public void processPendingCapture(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getWrkNo() == null) {
            return;
        }
        String current = Cools.isEmpty(wrkMast.getMemo()) ? CAPTURE_PENDING : wrkMast.getMemo();
        if (!wrkMastService.updateMemoIfCurrent(wrkMast.getWrkNo(), current, CAPTURE_RUNNING)) {
            return;
        }
        String status = CAPTURE_FAILED;
        try {
            String pic = capture(wrkMast.getSourceStaNo(), wrkMast.getLocNo(), wrkMast.getBarcode());
            if (!Cools.isEmpty(pic)) {
                writeBackPic(wrkMast, pic);
                status = CAPTURE_DONE;
            }
        } catch (Exception e) {
            log.warn("入库异步抓拍处理异常:workNo={}, sourceStaNo={}, locNo={}, barcode={}",
                    wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), wrkMast.getLocNo(), wrkMast.getBarcode(), e);
        } finally {
            if (!wrkMastService.updateMemoIfCurrent(wrkMast.getWrkNo(), CAPTURE_RUNNING, status)) {
                log.info("入库抓拍状态回写跳过:workNo={}, status={}", wrkMast.getWrkNo(), status);
            }
        }
    }
    @Override
    public List<String> resolvePicUrls(String pic) {
        CaptureConfig config = loadConfig();
        String prefix = config == null ? "" : config.imageUrlPrefix;
@@ -113,6 +155,32 @@
        return new ArrayList<>(urls);
    }
    private void writeBackPic(WrkMast wrkMast, String pic) {
        Date now = new Date();
        WrkDetl wrkDetl = new WrkDetl();
        wrkDetl.setPic(pic);
        wrkDetl.setModiTime(now);
        wrkDetlService.update(wrkDetl, new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo()));
        WrkDetlLog wrkDetlLog = new WrkDetlLog();
        wrkDetlLog.setPic(pic);
        wrkDetlLog.setModiTime(now);
        EntityWrapper<WrkDetlLog> logWrapper = new EntityWrapper<>();
        logWrapper.eq("wrk_no", wrkMast.getWrkNo());
        if (wrkMast.getIoTime() != null) {
            logWrapper.eq("io_time", wrkMast.getIoTime());
        }
        wrkDetlLogService.update(wrkDetlLog, logWrapper);
        if (!Cools.isEmpty(wrkMast.getLocNo())) {
            LocDetl locDetl = new LocDetl();
            locDetl.setPic(pic);
            locDetl.setModiTime(now);
            locDetlService.update(locDetl, new EntityWrapper<LocDetl>().eq("loc_no", wrkMast.getLocNo()));
        }
    }
    private boolean captureOne(String captureUrl, Integer sourceStaNo, int index, JSONObject camera, String picName) {
        String ip = camera.getString("ip");
        if (Cools.isEmpty(ip)) {
src/main/java/com/zy/asrs/service/impl/WrkMastServiceImpl.java
@@ -7,6 +7,7 @@
import com.zy.asrs.entity.result.FindLocNoAttributeVo;
import com.zy.asrs.mapper.WrkMastLogMapper;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.InboundCameraCaptureService;
import com.zy.asrs.service.WrkMastService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +40,18 @@
    }
    @Override
    public List<WrkMast> selectPendingInboundCameraCapture() {
        return this.baseMapper.selectPendingInboundCameraCapture(
                InboundCameraCaptureService.CAPTURE_PENDING,
                InboundCameraCaptureService.CAPTURE_RUNNING);
    }
    @Override
    public boolean updateMemoIfCurrent(Integer wrkNo, String current, String next) {
        return this.baseMapper.updateMemoIfCurrent(wrkNo, current, next) > 0;
    }
    @Override
    public WrkMast selectByBarcode(String barcode) {
        List<WrkMast> wrkMasts = this.selectList(new EntityWrapper<WrkMast>().eq("barcode", barcode));
        if (Cools.isEmpty(wrkMasts)) {
src/main/java/com/zy/asrs/task/InboundCameraCaptureScheduler.java
New file
@@ -0,0 +1,37 @@
package com.zy.asrs.task;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.InboundCameraCaptureService;
import com.zy.asrs.service.WrkMastService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class InboundCameraCaptureScheduler {
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private InboundCameraCaptureService inboundCameraCaptureService;
    @Scheduled(cron = "0/3 * * * * ? ")
    private void execute() {
        List<WrkMast> wrkMasts = wrkMastService.selectPendingInboundCameraCapture();
        if (wrkMasts == null || wrkMasts.isEmpty()) {
            return;
        }
        for (WrkMast wrkMast : wrkMasts) {
            try {
                inboundCameraCaptureService.processPendingCapture(wrkMast);
            } catch (Exception e) {
                log.warn("入库抓拍定时任务异常:workNo={}", wrkMast == null ? null : wrkMast.getWrkNo(), e);
            }
        }
    }
}
src/main/java/com/zy/common/web/WcsController.java
@@ -58,8 +58,6 @@
    private WorkService workService;
    @Autowired
    private StaDescService staDescService;
    @Autowired
    private InboundCameraCaptureService inboundCameraCaptureService;
    @PostMapping("/pakin/loc/v1")
    @ResponseBody
@@ -497,6 +495,7 @@
            wrkMast.setUserNo(waitPakins.get(0).getOrderNo());
            wrkMast.setCubeNumber(waitPakins.get(0).getCubeNumber());
            wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
            wrkMast.setMemo(InboundCameraCaptureService.CAPTURE_PENDING);
            // 操作人员数据
            wrkMast.setAppeTime(now);
            wrkMast.setModiTime(now);
@@ -504,7 +503,6 @@
            if (!res) {
                throw new CoolException("保存工作档失败");
            }
            String pic = inboundCameraCaptureService.capture(devpNo, dto.getLocNo(), barcode);
            // 生成工作档明细
            waitPakins.forEach(waitPakin -> {
                WrkDetl wrkDetl = new WrkDetl();
@@ -514,9 +512,6 @@
                wrkDetl.setAppeTime(now);
                wrkDetl.setModiTime(now);
                wrkDetl.setWeight(wrkMast.getScWeight());
                if (!Cools.isEmpty(pic)) {
                    wrkDetl.setPic(pic);
                }
                if (!wrkDetlService.insert(wrkDetl)) {
                    throw new CoolException("保存工作明细失败");
                }
src/main/resources/mapper/WrkMastMapper.xml
@@ -86,6 +86,17 @@
        order by io_time,wrk_no asc
    </select>
    <select id="selectPendingInboundCameraCapture" resultMap="BaseResultMap">
        select top 5 *
        from asr_wrk_mast
        where io_type = 1
        and (
            memo = #{pending}
            or (memo = #{running} and dateadd(mi, 5, modi_time) &lt;= getdate())
        )
        order by io_time, wrk_no
    </select>
    <select id="selectWrkMast" resultMap="BaseResultMap">
        select top 1 *
        from asr_wrk_mast