自动化立体仓库 - WMS系统
#
zwl
7 小时以前 44b6b79dd5dee0ebbd2d11b08abbc2be275bed58
#
6个文件已添加
55个文件已修改
2117 ■■■■ 已修改文件
src/main/java/com/zy/api/controller/HmesApiController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/WcsApiController.java 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/params/WorkTaskParams.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/entity/CrnProtocol.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/entity/DeviceConfig.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/entity/DeviceStatusVo.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/entity/DualCrnProtocol.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/entity/StationProtocol.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/HmesApiService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/WcsApiService.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java 400 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocMastController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderPakinController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderPakoutController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OutController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/WaitPakinController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/WrkMastLogController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasCrnp.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocAroundBind.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocMast.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/Mat.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WaitPakin.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMast.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMastLog.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/OpenOrderPakoutParam.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/QueryTaskParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/WaitPakinService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderPakinServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderPakoutServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WaitPakinServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WrkMastLogServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/WorkMastScheduler.java 146 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkLogHandler.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/OrderExcelListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/DetlDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/LocTypeDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/StartupDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/param/SearchLocParam.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocAroundBindMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/StaDescMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastLogMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locMast/locMast.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakout/order.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/waitPakin/waitPakin.js 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locMast/locMast.html 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locMast/locMast_detail.html 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/HmesApiController.java
@@ -2,9 +2,11 @@
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.service.HmesApiService;
import com.zy.asrs.entity.param.OpenOrderPakoutParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,15 +31,21 @@
     * @date 2026/1/10 10:40
     * @return com.core.common.R
     */
    @ManagerAuth
//    @ManagerAuth
    @ApiOperation("下发生产任务")
    @PostMapping("/work/tasks")
    public R menauWork(@RequestBody ReceviceTaskParams params) {
    public R menauWork(@RequestBody OpenOrderPakoutParam params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
            return R.error("机台号不能为空!!");
        if (Cools.isEmpty(params.getOrderNo())) {
            return R.error("单据编号[orderNo]不能为空");
        }
        if (Cools.isEmpty(params.getBillType())) {
            return R.error("单据类型[BillType]不能为空");
        }
        if (Cools.isEmpty(params.getMatList())) {
            return R.error("单据明细[orderDetails]不能为空");
        }
        return hmesApiService.pubWorkTask(params);
@@ -50,14 +58,14 @@
     * @param params
     * @return com.core.common.R
     */
    @ManagerAuth
//    @ManagerAuth
    @ApiOperation("穿线完成")
    @PostMapping("/work/release/lock")
    public R releaseLock(@RequestBody ReceviceTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
        if (Objects.isNull(params.getDevNo())) {
            return R.error("机台号不能为空!!");
        }
src/main/java/com/zy/api/controller/WcsApiController.java
@@ -1,19 +1,23 @@
package com.zy.api.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.controller.params.WorkTaskParams;
import com.zy.api.service.WcsApiService;
import com.zy.asrs.entity.LocAroundBind;
import com.zy.asrs.entity.WaitPakin;
import com.zy.asrs.service.LocAroundBindService;
import com.zy.asrs.service.WaitPakinService;
import com.zy.asrs.utils.Utils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
@Api("WCS交互接口")
@@ -23,7 +27,11 @@
    @Autowired
    private WcsApiService wcsApiService;
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    /**
     * 通知WCS锁定周边库位,及禁止任务执行
     * @author Ryan
@@ -37,7 +45,7 @@
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
        if (Objects.isNull(params.getDevNo())) {
            return R.error("机台号不能为空!!");
        }
@@ -52,10 +60,10 @@
     * @param params
     * @return com.core.common.R
     */
    @ManagerAuth
//    @ManagerAuth
    @ApiOperation("堆垛机回库搬运指令")
    @PostMapping("/back/loc")
    public R backLoc(@RequestBody WorkTaskParams params) {
    public synchronized R backLoc(@RequestBody String params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
@@ -81,7 +89,7 @@
    }
    @ManagerAuth
    @ApiOperation("设备执行状态回写")
    @ApiOperation("设备执行状态回写-wcs任务完成回写")
    @PostMapping("/openapi/report")
    public R receviceTaskFromWcs(@RequestBody ReceviceTaskParams params) {
        if (Objects.isNull(params)) {
@@ -91,5 +99,51 @@
    }
    @ManagerAuth
    @ApiOperation("获取组托入库托盘信息")
    @PostMapping("/openapi/waitPakins")
    public R waitPakins() {
        List<WaitPakin> waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("io_status", "N"));
        return R.ok().add(waitPakins);
    }
    @ManagerAuth
    @ApiOperation("获取机台库位的数组")
    @GetMapping("/openapi/arr")
    public R arr() {
        int i = 0;
        int[] k = new  int[] { 3, 0, 4, 1, 5, 2};
        int c=0;
        int h=0;
        int i1 = 15;
        List<LocAroundBind> locAroundBinds = locAroundBindService.selectList(new EntityWrapper<LocAroundBind>().orderBy("dev_id"));
        String[] arr = new String[90];
        for (LocAroundBind locAroundBind : locAroundBinds) {
            String s = Utils.WMSLocToWCSLoc(locAroundBind.getBlocNo());
            int index = i*6+k[c];
            arr[index] = s;
            c++;
            if (c==k.length) {
                c=0;
                i++;
            }
            if (i==i1){
                i=0;
                h++;
                System.out.print("[");
                for (int j=0;j<i1*6;j++){
                    System.out.print(arr[j]+",");
                }
                System.out.println("]");
                if (h==2){
                    i1 = 13;
                }else if (h==3){
                   i1 = 8;
                }
            }
        }
        return R.ok();
    }
}
src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java
@@ -14,7 +14,7 @@
public class ReceviceTaskParams implements Serializable {
    @ApiModelProperty("机台号")
    private String deviceNo;
    private String devNo;
    @ApiModelProperty("流水号")
    private Integer id;
@@ -29,7 +29,7 @@
    private String taskNo;
    @ApiModelProperty("WMS任务号")
    private String wrkNo;
    private String superTaskNo;
    @ApiModelProperty("消息类型:task_complete、task_cancel")
    private String msgType;
@@ -43,4 +43,7 @@
    @ApiModelProperty("重量")
    private Double weight;
    @ApiModelProperty("Y:冻结  N:解冻")
    private String freeze;
}
src/main/java/com/zy/api/controller/params/WorkTaskParams.java
@@ -24,6 +24,12 @@
    @ApiModelProperty("库位编码")
    private String locNo;
    //源库位
    private String sourceLocNo;
    //源站点
    private String sourceStaNo;
    @ApiModelProperty("条码")
    private String barcode;
@@ -39,4 +45,5 @@
    @ApiModelProperty("是否余料")
    private Integer isSuplus;
}
src/main/java/com/zy/api/entity/CrnProtocol.java
New file
@@ -0,0 +1,48 @@
package com.zy.api.entity;
import lombok.Data;
import java.util.Map;
@Data
public class CrnProtocol {
    private Integer crnNo;
    private Integer mode;           // 1=Manual, 2=Auto, 3=Computer
    private Object modeType;        // Enum: CrnModeType
    private Integer alarm;          // Error code
    private Integer taskNo;         // Task number
    private Integer status;         // Current status code
    private Object statusType;      // Enum: CrnStatusType
    private Integer bay;            // Current bay
    private Integer level;          // Current level
    private Integer forkPos;        // Fork position code
    private Object forkPosType;     // Enum: CrnForkPosType
    private Integer liftPos;        // Lift position code
    private Object liftPosType;     // Enum: CrnLiftPosType
    private Integer walkPos;        // 0=In Position, 1=Not in Position
    private Integer loaded;         // 1=Loaded, 0=Empty
    // Speed and Distance
    private Double xSpeed;
    private Double ySpeed;
    private Double zSpeed;
    private Double xDistance;
    private Double yDistance;
    private Double xDuration;
    private Double yDuration;
    // Other Info
    private String lastIo;          // "I"=Inbound, "O"=Outbound
    private Integer crnLane;        // Lane number
    private float weight;
    private String barcode;
    private Long deviceDataLog;
    private Long lastCommandTime;
    // Reserved/Temp
    private Integer temp1;
    private Integer temp2;
    private Integer temp3;
    private Integer temp4;
    private Map<String, Object> extend;
}
src/main/java/com/zy/api/entity/DeviceConfig.java
New file
@@ -0,0 +1,18 @@
package com.zy.api.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class DeviceConfig implements Serializable {
    private Integer id;
    private String ip;
    private Integer port;
    private String threadImpl;
    private Date createTime;
    private String deviceType;
    private Integer deviceNo;
    private Integer fake;
    private String fakeInitStatus;
}
src/main/java/com/zy/api/entity/DeviceStatusVo.java
New file
@@ -0,0 +1,32 @@
package com.zy.api.entity;
import lombok.Data;
import java.util.List;
/**
 * Device Status Response Object
 * Corresponds to the map returned by OpenController.getDeviceStatus
 */
@Data
public class DeviceStatusVo {
    /**
     * Stacker Crane (CRN) Data List
     */
    private List<CrnProtocol> crnList;
    /**
     * RGV Device Config List
     * Note: The controller returns the DeviceConfig list for RGV, not the protocol status list.
     */
    private List<DeviceConfig> rgvList;
    /**
     * Dual-Station Stacker Crane Data List
     */
    private List<DualCrnProtocol> dualCrnList;
    /**
     * Conveyor Station Data List
     */
    private List<StationProtocol> stationList;
}
src/main/java/com/zy/api/entity/DualCrnProtocol.java
New file
@@ -0,0 +1,64 @@
package com.zy.api.entity;
import lombok.Data;
import java.util.Map;
@Data
public class DualCrnProtocol {
    private Integer crnNo;
    private Integer mode;
    private Object modeType;        // Enum: DualCrnModeType
    private Integer alarm;
    // Station 1 Data
    private Integer taskNo;
    private Integer status;
    private Object statusType;      // Enum: DualCrnStatusType
    private Integer bay;
    private Integer level;
    private Integer forkPos;
    private Object forkPosType;     // Enum: DualCrnForkPosType
    private Integer liftPos;
    private Object liftPosType;     // Enum: DualCrnLiftPosType
    private Integer walkPos;
    private Integer loaded;
    private Integer taskReceive;
    // Station 2 Data
    private Integer taskNoTwo;
    private Integer statusTwo;
    private Object statusTypeTwo;
    private Integer bayTwo;
    private Integer levelTwo;
    private Integer forkPosTwo;
    private Object forkPosTypeTwo;
    private Integer liftPosTwo;
    private Object liftPosTypeTwo;
    private Integer walkPosTwo;
    private Integer loadedTwo;
    private Integer taskReceiveTwo;
    // Movement Data (Integer type in DualCrnProtocol)
    private Integer xSpeed;
    private Integer ySpeed;
    private Integer zSpeed;
    private Integer xDistance;
    private Integer yDistance;
    private Integer xDuration;
    private Integer yDuration;
    // Other Info
    private Integer goodsType;
    private String barcode;
    private String lastIo;
    private Integer crnLane;
    private Long deviceDataLog;
    private Long lastCommandTime;
    // Reserved/Temp
    private Integer temp1;
    private Integer temp2;
    private Integer temp3;
    private Integer temp4;
    private Map<String, Object> extend;
}
src/main/java/com/zy/api/entity/StationProtocol.java
New file
@@ -0,0 +1,28 @@
package com.zy.api.entity;
import lombok.Data;
import java.util.Map;
@Data
public class StationProtocol {
    private Integer stationId;      // Station ID
    private Integer taskNo;         // Task number
    private Integer targetStaNo;    // Target Station ID
    // Status Flags
    private boolean autoing;        // Auto mode
    private boolean loading;        // Has goods
    private boolean inEnable;       // Inbound enabled
    private boolean outEnable;      // Outbound enabled
    private boolean emptyMk;        // Empty pallet mark
    private boolean fullPlt;        // Full pallet
    private boolean runBlock;       // Running blocked
    private boolean enableIn;       // Start inbound
    private Integer palletHeight;
    private Integer error;          // Error code
    private String errorMsg;        // Error message
    private String barcode;
    private Double weight;
    private Map<String, Object> extend;
}
src/main/java/com/zy/api/service/HmesApiService.java
@@ -2,10 +2,11 @@
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.asrs.entity.param.OpenOrderPakoutParam;
public interface HmesApiService {
    R pubWorkTask(ReceviceTaskParams params);
    R pubWorkTask(OpenOrderPakoutParam params);
    R releaseLock(ReceviceTaskParams params);
}
src/main/java/com/zy/api/service/WcsApiService.java
@@ -24,7 +24,7 @@
     * @param params
     * @return com.core.common.R
     */
    R backLocs(WorkTaskParams params);
    R backLocs(String params);
    /**
     * 下发任务至WCS
@@ -53,4 +53,7 @@
     * @return com.core.common.R
     */
    R receviceTaskFromWcs(ReceviceTaskParams params);
    //输入库位自动冻结算出相邻库位序号
    Integer[] freezeLocAround(Integer locId);
}
src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java
@@ -443,7 +443,7 @@
                orderItem.setMatnr(matnr.getMatnr());
                orderItem.setMaktx(matnr.getMaktx());
                orderItem.setBrand(matnr.getBrand());
                orderItem.setBatch(1 + "");
                orderItem.setBatch("");
                orderItem.setStandby1(item.getPro_id());
                // 关联上加派工单号+零件代码+供应商代码
                orderItem.setThreeCode(item.getTotal_serial());
src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java
@@ -1,26 +1,27 @@
package com.zy.api.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.R;
import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.service.HmesApiService;
import com.zy.api.service.WcsApiService;
import com.zy.asrs.entity.BasDevice;
import com.zy.asrs.entity.LocAroundBind;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.param.OpenOrderPakoutParam;
import com.zy.asrs.enums.LocStsType;
import com.zy.asrs.service.BasDeviceService;
import com.zy.asrs.service.LocAroundBindService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.LocDetlServiceImpl;
import com.zy.asrs.service.impl.OrderDetlPakoutServiceImpl;
import com.zy.asrs.service.impl.OrderPakoutServiceImpl;
import com.zy.common.model.DetlDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
@Service
@@ -37,54 +38,149 @@
    @Autowired
    private WcsApiService wcsApiService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private DocTypeService docTypeService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private MatService matService;
    @Autowired
    private OrderDetlService orderDetlService;
    @Autowired
    private OrderPakoutServiceImpl orderPakoutService;
    @Autowired
    private OrderDetlPakoutServiceImpl orderDetlPakoutService;
    @Autowired
    private LocDetlServiceImpl locDetlService;
    /**
     * 接收MES穿线任务
     * @author Ryan
     * @date 2026/1/10 10:54
     * @param params
     * @param param
     * @return com.core.common.R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R pubWorkTask(ReceviceTaskParams params) {
        if (Objects.isNull(params) || Objects.isNull(params.getDeviceNo())) {
            return R.error("参数不能为空!!");
        }
        BasDevice basDevice = basDeviceService.selectOne(new EntityWrapper<BasDevice>()
                .eq("status", 1)
                .eq("dev_no", params.getDeviceNo()));
        if (Objects.isNull(basDevice)) {
            throw new CoolException("机台信息不存在或已禁用!!");
        }
        List<LocAroundBind> binds = locAroundBindService.selectList(new EntityWrapper<LocAroundBind>().eq("dev_no", basDevice.getDevNo()));
        if (Objects.isNull(binds) || binds.isEmpty()) {
            throw new CoolException("机台未绑定工作站台!!");
        }
        Set<String> locs = binds.stream().map(LocAroundBind::getBlocNo).collect(Collectors.toSet());
        LocMast locMasts = locMastService.selectOne(new EntityWrapper<LocMast>()
                .in("loc_no", locs)
                .eq("loc_sts", LocStsType.LOC_STS_TYPE_F.type)
                .orderAsc(Arrays.asList("loc_no"))
                .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY"));
        if (Objects.isNull(locMasts)) {
            throw new CoolException("未查到可工作线轴!!");
        }
        //todo 锁库位需WCS锁定(相关库位,不可执行任务操作,不能只在WMS锁定)
        List<LocMast> locMs = locMastService.selectList(new EntityWrapper<LocMast>()
                .eq("frozen", 0).eq("deleted", 0)
                .in("loc_no", locs)
                .eq("loc_sts", LocStsType.LOC_STS_TYPE_O.type));
        locMs.forEach(loc -> {
            loc.setLocSts(LocStsType.LOC_STS_TYPE_X.type);
            if (!locMastService.updateById(loc)) {
                throw new CoolException("工作台周边库位禁用失败,不可执行穿线操作!!");
    public R pubWorkTask(OpenOrderPakoutParam param) {
        OrderPakout order = orderPakoutService.selectByNo(param.getOrderNo());
        // 如果单据不存在则添加;如果单据存在,作业中无法修改,反之则修改单据
        if (!Cools.isEmpty(order)) {
            if (order.getSettle() > 1L) {
                throw new CoolException(param.getOrderNo() + "正在出库,无法修改单据");
            }
        });
        return R.ok("可执行穿线动作!!");
            orderPakoutService.remove(order.getId());
        }
        DocType docType = docTypeService.selectOrAdd(param.getBillType(), Boolean.FALSE);
        Date now = new Date();
        // 单据主档
        order = new OrderPakout(
                String.valueOf(snowflakeIdWorker.nextId()),    // 编号[非空]
                param.getOrderNo(),    // 订单编号
                DateUtils.convert(now),    // 单据日期
                docType.getDocId(),    // 单据类型
                null,    // 项目编号
                null,    //
                null,    // 调拨项目编号
                null,    // 初始票据号
                null,    // 票据号
                null,    // 客户编号
                null,    // 客户
                null,    // 联系方式
                null,    // 操作人员
                null,    // 合计金额
                null,    // 优惠率
                null,    // 优惠金额
                null,    // 销售或采购费用合计
                null,    // 实付金额
                null,    // 付款类型
                null,    // 业务员
                null,    // 结算天数
                null,    // 邮费支付类型
                null,    // 邮费
                null,    // 付款时间
                null,    // 发货时间
                null,    // 物流名称
                null,    // 物流单号
                1L,    // 订单状态
                1,    // 状态
                9995L,    // 添加人员
                now,    // 添加时间
                9995L,    // 修改人员
                now,    // 修改时间
                null    // 备注
        );
        if (!orderPakoutService.insert(order)) {
            throw new CoolException("生成单据主档失败,请联系管理员");
        }
        // 单据明细档
        List<DetlDto> list = new ArrayList<>();
        List<DetlDto> orderDetails = param.getMatList();
        for (DetlDto detail : orderDetails) {
            DetlDto dto = new DetlDto(detail.getMatnr(), detail.getBatch(),detail.getBrand(),detail.getDevNo(),detail.getStandby2(),detail.getStandby3(),detail.getLineNumber(),
                    detail.getBoxType1(),detail.getBoxType2(),detail.getBoxType3(), detail.getAnfme());
            if (DetlDto.hasLineNumber(list, dto)) {
                DetlDto detlDto = DetlDto.findLineNumber(list, dto.getMatnr(), dto.getBatch(),dto.getBrand(),dto.getDevNo(),dto.getStandby2(),dto.getStandby3(),dto.getLineNumber(),
                        dto.getBoxType1(),dto.getBoxType2(),dto.getBoxType3());
                assert detlDto != null;
                detlDto.setAnfme(detlDto.getAnfme() + detail.getAnfme());
            } else {
                list.add(dto);
            }
        }
        //下发的订单明细,查看库存是否有足够的库存,排除机台的库位
        for (DetlDto detail : list) {
            List<LocDetl> matnr = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr", detail.getMatnr()));
            Double count=0.0;
            for (LocDetl detl : matnr) {
                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", detl.getLocNo()).eq("loc_sts","F"));
                if (locMast != null) {
                    LocAroundBind bLocNo = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_no", locMast.getLocNo()));
                    if (Cools.isEmpty(bLocNo)) {
                        count=detl.getAnfme()+count;
                    }
                }
            }
            if (count<detail.getAnfme()) {
                return R.error("物料="+detail.getMatnr()+"库存不足无法生成订单");
            }
        }
        for (DetlDto detlDto : list) {
            Mat mat = matService.selectByMatnr(detlDto.getMatnr());
            if (Cools.isEmpty(mat)) {
                throw new CoolException(detlDto.getMatnr() + "编号商品检索失败,请先添加商品");
            }
            OrderDetlPakout orderDetl = new OrderDetlPakout();
            orderDetl.sync(mat);
            orderDetl.setLineNumber(detlDto.getLineNumber());
            orderDetl.setBatch(detlDto.getBatch());
            orderDetl.setAnfme(detlDto.getAnfme());
            orderDetl.setBrand(detlDto.getBrand());
            orderDetl.setStandby1(detlDto.getStandby1());
            orderDetl.setStandby2(detlDto.getStandby2());
            orderDetl.setStandby3(detlDto.getStandby3());
            orderDetl.setOrderId(order.getId());
            orderDetl.setOrderNo(order.getOrderNo());
            orderDetl.setCreateBy(9527L);
            orderDetl.setCreateTime(now);
            orderDetl.setUpdateBy(9527L);
            orderDetl.setUpdateTime(now);
            orderDetl.setStatus(1);
            orderDetl.setQty(0.0D);
            orderDetl.setPakinPakoutStatus(2);
            if (!orderDetlPakoutService.insert(orderDetl)) {
                throw new CoolException("生成单据明细失败,请联系管理员");
            }
        }
        return  R.ok();
    }
    /**
@@ -97,37 +193,31 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R releaseLock(ReceviceTaskParams params) {
        if (Objects.isNull(params) || Objects.isNull(params.getDeviceNo())) {
        if (Objects.isNull(params) || Objects.isNull(params.getDevNo())) {
            return R.error("参数不能为空!!");
        }
        Integer frozen = params.getFreeze().equals("Y") ? 1 : 0;
        String s = params.getFreeze().equals("Y") ? "冻结" : "解冻";
        BasDevice basDevice = basDeviceService.selectOne(new EntityWrapper<BasDevice>()
                .eq("status", 1)
                .eq("dev_no", params.getDeviceNo()));
                .eq("dev_no", params.getDevNo()));
        if (Objects.isNull(basDevice)) {
            throw new CoolException("机台信息不存在或已禁用!!");
        }
        List<LocAroundBind> binds = locAroundBindService.selectList(new EntityWrapper<LocAroundBind>().eq("dev_no", basDevice.getDevNo()));
        List<LocAroundBind> binds = locAroundBindService.selectList(new EntityWrapper<LocAroundBind>()
                .eq("dev_no", basDevice.getType())
                .eq("freeze", frozen==1? 0:1));
        if (Objects.isNull(binds) || binds.isEmpty()) {
            throw new CoolException("机台未绑定工作站台!!");
        }
        Set<String> locs = binds.stream().map(LocAroundBind::getBlocNo).collect(Collectors.toSet());
        List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().in("loc_no", locs)
                .eq("frozen", 0).eq("deleted", 0)
                .eq("loc_sts", LocStsType.LOC_STS_TYPE_X.type));
        if (Objects.isNull(locMasts) || locMasts.isEmpty()) {
            throw new CoolException("没有禁用库位,不需要释放!!");
            throw new CoolException("机台不需要"+s+"!!");
        }
        locMasts.forEach(loc -> {
           loc.setLocSts(LocStsType.LOC_STS_TYPE_O.type);
           if (!locMastService.updateById(loc)) {
               throw new CoolException("库位释放失败,请检查后再操作!!");
        binds.forEach(loc -> {
           loc.setFreeze(frozen);
           if (!locAroundBindService.updateById(loc)) {
               throw new CoolException("库位"+s+"失败,请检查后再操作!!");
           }
        });
//        wcsApiService.reportLockLocs(locs, "lock");
        return R.ok("释放成功 !!");
        return R.ok(s+"成功 !!");
    }
}
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
@@ -11,13 +11,14 @@
import com.zy.api.service.WcsApiService;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.LocDetlServiceImpl;
import com.zy.asrs.service.impl.MatServiceImpl;
import com.zy.asrs.service.impl.WrkDetlServiceImpl;
import com.zy.asrs.utils.Utils;
import com.zy.common.constant.MesConstant;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -28,6 +29,7 @@
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Service
public class WcsApiServiceImpl implements WcsApiService {
@@ -47,6 +49,19 @@
    private MatService matService;
    @Autowired
    private LocDetlService locDetlService;
    @Value("${wcs.address.URL}")
    private String wcs_address;
    @Value("${wcs.address.createOutTask}")
    private String getWcs_address;
    @Value("${wcs.address.createInTask}")
    private String createInTask;
    @Value("${wcs.address.createLocMoveTask}")
    private String createLocMoveTask;
    @Autowired
    private CommonService commonService;
    /**
     * 通知WCS锁定库位,及禁止当前库位的一切操作
@@ -61,7 +76,7 @@
    public R lockLocs(ReceviceTaskParams params) {
        BasDevice basDevice = basDeviceService.selectOne(new EntityWrapper<BasDevice>()
                .eq("status", 1)
                .eq("dev_no", params.getDeviceNo()));
                .eq("dev_no", params.getDevNo()));
        if (Objects.isNull(basDevice)) {
            throw new CoolException("机台信息不存在或已禁用!!");
        }
@@ -86,15 +101,15 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R backLocs(WorkTaskParams params) {
        if (Objects.isNull(params.getWrkNo())) {
            throw new CoolException("工作号不能为空!!");
        }
    public R backLocs(String params) {
//        if (Objects.isNull(params.getWrkNo())) {
//            throw new CoolException("工作号不能为空!!");
//        }
//        String wrkCode = params.getTaskNo();
//       if (wrkCode.contains("-1")) {
//           throw new CoolException("配对任务编码错误,请检查后重新上传!!");
//       }
        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getWrkNo()));
        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", params));
        if (Objects.isNull(mast)) {
            throw new CoolException("任务不存在!!");
        }
@@ -132,27 +147,98 @@
        if (Objects.isNull(params.getLocNo())) {
            return R.error("目标库位不能为空!!");
        }
        String url = MesConstant.PUB_TASK_IN;
        if (Objects.isNull(params.getType()) && params.getType().equals("out")) {
            url = MesConstant.PUB_TASK_OUT;
        String url = createInTask;
        if (!Objects.isNull(params.getType()) && params.getType().equals("out")) {
            url = getWcs_address;
        }else if (!Objects.isNull(params.getType()) && params.getType().equals("move")) {
            url = createLocMoveTask;
        }
        String response;
        R r = R.ok();
        try {
            log.info("下发搬运任务给wcs="+JSON.toJSONString(params));
            response = new HttpHandler.Builder()
                    .setUri(MesConstant.URL)
                    .setUri(wcs_address)
                    .setPath(url)
                    .setJson(JSON.toJSONString(params))
                    .build()
                    .doPost();
            R result = JSON.parseObject(response, R.class);
            JSONObject jsonObject = JSON.parseObject(response);
            log.info("下发任务给wcs的返回值="+response);
            Integer code = jsonObject.getInteger("code");
            if (result.get("code").equals("200")) {
            if (code==200) {
                WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getTaskNo()));
                if (!Objects.isNull(wrkMast)) {
                    if (wrkMast.getIoType()==1 || wrkMast.getIoType()==10) {
                        wrkMast.setWrkSts(2L);
                        wrkMast.setModiTime(new Date());
                        wrkMastService.updateById(wrkMast);
                    }else if(wrkMast.getIoType()==2){
                        wrkMast.setWrkSts(2L);
                        wrkMast.setModiTime(new Date());
                        wrkMastService.updateById(wrkMast);
                        String s = Utils.convertLocFormat(params.getLocNo());
                        LocAroundBind bind = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>()
                                .eq("b_loc_no", s));
                        if (!Objects.isNull(bind)) {
                            bind.setFreeze(1);
                            locAroundBindService.updateById(bind);
                            //冻结相邻库位
                            Integer[] aroundIds = freezeLocAround(bind.getOrderNo());
                            if (aroundIds != null) {
                                for (Integer id : aroundIds) {
                                    if (id != null && id > 0) {
                                        LocAroundBind aroundBind = locAroundBindService.selectOne(
                                                new EntityWrapper<LocAroundBind>()
                                                        .eq("dev_id", bind.getDevId())
                                                        .eq("order_no", id));
                                        if (aroundBind != null) {
                                            aroundBind.setFreeze(1);
                                            locAroundBindService.updateById(aroundBind);
                                        }
                                    }
                                }
                            }
                        }
                    }else if (wrkMast.getIoType()==101){
                        wrkMast.setWrkSts(12L);
                        wrkMast.setModiTime(new Date());
                        wrkMastService.updateById(wrkMast);
                        //出库为机台工位时,冻结相对有的库位,及相邻库位
                        String s = Utils.convertLocFormat(params.getLocNo());
                        LocAroundBind bind = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>()
                                .eq("b_loc_no", s));
                        if (!Objects.isNull(bind)&&Cools.isEmpty(wrkMast.getStaNo())) {
                            bind.setFreeze(1);
                            locAroundBindService.updateById(bind);
                            //冻结相邻库位
                            Integer[] aroundIds = freezeLocAround(bind.getOrderNo());
                            if (aroundIds != null) {
                                for (Integer id : aroundIds) {
                                    if (id != null && id > 0) {
                                        LocAroundBind aroundBind = locAroundBindService.selectOne(
                                                new EntityWrapper<LocAroundBind>()
                                                        .eq("dev_id", bind.getDevId())
                                                        .eq("order_no", id));
                                        if (aroundBind != null) {
                                            aroundBind.setFreeze(1);
                                            locAroundBindService.updateById(aroundBind);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                //TODO 上报是否成功
            }else {
                r =R.error();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
        return r;
    }
@@ -202,70 +288,129 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R receviceTaskFromWcs(ReceviceTaskParams params) {
        if (Objects.isNull(params.getWrkNo())) {
        log.info("wcs任务反馈="+JSON.toJSONString(params));
        if (Objects.isNull(params.getSuperTaskNo())) {
            throw new CoolException("WMS任务号不能为空!!");
        }
        if (Objects.isNull(params.getNotifyType())) {
            throw new CoolException("动作类型不能为空!!");
        }
        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getWrkNo()));
        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getSuperTaskNo()));
        if (Objects.isNull(mast)) {
            throw new CoolException("任务档不存在!!");
        }
        if (params.getNotifyType().equals("task")) {
            //任务
            if (params.getMsgType().equals("task_complete")) {
                if (!Objects.isNull(mast.getWrkCode())) {
                    if (mast.getOveMk().equals("N") && !Cools.isEmpty(mast.getIsSuplus())) {
                        throw new CoolException("任务未上报重量,无法完结任务!!");
                //称重
                if ((mast.getIoType()==1||mast.getIoType()==10)&&mast.getWrkSts() == 2 && Cools.isEmpty(mast.getStaNo())) {
                    Double weight = 0.0;
                    if (!Cools.isEmpty(params.getData())){
                        JSONObject jsonObject = JSONObject.parseObject(params.getData());
                        weight=jsonObject.getDouble("weight");
                    }
                }
                if (mast.getIoType() == 1) {
                    mast.setWrkSts(4L);
                } else if (mast.getIoType() == 101) {
                    mast.setWrkSts(14L);
                }
                if (!wrkMastService.updateById(mast)) {
                    throw new CoolException("任务状态修改失败!!");
                }
            } else if (params.getMsgType().equals("task_cancel")) {
                //todo 取消任务
            }
        } else if (params.getNotifyType().equals("weight")) {
            //称重
            if (mast.getWrkSts() == 2) {
                if (mast.getIoType() == 10) {
                    //空板入库任务档
                    LocDetl locDetl = locDetlService.selectOne(new EntityWrapper<LocDetl>()
                            .eq("barcode", mast.getBarcode())
                            .eq("loc_no", mast.getSourceLocNo()));
                    if (Objects.isNull(locDetl)) {
                        throw new CoolException("明细数据不存在!!");
                    }
                    Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", locDetl.getMatnr()));
                    if (Objects.isNull(matnr)) {
                        throw new CoolException("物料基础信息不存在!!");
                    }
                    Double val = Math.round((params.getWeight() - matnr.getSafeQty()) * 10000) / 10000.0;
                    if (val.compareTo(0.0) > 0) {
                        WrkDetl wrkDetl = new WrkDetl();
                        BeanUtils.copyProperties(locDetl, wrkDetl);
                        wrkDetl.setWrkNo(mast.getWrkNo());
                        wrkDetl.setStockQty(locDetl.getAnfme());
                        wrkDetl.setIoTime(new Date());
                        wrkDetl.setWeight(params.getWeight());
                        //余料长度
                        wrkDetl.setAnfme(val * matnr.getVolume());
                        mast.setIoType(1);
                        mast.setIsSuplus(1);
                    if (mast.getIoType() == 10) {
                        //空板入库任务档
                        LocDetl locDetl = locDetlService.selectOne(new EntityWrapper<LocDetl>()
                                .eq("zpallet", mast.getBarcode())
                                .eq("loc_no", mast.getSourceLocNo()));
                        if (Objects.isNull(locDetl)) {
                            throw new CoolException("明细数据不存在!!");
                        }
                        Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", locDetl.getMatnr()));
                        if (Objects.isNull(matnr)) {
                            throw new CoolException("物料基础信息不存在!!");
                        }
                        if (!Cools.isEmpty(weight)) {
                            Double val = Math.round((weight - matnr.getSafeQty()) * 10000) / 10000.0;
                            if (val.compareTo(0.0) > 0) {
                                WrkDetl wrkDetl = new WrkDetl();
                                BeanUtils.copyProperties(locDetl, wrkDetl);
                                wrkDetl.setWrkNo(mast.getWrkNo());
                                wrkDetl.setStockQty(locDetl.getAnfme());
                                wrkDetl.setIoTime(new Date());
                                wrkDetl.setWeight(weight);
                                wrkDetl.setIoTime(mast.getIoTime());
                                //余料长度
                                wrkDetl.setAnfme(val * matnr.getVolume());
                                if (!wrkDetlService.insert(wrkDetl)){
                                    throw new CoolException("无法新增明细!!");
                                }
                                mast.setIoType(1);
                                mast.setIsSuplus(1);
                                mast.setOveMk("Y");
                                if (!wrkMastService.updateById(mast)) {
                                    throw new CoolException("任务档修改失败!!");
                                }
                                // 更新原出库单
                                if (!Cools.isEmpty(mast.getWrkCode())) {
                                    String wrkNo = mast.getWrkCode();
                                    WrkMast orgWrk = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", wrkNo));
                                    if (Objects.isNull(orgWrk)) {
                                        throw new CoolException("数据错误,主任务档不存在或已删除!!");
                                    }
                                    orgWrk.setOveMk("Y");
                                    if (!wrkMastService.updateById(orgWrk)) {
                                        throw new CoolException("任务档修改失败!!");
                                    }
                                    WrkDetl detl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo));
                                    if (Objects.isNull(detl)) {
                                        throw new CoolException("子任务档明细不存在!!");
                                    }
//                                    //库存减去称重长度
//                                    Double v = Math.round((wrkDetl.getStockQty() - realQty) * 10000) / 10000.0;
//                                    //原出为数量与真实数量互换,保持一致性
//                                    detl.setAnfme(v);
//                                    detl.setWeight(weight);
                                    if (!wrkDetlService.update(detl, new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo).eq("matnr", detl.getMatnr()).eq("barcode", detl.getBarcode()))) {
                                        throw new CoolException("原任务档明细修改失败!!");
                                    }
                                } else {
                                    throw new CoolException("任务号截取失败,请检查主任务档任档wrkCode字段");
                                }
                            }
                        }
                    } else {
                        WrkDetl wrkDetl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", mast.getWrkNo()));
                        if (Objects.isNull(wrkDetl)) {
                            throw new CoolException("数据错误,任务明细不存在!!");
                        }
                        Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", wrkDetl.getMatnr()));
                        if (Objects.isNull(matnr)) {
                            throw new CoolException("物料基础信息不存在!!");
                        }
                        Double realQty = Math.round((wrkDetl.getStockQty() - wrkDetl.getAnfme()) * 10000) / 10000.0;
                        if (!Cools.isEmpty(weight)) {
                            Double val = Math.round((weight - 2.35) * 10000) / 10000.0;
                            //称重后,计算出真实长度
                            realQty = val * matnr.getVolume();
                            if (realQty<matnr.getSafeQty()){
                                wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkDetl.getWrkNo()));
                                mast.setIoType(10);
                                mast.setEmptyMk("Y");
                            }else{
                                wrkDetl.setAnfme(realQty);
                                wrkDetl.setWeight(weight);
                                if (!wrkDetlService.update(wrkDetl, new EntityWrapper<WrkDetl>().eq("wrk_no", mast.getWrkNo()).eq("matnr", wrkDetl.getMatnr()).eq("barcode", wrkDetl.getBarcode()))) {
                                    throw new CoolException("任务档明细修改失败!!");
                                }
                            }
                        }
                        mast.setOveMk("Y");
                        if (!wrkMastService.updateById(mast)) {
                            throw new CoolException("任务档修改失败!!");
                        }
                        // 更新原出库单
                        int indexOf = mast.getWrkCode().indexOf("-1");
                        if (indexOf != -1) {
                            String wrkNo = mast.getWrkCode().substring(0, indexOf);
//                        int indexOf = mast.getWrkCode().indexOf("-1");
                        if (!Cools.isEmpty(mast.getWrkCode())) {
                            String wrkNo = mast.getWrkCode();
                            WrkMast orgWrk = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", wrkNo));
                            if (Objects.isNull(orgWrk)) {
                                throw new CoolException("数据错误,主任务档不存在或已删除!!");
@@ -274,74 +419,93 @@
                            if (!wrkMastService.updateById(orgWrk)) {
                                throw new CoolException("任务档修改失败!!");
                            }
                            //称重后,计算出真实长度
                            Double realQty = val * matnr.getVolume();
                            WrkDetl detl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo));
                            if (Objects.isNull(detl)) {
                                throw new CoolException("子任务档明细不存在!!");
                            }
                            //库存减去称重长度
                            Double v = Math.round((wrkDetl.getStockQty() - realQty) * 10000) / 10000.0;
                            //原出为数量与真实数量互换,保持一致性
                            wrkDetl.setAnfme(v);
                            wrkDetl.setWeight(params.getWeight());
                            if (!wrkDetlService.insert(wrkDetl)) {
                                throw new CoolException("明细保存失败!!");
                            detl.setAnfme(v);
                            detl.setWeight(weight);
                            if (!wrkDetlService.update(detl, new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo).eq("matnr", detl.getMatnr()).eq("barcode", detl.getBarcode()))) {
                                throw new CoolException("原任务档明细修改失败!!");
                            }
                        } else {
                            throw new CoolException("任务号截取失败,请检查主任务档任档wrkCode字段");
                        }
                    }
                } else {
                    WrkDetl wrkDetl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", mast.getWrkNo()));
                    if (Objects.isNull(wrkDetl)) {
                        throw new CoolException("数据错误,任务明细不存在!!");
                    }
                    Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", wrkDetl.getMatnr()));
                    if (Objects.isNull(matnr)) {
                        throw new CoolException("物料基础信息不存在!!");
                    }
                    Double val = Math.round((params.getWeight() - matnr.getSafeQty()) * 10000) / 10000.0;
                    //称重后,计算出真实长度
                    Double realQty = val * matnr.getVolume();
                    wrkDetl.setAnfme(realQty);
                    wrkDetl.setWeight(params.getWeight());
                    if (!wrkDetlService.update(wrkDetl, new EntityWrapper<WrkDetl>().eq("wrk_no", mast.getWrkNo()).eq("matnr", wrkDetl.getMatnr()).eq("barcode", wrkDetl.getBarcode()))) {
                        throw new CoolException("任务档明细修改失败!!");
                    }
                    mast.setOveMk("Y");
                    if (!wrkMastService.updateById(mast)) {
                        throw new CoolException("任务档修改失败!!");
                    }
                }
                    // 更新原出库单
                    int indexOf = mast.getWrkCode().indexOf("-1");
                    if (indexOf != -1) {
                        String wrkNo = mast.getWrkCode().substring(0, indexOf);
                        WrkMast orgWrk = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", wrkNo));
                        if (Objects.isNull(orgWrk)) {
                            throw new CoolException("数据错误,主任务档不存在或已删除!!");
                        }
                        orgWrk.setOveMk("Y");
                        if (!wrkMastService.updateById(orgWrk)) {
                            throw new CoolException("任务档修改失败!!");
                        }
                        WrkDetl detl = wrkDetlService.selectOne(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo));
                        if (Objects.isNull(detl)) {
                            throw new CoolException("子任务档明细不存在!!");
                        }
                        //库存减去称重长度
                        Double v = Math.round((wrkDetl.getStockQty() - realQty) * 10000) / 10000.0;
                        //原出为数量与真实数量互换,保持一致性
                        detl.setAnfme(v);
                        detl.setWeight(params.getWeight());
                        if (!wrkDetlService.update(detl, new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo).eq("matnr", detl.getMatnr()).eq("barcode", detl.getBarcode()))) {
                            throw new CoolException("原任务档明细修改失败!!");
                        }
                    } else {
                        throw new CoolException("任务号截取失败,请检查主任务档任档wrkCode字段");
                if (!Objects.isNull(mast.getWrkCode())) {
                    if (mast.getOveMk().equals("N") && !Cools.isEmpty(mast.getIsSuplus())) {
                        throw new CoolException("任务未上报重量,无法完结任务!!");
                    }
                }
            } else {
                throw new CoolException("数据错误,当前任务状态有误 !");
                if (mast.getIoType() == 1 || mast.getIoType() == 2 ||mast.getIoType() == 10) {
                    mast.setWrkSts(4L);
                } else if ((mast.getIoType() == 101||mast.getIoType()==110) && mast.getWrkSts()<14) {
                    mast.setWrkSts(14L);
                    if(Cools.isEmpty(mast.getStaNo())){
                        mast.setOveMk("Y");
                    }
                }
                if (!wrkMastService.updateById(mast)) {
                    throw new CoolException("任务状态修改失败!!");
                }
            } else if (params.getMsgType().equals("task_cancel")) {
                //todo 取消任务
            }else if (params.getMsgType().equals("task_arrive")) {
                //到达目的地
                //如果出库任务是跨区则需要生成新的入库任务入库
                if(!Cools.isEmpty(mast.getLocNo())){
                    mast.setOnlineYn("N");//等待生成跨区入库任务
                }
                mast.setWrkSts(14L);
                if(Cools.isEmpty(mast.getStaNo())){
                    mast.setOveMk("Y");
                }
                mast.setModiTime(new Date());
                if (!wrkMastService.updateById(mast)) {
                    throw new CoolException("任务状态修改失败!!");
                }
            }
        } else if (params.getNotifyType().equals("weight")) {
        }
        return R.ok();
    }
    //输入库位自动冻结算出相邻库位序号
    @Override
    public Integer[] freezeLocAround(Integer locId) {
        Integer[] locAround = new Integer[3];
        if (Objects.isNull(locId)) {
            throw new CoolException("库位ID不能为空!!");
        }else if (locId==1){
            locAround[0] = 2;
            locAround[1] = 3;
            locAround[2] = 5;
        }else if (locId==2){
            locAround[0] = 1;
            locAround[1] = 6;
            locAround[2] = 0;
        }else if (locId==3){
            locAround[0] = 1;
            locAround[1] = 4;
            locAround[2] = 0;
        }else if (locId==4){
            locAround[0] = 5;
            locAround[1] = 3;
            locAround[2] = 0;
        }else if (locId==5){
            locAround[0] = 4;
            locAround[1] = 1;
            locAround[2] = 6;
        }else if (locId==6){
            locAround[0] = 2;
            locAround[1] = 5;
            locAround[2] = 0;
        }
        return locAround;
    }
}
src/main/java/com/zy/asrs/controller/LocMastController.java
@@ -48,6 +48,10 @@
    private WrkDetlLogService wrkDetlLogService;
    @Autowired
    private BasAreasService basAreasService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    @Autowired
    private BasDeviceService basDeviceService;
    @RequestMapping(value = "/locMast/init/pwd")
    public R locMastInitPwd(@RequestParam(required = false) String pwd) {
@@ -78,8 +82,7 @@
                  @RequestParam Map<String, Object> param) {
        excludeTrash(param);
        EntityWrapper<LocMast> wrapper = new EntityWrapper<>();
        wrapper.eq("frozen", 0)
                .eq("deleted", 0);
        wrapper.eq("deleted", 0);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
@@ -350,4 +353,52 @@
            return R.error("初始化失败===>" + e.getMessage());
        }
    }
    @GetMapping(value = "/locMast/jt")
    @ManagerAuth
    public R jt() {
        List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
                .eq("whs_type", 2)
                .eq("loc_sts", "O")
                .orderBy("loc_no"));
        //机台号
        long i = 1;
        //机台排序
        int j = 0;
        int[] arr =  {3,4,1,5,2,6};
        for (LocMast locMast : locMasts) {
            LocAroundBind locAroundBind = new LocAroundBind(
                    i,
                    i+"",
                    locMast.getLocNo(),
                    "O",
                    arr[j++]
            );
            locAroundBindService.insert(locAroundBind);
            if(j==6){
                j = 0;
                i++;
            }
        }
        return R.ok();
    }
    @GetMapping(value = "/locMast/addjt")
    @ManagerAuth
    public R addjt() {
        Date date = new Date();
        for (int i =1 ;i<52;i++){
            BasDevice basDevice =new BasDevice(
                    i+"",
                    i+"",
                    date,
                    "9995",
                    date,
                    "9995",
                    1
            );
            basDeviceService.insert(basDevice);
        }
        return R.ok();
    }
}
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -1,11 +1,16 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.AppAuth;
import com.core.common.*;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.AxisBean;
import com.zy.asrs.entity.param.*;
import com.zy.asrs.service.OpenService;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.asrs.service.*;
import com.zy.common.model.DetlDto;
import com.zy.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
@@ -13,9 +18,8 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * Created by vincent on 2022/4/8
@@ -32,6 +36,18 @@
    @Autowired
    private OpenService openService;
    @Autowired
    private MatService matService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private ReportQueryMapper reportQueryMapper;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private WrkDetlService wrkDetlService;
    @PostMapping("/order/matSync/default/v2")
//    @AppAuth(memo = "商品信息同步接口")
@@ -134,7 +150,7 @@
        if (Cools.isEmpty(param.getOrderType())) {
            return R.error("单据类型[orderType]不能为空");
        }
        if (Cools.isEmpty(param.getOrderDetails())) {
        if (Cools.isEmpty(param.getMatList())) {
            return R.error("单据明细[orderDetails]不能为空");
        }
        openService.pakoutOrderCreate(param);
@@ -216,4 +232,138 @@
        System.out.println(JSON.toJSONString(param1));
    }
    /*************************************电视机程序***********************************************/
    @GetMapping("/locDetl/statistics")
    public R locDetlStatistics(){
        HashMap<String, Object> param = new HashMap<>();
        Page<LocDetl> stockStatis = locDetlService.getStockStatis(toPage(1, 100, param, LocDetl.class));
        for (LocDetl locDetl : stockStatis.getRecords()) {
            Mat mat = matService.selectByMatnr(locDetl.getMatnr());
            if (mat != null) {
                locDetl.sync(mat);
            }
        }
        return R.ok(stockStatis);
    }
    @GetMapping("/line/charts")
    public R locIoLineCharts(){
        Map<String,Object> map=new HashMap<String, Object>();
        List<AxisBean> list = new ArrayList<AxisBean>();
        List<WorkChartAxis> listChart = reportQueryMapper.getChartAxis();
        if(listChart!=null) {
            ArrayList<Integer> data1 = new ArrayList<Integer>();
            ArrayList<Integer> data2 = new ArrayList<Integer>();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -12);
            for(int i=0;i<12;i++) {
                boolean flag = true;
                calendar.add(Calendar.DATE, 1);
                String str = sf.format(calendar.getTime());
                for(WorkChartAxis workChart : listChart) {
                    if(str.equals(workChart.getYmd())) {
                        data1.add(workChart.getInqty());
                        data2.add(workChart.getOutqty());
                        flag = false;
                        break;
                    }
                }
                if(flag) {
                    data1.add(0);
                    data2.add(0);
                }
            }
            AxisBean inqty = new AxisBean();
            inqty.setName("入库数量");
            Integer[] array1 = new Integer[data1.size()];
            inqty.setData(data1.toArray(array1));
            list.add(inqty);
            AxisBean outqty = new AxisBean();
            outqty.setName("出库数量");
            Integer[] array2 = new Integer[data2.size()];
            outqty.setData(data2.toArray(array2));
            list.add(outqty);
        }
        map.put("rows",list);
        return R.ok(map);
    }
    /**
     * 库存信息查询接口
     */
    @GetMapping("/queryLoc")
    public synchronized R queryLoc() {
        List<Map<String, Object>> pie = new ArrayList<>();
        LocChartPie locUseRate = reportQueryMapper.getLocUseRate();
        if (locUseRate != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", "在库");
            map.put("value", locUseRate.getFqty());
            pie.add(map);
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", "空");
            map1.put("value", locUseRate.getOqty());
            pie.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("name", "使用");
            map2.put("value", locUseRate.getUqty());
            pie.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("name", "禁用");
            map3.put("value", locUseRate.getXqty());
            pie.add(map3);
        }
        // 总库位数
        Integer total = (int) Arith.add(0, locUseRate.getFqty(), locUseRate.getOqty(), locUseRate.getUqty(), locUseRate.getXqty());
        // 使用中
        Integer used = locUseRate.getFqty() + locUseRate.getUqty();
        // 库位使用率
        double usedDivides = Arith.divides(3, used, total);
        double usedPr = Arith.multiplys(1, usedDivides, 100);
        return R.ok(
                Cools.add("pie", pie)
                        .add("stockCount", locUseRate.getFqty())
                        .add("emptyCount", locUseRate.getOqty())
                        .add("disableCount", locUseRate.getXqty())
                        .add("total", total)
                        .add("used", used)
                        .add("usedPr", usedPr)
        );
    }
    /**
     * 任务查询接口
     */
    @PostMapping("/queryTask")
    public synchronized R queryTask(@RequestBody QueryTaskParam param) {
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        }
        if (Cools.isEmpty(param.getTaskNo())) {
            return R.error("任务号[taskNo]不能为空");
        }
        WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", param.getTaskNo()));
        if (wrkMast == null) {
            return R.error("任务不存在");
        }
        List<WrkDetl> wrkDetls = wrkDetlService.selectByWrkNo(Integer.valueOf(param.getTaskNo()));
        HashMap<String, Object> map = new HashMap<>();
        map.put("taskNo", param.getTaskNo());
        map.put("ioType", wrkMast.getIoType());
        map.put("wrkDetls", wrkDetls);
        return R.ok().add(map);
    }
}
src/main/java/com/zy/asrs/controller/OrderPakinController.java
@@ -11,6 +11,7 @@
import com.zy.asrs.entity.param.OrderDomainParam;
import com.zy.asrs.entity.result.WrkTraceVo;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.MatServiceImpl;
import com.zy.common.model.DetlDto;
import com.zy.common.web.BaseController;
import org.springframework.beans.BeanUtils;
@@ -42,6 +43,8 @@
    private WrkMastService wrkMastService;
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Autowired
    private MatServiceImpl matService;
    @RequestMapping(value = "/order/nav/list/auth")
    @ManagerAuth
@@ -166,6 +169,8 @@
                }
            } else {
                list.add(dto);
                Mat mat = matService.selectByMatnr(orderDetl.getMatnr());
                orderDetl.sync(mat);
                orderDetl.setOrderId(order.getId());
                orderDetl.setOrderNo(order.getOrderNo());
                orderDetl.setCreateBy(getUserId());
src/main/java/com/zy/asrs/controller/OrderPakoutController.java
@@ -11,6 +11,8 @@
import com.zy.asrs.entity.param.OrderDomainParam;
import com.zy.asrs.entity.result.WrkTraceVo;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.MatServiceImpl;
import com.zy.asrs.service.impl.OrderPakoutServiceImpl;
import com.zy.common.model.DetlDto;
import com.zy.common.web.BaseController;
import org.springframework.beans.BeanUtils;
@@ -42,6 +44,10 @@
    private WrkMastService wrkMastService;
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Autowired
    private MatServiceImpl matService;
    @Autowired
    private OrderPakoutServiceImpl orderPakoutService;
    @RequestMapping(value = "/order/nav/list/auth")
    @ManagerAuth
@@ -106,7 +112,7 @@
            }
            param.setOrderNo(prefix + snowflakeIdWorker.nextId());
        }
        OrderPakout order = orderService.selectByNo(param.getOrderNo());
        OrderPakout order = orderPakoutService.selectByNo(param.getOrderNo());
        if (order != null) {
            return R.error("单据编号已存在");
        }
@@ -163,8 +169,11 @@
                    throw new CoolException("保存订单明细档失败");
                }
            } else {
                Mat mat = matService.selectByMatnr(orderDetl.getMatnr());
                list.add(dto);
                orderDetl.setOrderId(order.getId());
                orderDetl.sync(mat);
                orderDetl.setBatch(Cools.isEmpty(dto.getBatch())? "" :dto.getBatch());
                orderDetl.setOrderNo(order.getOrderNo());
                orderDetl.setCreateBy(getUserId());
                orderDetl.setCreateTime(now);
@@ -229,6 +238,7 @@
                orderDetl.setUpdateTime(now);
                orderDetl.setStatus(1);
                orderDetl.setQty(0.0D);
                orderDetl.setBatch(Cools.isEmpty(dto.getBatch())? "" :dto.getBatch());
                if (!orderDetlService.insert(orderDetl)) {
                    throw new CoolException("保存订单明细档失败");
                }
src/main/java/com/zy/asrs/controller/OutController.java
@@ -95,6 +95,10 @@
                        LocDto locDto = new LocDto(locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getMaktx(), locDetl.getBatch(), orderDetl.getOrderNo(),
                                issued >= locDetl.getAnfme() ? locDetl.getAnfme() : issued);
                        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()));
                        LocAroundBind bLocNo = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_no", locMast.getLocNo()));
                        if (!Cools.isEmpty(bLocNo)) {
                            continue;
                        }
                        locDto.setFrozen(locDetl.getFrozen());
                        locDto.setFrozenLoc(locMast.getFrozen());
                        List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locDetl.getLocNo(), 107);
src/main/java/com/zy/asrs/controller/WaitPakinController.java
@@ -81,7 +81,7 @@
    }
    @RequestMapping(value = "/waitPakin/update/auth")
    @ManagerAuth
    @ManagerAuth
    public R update(WaitPakin waitPakin){
        if (Cools.isEmpty(waitPakin)){
            return R.error();
@@ -90,6 +90,25 @@
        return R.ok();
    }
    @RequestMapping(value = "/waitPakin/update/beBatch/auth")
    @ManagerAuth
    public R updateBeBatch(@RequestBody Map<String, Object> param) {
        String zpallet = (String) param.get("zpallet");
        Integer beBatch = Integer.parseInt(param.get("beBatch").toString());
        if (Cools.isEmpty(zpallet)) {
            return R.error("托盘码不能为空");
        }
        boolean result = waitPakinService.updateBeBatchByZpallet(zpallet, beBatch);
        if (result) {
            return R.ok("修改成功");
        } else {
            return R.error("修改失败");
        }
    }
    @RequestMapping(value = "/waitPakin/delete/auth")
    @ManagerAuth
    @Transactional
src/main/java/com/zy/asrs/controller/WrkMastLogController.java
@@ -82,15 +82,16 @@
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){
        for (Map.Entry<String, Object> entry : map.entrySet()){
            String val = String.valueOf(entry.getValue());
            String key = humpToLine(entry.getKey());
            if (val.contains(RANGE_TIME_LINK)){
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
                wrapper.ge(key, DateUtils.convert(dates[0]));
                wrapper.le(key, DateUtils.convert(dates[1]));
            } else {
                if (entry.getKey().equals("manu_type")) {
                    wrapper.like(entry.getKey(), val);
                if (key.equals("manu_type")) {
                    wrapper.like(key, val);
                } else {
                    wrapper.eq(entry.getKey(), val);
                    wrapper.eq(key, val);
                }
            }
        }
src/main/java/com/zy/asrs/entity/BasCrnp.java
@@ -13,12 +13,14 @@
import com.core.common.Cools;
import com.core.common.SpringUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
@TableName("asr_bas_crnp")
@Data
public class BasCrnp implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -156,6 +158,10 @@
    @TableField("tank_qty1")
    private Integer tankQty1;
    @ApiModelProperty(value= "重量")
    @TableField("weight")
    private Float weight;
    public BasCrnp() {}
    public BasCrnp(String inEnable,String outEnable,Integer crnSts,Integer wrkNo,Long crnErr,String frmLocno,Integer frmSta,Integer toSta,String toLocno,Long appeUser,Date appeTime,Long modiUser,Date modiTime,String hpMk,String retrieveMk,String ctlHp,String ctlRest,String empIn,Integer tankQty,Integer tankQty1) {
src/main/java/com/zy/asrs/entity/LocAroundBind.java
@@ -61,6 +61,14 @@
    @TableField("dev_name")
    private String devName;
    @ApiModelProperty("机台顺序")
    @TableField("order_no")
    private Integer orderNo;
    @ApiModelProperty("是否冻结")
    @TableField("freeze")
    private Integer freeze;
    public LocAroundBind() {}
    public LocAroundBind(Long devId,String devNo,Long bLocId,String blocNo) {
@@ -99,4 +107,11 @@
//    );
    public LocAroundBind(Long devId, String devNo, String blocNo, String locType, int orderNo) {
        this.devId = devId;
        this.devNo = devNo;
        this.blocNo = blocNo;
        this.locType = locType;
        this.orderNo = orderNo;
    }
}
src/main/java/com/zy/asrs/entity/LocMast.java
@@ -100,11 +100,11 @@
    @TableField("loc_type1")
    private Short locType1;
    @ApiModelProperty(value= "宽窄类型{0:未知,1:窄库位,2:宽库位}")
    @ApiModelProperty(value= "机台号")
    @TableField("loc_type2")
    private Short locType2;
    @ApiModelProperty(value= "轻重类型{0:未知,1:轻库位,2:重库位}")
    @ApiModelProperty(value= "机台号排序")
    @TableField("loc_type3")
    private Short locType3;
src/main/java/com/zy/asrs/entity/Mat.java
@@ -81,6 +81,21 @@
    private String name;
    /**
     * 归零阈值
     */
    @ApiModelProperty(value= "归零阈值")
    @ExcelProperty(value = "归零阈值")
    @TableField("safe_qty")
    private Double safeQty;
    /**
     * 体积
     */
    @ApiModelProperty(value= "体积")
    @ExcelProperty(value = "每公斤长度")
    private Double volume;
    /**
     * 规格
     */
    @ApiModelProperty(value= "规格")
@@ -173,13 +188,6 @@
    @TableField("item_num")
    private String itemNum;
    /**
     * 安全库存量
     */
    @ApiModelProperty(value= "安全库存量")
    @ExcelProperty(value = "归零阈值")
    @TableField("safe_qty")
    private Double safeQty;
    /**
     * 重量
@@ -199,13 +207,6 @@
    @ApiModelProperty(value= "长度")
    @TableField("man_length")
    private Double manLength;
    /**
     * 体积
     */
    @ApiModelProperty(value= "体积")
    @ExcelProperty(value = "每公斤长度")
    private Double volume;
    /**
     * 三方编码
src/main/java/com/zy/asrs/entity/WaitPakin.java
@@ -281,7 +281,7 @@
        return this.boxType1;
    }
//    public void sync(Object source) {
//        Synchro.Copy(source, this);
//    }
    public void sync(Object source) {
        Synchro.Copy(source, this);
    }
}
src/main/java/com/zy/asrs/entity/WrkMast.java
@@ -116,6 +116,14 @@
    @TableField("source_loc_no")
    private String sourceLocNo;
    /**
     * N : 待生成入库任务
     * Y : 成功生成入库任务
     */
    @ApiModelProperty(value= "生成跨区入库任务标记")
    @TableField("online_yn")
    private String onlineYn;
    @ApiModelProperty(value= "")
    @TableField("loc_sts")
    private String locSts;
@@ -129,10 +137,6 @@
    @ApiModelProperty(value= "")
    @TableField("link_mis")
    private String linkMis;
    @ApiModelProperty(value= "")
    @TableField("online_yn")
    private String onlineYn;
    @ApiModelProperty(value= "")
    @TableField("upd_mk")
src/main/java/com/zy/asrs/entity/WrkMastLog.java
@@ -30,6 +30,7 @@
    private Long id;
    @ApiModelProperty("日志ID")
    @TableField("log_id")
    private Long logId;
    /**
src/main/java/com/zy/asrs/entity/param/OpenOrderPakoutParam.java
@@ -17,24 +17,15 @@
    private String orderNo;
    private String billType;
    private String orderType;
    private String orderTime;
    private List<DetlDto> orderDetails;
    private List<DetlDto> matList;
    private String lgort;
//    public static void main(String[] args) {
//        OpenOrderPakoutParam param = new OpenOrderPakoutParam();
//        param.setOrderNo("LXT12321321");
//        param.setOrderType("交货单");
//        param.setOrderTime(DateUtils.convert(new Date()));
//        List<DetlDto> orderDetails = new ArrayList<>();
//        param.setOrderDetails(orderDetails);
//        DetlDto detlDto = new DetlDto("15099-10000", 3.0);
//        orderDetails.add(detlDto);
//        System.out.println(JSON.toJSONString(param));
//    }
}
src/main/java/com/zy/asrs/entity/param/QueryTaskParam.java
New file
@@ -0,0 +1,10 @@
package com.zy.asrs.entity.param;
import lombok.Data;
@Data
public class QueryTaskParam {
    private String taskNo;
}
src/main/java/com/zy/asrs/service/WaitPakinService.java
@@ -5,4 +5,6 @@
public interface WaitPakinService extends IService<WaitPakin> {
    boolean updateBeBatchByZpallet(String zpallet, Integer beBatch);
}
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java
@@ -45,26 +45,26 @@
    @Override
    public BasDevp checkSiteStatus(Integer devpNo, boolean pakin) {
        BasDevp station = selectById(devpNo);
        if (station == null){
            throw new CoolException(devpNo+"站点不存在");
        }
        if (pakin) {
            if(station.getAutoing()==null || !station.getAutoing().equals("Y")) {
                throw new CoolException(devpNo+"站点不是自动状态");
            }
            if(station.getLoading()==null || !station.getLoading().equals("Y")) {
                throw new CoolException(devpNo+"站点无物");
            }
            if(station.getWrkNo()!=null && station.getWrkNo()>0 && station.getWrkNo() < 9990) {
                throw new CoolException(devpNo+"站点已有工作号");
            }
//            if(!station.getInEnable().equals("Y")) {
//                throw new CoolException(devpNo+"站点不是可入状态");
//        if (station == null){
//            throw new CoolException(devpNo+"站点不存在");
//        }
//        if (pakin) {
//            if(station.getAutoing()==null || !station.getAutoing().equals("Y")) {
//                throw new CoolException(devpNo+"站点不是自动状态");
//            }
            if(wrkMastService.getWorkingMast(devpNo)>0){
                throw new CoolException(devpNo+"站点不能同时生成两笔入库工作档");
            }
        }
//            if(station.getLoading()==null || !station.getLoading().equals("Y")) {
//                throw new CoolException(devpNo+"站点无物");
//            }
//            if(station.getWrkNo()!=null && station.getWrkNo()>0 && station.getWrkNo() < 9990) {
//                throw new CoolException(devpNo+"站点已有工作号");
//            }
////            if(!station.getInEnable().equals("Y")) {
////                throw new CoolException(devpNo+"站点不是可入状态");
////            }
//            if(wrkMastService.getWorkingMast(devpNo)>0){
//                throw new CoolException(devpNo+"站点不能同时生成两笔入库工作档");
//            }
//        }
        return station;
    }
}
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -262,7 +262,7 @@
        }
        // 单据明细档
        List<DetlDto> list = new ArrayList<>();
        List<DetlDto> orderDetails = param.getOrderDetails();
        List<DetlDto> orderDetails = param.getMatList();
        for (DetlDto detail : orderDetails) {
            DetlDto dto = new DetlDto(detail.getMatnr(), detail.getBatch(),detail.getBrand(),detail.getStandby1(),detail.getStandby2(),detail.getStandby3(),detail.getLineNumber(),
                    detail.getBoxType1(),detail.getBoxType2(),detail.getBoxType3(), detail.getAnfme());
src/main/java/com/zy/asrs/service/impl/OrderPakinServiceImpl.java
@@ -134,7 +134,7 @@
                openParam.setOrderNo(orderNo);
                openParam.setOrderTime(DateUtils.convert(wrkMast.getModiTime()));
                openParam.setOrderType("手动出库单");
                openParam.setOrderDetails(detlDtos);
                openParam.setMatList(detlDtos);
                openService.pakoutOrderCreate(openParam);
            }
src/main/java/com/zy/asrs/service/impl/OrderPakoutServiceImpl.java
@@ -133,7 +133,7 @@
                openParam.setOrderNo(orderNo);
                openParam.setOrderTime(DateUtils.convert(wrkMast.getModiTime()));
                openParam.setOrderType("手动出库单");
                openParam.setOrderDetails(detlDtos);
                openParam.setMatList(detlDtos);
                openService.pakoutOrderCreate(openParam);
            }
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java
@@ -134,7 +134,7 @@
                openParam.setOrderNo(orderNo);
                openParam.setOrderTime(DateUtils.convert(wrkMast.getModiTime()));
                openParam.setOrderType("手动出库单");
                openParam.setOrderDetails(detlDtos);
                openParam.setMatList(detlDtos);
                openService.pakoutOrderCreate(openParam);
            }
src/main/java/com/zy/asrs/service/impl/WaitPakinServiceImpl.java
@@ -1,5 +1,6 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zy.asrs.mapper.WaitPakinMapper;
import com.zy.asrs.entity.WaitPakin;
import com.zy.asrs.service.WaitPakinService;
@@ -9,4 +10,11 @@
@Service("waitPakinService")
public class WaitPakinServiceImpl extends ServiceImpl<WaitPakinMapper, WaitPakin> implements WaitPakinService {
    @Override
    public boolean updateBeBatchByZpallet(String zpallet, Integer beBatch) {
        WaitPakin updateEntity = new WaitPakin();
        updateEntity.setBeBatch(beBatch);
        return this.update(updateEntity, new EntityWrapper<WaitPakin>().eq("zpallet", zpallet));
    }
}
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -420,7 +420,7 @@
        int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType));
        String wrkCode = null;
        if (!Objects.isNull(deviceNo)) {
            wrkCode = workNo + "-1";
            wrkCode = workNo + "";
            ioType = 101;
            generateOutStock(taskDto, userId, workNo, wrkCode, now, ioType, locMast, staDesc, deviceNo);
        } else {
@@ -455,7 +455,7 @@
        LocAroundBind binds = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>()
                .eq("loc_type", LocStsType.LOC_STS_TYPE_O.type)
                .eq("dev_no", basDevice.getDevNo()).orderBy("is_default", false));
                .eq("dev_no", basDevice.getType()).orderBy("order_no"));
        if (Objects.isNull(binds)) {
            throw new CoolException("机台未设置默认工作位!!");
@@ -500,6 +500,7 @@
            throw new CoolException("预约库位状态失败,库位号:" + locMasts.getLocNo());
        }
        List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locMasts.getLocNo(), 1);
        //TODO 1. 获取入库站点, 目标库位  3. 将出库明细添加至入库明细
        Integer staNo = staNos.stream().findFirst().get();
@@ -513,9 +514,11 @@
        wrkMast.setIoType(ioType); // 入出库状态
        wrkMast.setIoPri(13D); // 优先级:13
        wrkMast.setCrnNo(locMast.getCrnNo());
        wrkMast.setSourceStaNo(staDesc.getCrnStn() + ""); // 源站
//        wrkMast.setStaNo(staDesc.getStnNo() + ""); // 目标站
        wrkMast.setStaNo(staNo + ""); // 目标站
        if(!Objects.equals(locMasts.getCrnNo(), locMast.getCrnNo())){
            wrkMast.setSourceStaNo(staDesc.getCrnStn() + ""); // 源站
            wrkMast.setStaNo(staNo + ""); // 目标站
        }
        wrkMast.setLocNo(locMasts.getLocNo());
        wrkMast.setSourceLocNo(taskDto.getLocNo()); // 源库位
        wrkMast.setFullPlt("Y"); // 满板:Y
@@ -1240,6 +1243,16 @@
            // 出库 ===>> F.在库
            if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) {
                locSts = "F";
                if (!Cools.isEmpty(wrkMast.getLocNo())) {
                    LocAroundBind bLocId = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_id", wrkMast.getLocNo()));
                    if (!Objects.isNull(bLocId)) {
                        bLocId.setLocType(LocStsType.LOC_STS_TYPE_O.type);
                        if (!locAroundBindService.updateById(bLocId)) {
                        }
                    }
                }
                // 空板出库 ===>> D.空桶/空栈板
            } else if (wrkMast.getIoType() == 110) {
                locSts = "D";
@@ -1455,11 +1468,13 @@
            ioType = 1;
        }
        wokNo = commonService.getWorkNo(0);
        LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getLocNo()));
        // 获取目标站
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", ioType)
                .eq("stn_no", wrkMast.getStaNo()) // 作业站点 = 拣料出库的目标站
                .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
//                .eq("stn_no", wrkMast.getStaNo()) // 作业站点 = 拣料出库的目标站
                .eq("crn_no", locMast1.getCrnNo()); // 堆垛机号
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (Cools.isEmpty(staDesc)) {
            throw new CoolException("入库路径不存在");
@@ -1476,10 +1491,10 @@
        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(locDetl);
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(Integer.parseInt(wrkMast.getStaNo()), false);
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(staDesc.getCrnStn(), false);
        sourceStaNo.setLocType1((short) 1);
        LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
        StartupDto locNo = commonService.getLocNo(1, Integer.parseInt(wrkMast.getStaNo()), findLocNoAttributeVo, locTypeDto);
        StartupDto locNo = commonService.getLocNo1(locMast1.getCrnNo());
        Date now = new Date();
        // 堆垛机站点(目标站)
@@ -1489,9 +1504,9 @@
        mast.setWrkNo(wokNo);
        // 更新工作档数据状态
        mast.setIoType(ioType); // 入出库类型: 103->53,104->54,107->57
        mast.setWrkSts(2L); // 工作状态: 2.设备上走
        mast.setSourceStaNo(wrkMast.getStaNo()); // 源站
        mast.setStaNo(staNo + ""); // 目标站
        mast.setWrkSts(1L); // 工作状态: 2.设备上走
        mast.setSourceStaNo(""); // 源站
        mast.setStaNo(""); // 目标站
        mast.setSourceLocNo(wrkMast.getLocNo());
        mast.setLocNo(locNo.getLocNo()); // 目标库位 = 出库时的源库位
        mast.setModiTime(now);
src/main/java/com/zy/asrs/service/impl/WrkMastLogServiceImpl.java
@@ -36,8 +36,11 @@
        }
        WrkMastLog mastLog = new WrkMastLog();
        BeanUtils.copyProperties(mast, mastLog);
//        mastLog.setLogId(mast.getId());
//
        if (mast.getWrkSts() != null) {
            mastLog.setWrkSts(mast.getWrkSts().intValue());
        }
        mastLog.setLogId(Long.valueOf(mast.getWrkNo()));
        if (!wrkMastLogService.insert(mastLog)) {
            throw new CoolException("任务日志保存失败!!");
        }
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java
@@ -1,13 +1,16 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.Order;
import com.zy.asrs.service.ApiLogService;
import com.zy.asrs.service.OrderService;
import com.core.common.R;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.handler.OrderSyncHandler;
import com.zy.asrs.utils.OrderInAndOutUtil;
import com.zy.common.entity.Parameter;
import com.zy.common.model.LocDto;
import com.zy.common.model.TaskDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -15,7 +18,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.*;
/**
 * updated by IX in 2024/12/17
@@ -33,6 +36,24 @@
    @Value("${erp.switch.ErpReportOld}")
    private boolean ErpReportOld;
    @Autowired
    private OrderPakoutService orderPakoutService;
    @Autowired
    private DocTypeService docTypeService;
    @Autowired
    private OrderDetlPakoutService orderDetlPakoutService;
    @Autowired
    private LocDetlService locDetlService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private StaDescService staDescService;
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private WorkService workService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    @Scheduled(cron = "0 0 1 * * ? ")
    public void clearApiLog() {
@@ -43,73 +64,125 @@
        }
    }
    @Scheduled(cron = "0 1 * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderIssuedOnceMore() {
        List<Order> orderList = orderService.selectComplete99();
        for (Order order : orderList) {
            try {
                ReturnT<String> result = orderSyncHandler.startOrderIssuedOnceMore(order);
                if (!result.isSuccess()) {
                    log.error("单据[orderNo={}]再次转执行表失败:{}", order.getOrderNo(),result.getMsg());
    @Scheduled(cron = "0/30 * * * * ? ")
    public void checkOrderPakoutSettled() {
        List<OrderPakout> list = orderPakoutService.selectBySettle(1L);
        if (Cools.isEmpty(list)) {
            return;
        }
        for (OrderPakout order : list) {
            if (order.getDocType() != null) {
                DocType docType = docTypeService.selectById(order.getDocType());
                if (docType != null && Integer.valueOf(1).equals(docType.getPakout())) {
                    List<LocDto> locDtos = new ArrayList<>();
                    Set<String> exist = new HashSet<>();
                    Boolean flag = false;
                    // 获取该订单中订单明细里的id
                    List<OrderDetlPakout> detls = orderDetlPakoutService.selectByOrderId(order.getId());
                    if (!Cools.isEmpty(detls)) {
                        for (OrderDetlPakout detl : detls) {
                            double issued = Optional.of(detl.getAnfme() - detl.getWorkQty()).orElse(0.0D);
                            if (issued <= 0.0D) {
                                continue;
                            }
                            List<LocDetl> locDetls = locDetlService.queryStockAll(null, exist, detl.getMatnr(), detl.getBatch(),
                                    detl.getBrand(), detl.getStandby1(), detl.getStandby2(), detl.getStandby3(), detl.getBoxType1(), detl.getBoxType2(), detl.getBoxType3());
                            for (LocDetl locDetl : locDetls) {
                                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()).eq("loc_sts","F"));
                                if (locMast != null) {
                                    LocAroundBind bLocNo = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_no", locMast.getLocNo()));
                                    if (!Cools.isEmpty(bLocNo)) {
                                        continue;
                                    }
                                }
                                if (issued > 0) {
                                    LocDto locDto = new LocDto(locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getMaktx(), locDetl.getBatch(), detl.getOrderNo(),
                                            issued >= locDetl.getAnfme() ? locDetl.getAnfme() : issued);
//                                    LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetl.getLocNo()));
                                    locDto.setFrozen(locDetl.getFrozen());
                                    locDto.setFrozenLoc(locMast.getFrozen());
                                    List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locDetl.getLocNo(), issued >= locDetl.getAnfme() ? 101 : 103);
                                    locDto.setStaNos(staNos);
                                    locDto.setBrand(detl.getBrand());
                                    locDto.setStandby1(detl.getStandby1());
                                    locDto.setStandby2(detl.getStandby2());
                                    locDto.setStandby3(detl.getStandby3());
                                    locDto.setBoxType1(detl.getBoxType1());
                                    locDto.setBoxType2(detl.getBoxType2());
                                    locDto.setBoxType3(detl.getBoxType3());
                                    locDtos.add(locDto);
                                    exist.add(locDetl.getLocNo());
                                    // 剩余待出数量递减
                                    issued = issued - locDetl.getAnfme();
                                } else {
                                    break;
                                }
                            }
                            if (issued > 0) {
                                flag = true;
                                break;
                            }
                        }
                        if (flag) {
                            continue;
                        }
                        List<TaskDto> taskDtos = new ArrayList<>();
                        // 根据 (库位 & 出库站) 分组; 理想状态:一组为一次出库任务
                        for (LocDto locDto : locDtos) {
                            if (locDto.isLack()) { continue; }
                            TaskDto taskDto = new TaskDto(locDto.getLocNo(), locDto.getStaNo(), locDto, locDto.getStandby1());
                            if (TaskDto.has(taskDtos, taskDto)) {
                                TaskDto dto = TaskDto.find(taskDtos, taskDto);
                                assert dto != null;
                                dto.getLocDtos().addAll(taskDto.getLocDtos());
                            } else {
                                taskDtos.add(taskDto);
                            }
                        }
                        // -----------------------------------------------------------------------------------------------
                        for (TaskDto taskDto : taskDtos) {
                            BasDevp staNo = basDevpService.checkSiteStatus(taskDto.getStaNo());
                            if (!Objects.isNull(taskDto.getDeviceNo())) {
                                //生成出库任务
                                workService.stockOut(staNo, taskDto, taskDto.getDeviceNo(), 9995L);
                            } else  {
                                workService.stockOut(staNo, taskDto, null, 9995L);
                            }
                        }
                    }
                }
            } catch (Exception e){
                log.error(e.getMessage());
                log.error("单据[orderNo={}]再次转执行表失败", order.getOrderNo());
            }
        }
    }
    /**
     * 上报单据转执行单据
     * @author Ryan
     * @date 2026/1/5 14:07
     */
    @Scheduled(cron = "0/5 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderIssued() {
//        String erpReport = Parameter.get().getErpReport();
//        if (!Cools.isEmpty(erpReport) && erpReport.equals("true")) {
            List<Order> orderList = orderService.selectComplete1();
//            List<Order> orderList = orderService.selectList(new EntityWrapper<Order>().eq("settle", 1L).eq("status", 1).orderBy("create_time", true));
            for (Order order : orderList) {
                try {
                    ReturnT<String> result = orderSyncHandler.startOrderIssued(order);
                    if (!result.isSuccess()) {
                        log.error("单据[orderNo={}]转执行表失败", order.getOrderNo());
                    }
                } catch (Exception e){
                    log.error(e.getMessage());
                    log.error("单据[orderNo={}]转执行表失败", order.getOrderNo());
                }
            }
//        }
    }
//    @Scheduled(cron = "0/5 * * * * ? ")
    //    @Scheduled(cron = "0/5 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderInAndOutUtil() {
//        String erpReport = Parameter.get().getErpReport();
//        if (!Cools.isEmpty(erpReport) && erpReport.equals("true")) {
            List<Order> orders = OrderInAndOutUtil.selectComplete(null);
            for (Order order : orders) {
                try {
                    ReturnT<String> result = orderSyncHandler.startOrderInAndOutUtil(order);
                    if (!result.isSuccess()) {
                        log.error("单据[orderNo={}]转上报表失败", order.getOrderNo());
                    }
                } catch (Exception e){
                    log.error(e.getMessage());
        List<Order> orders = OrderInAndOutUtil.selectComplete(null);
        for (Order order : orders) {
            try {
                ReturnT<String> result = orderSyncHandler.startOrderInAndOutUtil(order);
                if (!result.isSuccess()) {
                    log.error("单据[orderNo={}]转上报表失败", order.getOrderNo());
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("单据[orderNo={}]转上报表失败", order.getOrderNo());
            }
        }
//        }
    }
//    @Scheduled(cron = "0/30 * * * * ? ")
    //    @Scheduled(cron = "0/30 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderReport() {
        if (!ErpReportOld){
        if (!ErpReportOld) {
            return;
        }
        String erpReport = Parameter.get().getErpReport();
src/main/java/com/zy/asrs/task/WorkMastScheduler.java
@@ -1,14 +1,25 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.api.controller.params.WorkTaskParams;
import com.zy.api.service.WcsApiService;
import com.zy.asrs.entity.LocAroundBind;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.Task;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.TaskMapper;
import com.zy.asrs.service.LocAroundBindService;
import com.zy.asrs.service.TaskService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.service.impl.LocMastServiceImpl;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.handler.WorkMastHandler;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.enums.WorkNoType;
import com.zy.common.service.CommonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +47,12 @@
    private TaskService taskService;
    @Autowired
    private WcsApiService wcsApiService;
    @Autowired
    private LocMastServiceImpl locMastService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    @Scheduled(cron = "0/3 * * * * ? ")
    private void execute() {
@@ -63,29 +80,124 @@
     * @author Ryan
     * @date 2026/1/10 14:42
     */
//    @Scheduled(cron = "0/15 * * * * ? ")
    @Scheduled(cron = "0/3 * * * * ? ")
    private void autoPubTasks() {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", Arrays.asList(1L, 11L)));
        if (wrkMasts.isEmpty()) {
            return;
        }
        Collections.shuffle(wrkMasts);
        wrkMasts.forEach(wrkMast -> {
            WorkTaskParams params = new WorkTaskParams();
            if (wrkMast.getIoType().equals(1)) {
                params.setType("in");
                params.setTaskNo(wrkMast.getWrkCode())
                        .setLocNo(wrkMast.getLocNo())
                        .setBarcode(wrkMast.getBarcode())
                        .setTaskPri(Integer.parseInt(wrkMast.getIoPri() + ""));
            } else {
                params.setType("out")
                        .setTaskNo(wrkMast.getWrkCode())
                        .setLocNo(wrkMast.getLocNo())
                        .setStaNo(wrkMast.getStaNo())
                        .setTaskPri(Integer.parseInt(wrkMast.getIoPri() + ""));
        for (WrkMast wrkMast : wrkMasts) {
            //查看下发任务是否为冻结库位,是冻结库位则跳过下发任务
            LocAroundBind locAroundBind = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>()
                    .eq("b_loc_no", wrkMast.getLocNo())
                    .eq("freeze", 1));
            if (Cools.isEmpty(locAroundBind)) {
                locAroundBind = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>()
                        .eq("b_loc_no", wrkMast.getSourceLocNo())
                        .eq("freeze", 1));
                if (!Cools.isEmpty(locAroundBind)) {
                    continue;
                }
            }else {
                continue;
            }
            wcsApiService.pubWrkToWcs(params);
        });
            Integer crnNo = wrkMast.getCrnNo();
            //该堆垛机已经下发任务给wcs后不再下发新的搬运任务
            List<WrkMast> wrkMasts1 = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("crn_no", crnNo).in("wrk_sts", Arrays.asList(2L, 12L)));
            if (!wrkMasts1.isEmpty()) {
                continue;
            }
            //源库位为冻结库位时禁止下发搬运任务给堆垛机
            if (!Cools.isEmpty(wrkMast.getSourceLocNo())){
                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                        .eq("loc_no", wrkMast.getSourceLocNo())
                        .eq("frozen",0));
                if (Cools.isEmpty(locMast)) {
                    continue;
                }
            }
            //目标库位为冻结库位时禁止下发搬运任务给堆垛机
            if (!Cools.isEmpty(wrkMast.getLocNo())){
                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                        .eq("loc_no", wrkMast.getLocNo())
                        .eq("frozen",0));
                if (Cools.isEmpty(locMast)) {
                    continue;
                }
            }
            String wcsSourceLocNo = Cools.isEmpty(wrkMast.getSourceLocNo()) ? "" : Utils.WMSLocToWCSLoc(wrkMast.getSourceLocNo());
            String wcsLocNo = Cools.isEmpty(wrkMast.getLocNo()) ? "" : Utils.WMSLocToWCSLoc(wrkMast.getLocNo());
            WorkTaskParams params = new WorkTaskParams();
            //出库和移库
            if(wrkMast.getIoType()==101&&!Cools.isEmpty(wrkMast.getStaNo())&& !wrkMast.getStaNo().equals("0")) {
                params.setType("out")
                        .setTaskNo(wrkMast.getWrkNo()+"")
                        .setSourceLocNo(wcsSourceLocNo)
                        .setLocNo(wcsLocNo)
                        .setStaNo(wrkMast.getStaNo())
                        .setTaskPri(wrkMast.getIoPri().intValue())
                        .setBarcode(wrkMast.getBarcode());
            }else if(wrkMast.getIoType()==2&& !Cools.isEmpty(wrkMast.getSourceStaNo())){
                params.setType("in")
                        .setTaskNo(wrkMast.getWrkNo()+"")
                        .setSourceStaNo(wrkMast.getSourceStaNo())
                        .setLocNo(wcsLocNo)
                        .setTaskPri(wrkMast.getIoPri().intValue())
                        .setBarcode(wrkMast.getBarcode());
            } else {
                params.setType("move")
                        .setTaskNo(wrkMast.getWrkNo()+"")
                        .setSourceLocNo(wcsSourceLocNo)
                        .setLocNo(wcsLocNo)
                        .setBarcode(wrkMast.getBarcode());
            }
            R r = wcsApiService.pubWrkToWcs(params);
            if (r.get("code").equals(200)){
                break;
            }
        };
    }
    /**
     * 自动生成跨区入任务
     *
     * @author Ryan
     * @date 2026/1/10 14:42
     */
    @Scheduled(cron = "0/3 * * * * ? ")
    private void autoInStack() {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", 15).eq("online_yn","N"));
        if (wrkMasts.isEmpty()) {
            return;
        }
        for (WrkMast wrkMast : wrkMasts) {
            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getLocNo()));
            // 构造跨区入库任务
            WrkMast inMast = new WrkMast();
            // 生成工作号
            int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(1));
            inMast.setWrkNo(workNo);          // 生成新任务号
            inMast.setBarcode(wrkMast.getBarcode());                // 托盘码保持一致
            inMast.setIoType(2);                                 // 跨区入库类型
            inMast.setWrkSts(1L);                                // 待下发
            inMast.setLocNo(wrkMast.getLocNo());              // 原目标库位
            inMast.setIoPri(13.0);
            inMast.setSourceStaNo(wrkMast.getStaNo());
            inMast.setWrkCode(wrkMast.getWrkNo()+"");                  // 关联原出库任务
            inMast.setAppeUser(wrkMast.getAppeUser());              // 申请人
            inMast.setAppeTime(new Date());
            inMast.setIoTime(new Date());
            inMast.setCrnNo(locMast.getCrnNo());
            if(!wrkMastService.insert(inMast)){
                throw new CoolException("跨区入库任务生成失败!");
            }else {
                wrkMast.setOnlineYn("Y");
                wrkMastService.updateById(wrkMast);
            }
        }
    }
}
src/main/java/com/zy/asrs/task/handler/WorkLogHandler.java
@@ -94,9 +94,9 @@
            // 出库 --------------------------------------------------------------------------------
            } else if (wrkMast.getWrkSts() == 15) {
                if (!Objects.isNull(wrkMast.getWrkCode())) {
                    return FAIL;
                }
//                if (!Objects.isNull(wrkMast.getWrkCode())) {
//                    return FAIL;
//                }
//                if (!Cools.isEmpty(wrkDetls)) {
//                    if (!orderService.saveHandlerOrder(Boolean.FALSE, wrkMast, wrkDetls)) {
//                        exceptionHandle("生成手动出库单据[workNo={0}]失败", wrkMast.getWrkNo());
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -469,25 +469,28 @@
        }
        /***/
        if (!Objects.isNull(wrkMast.getWrkCode())) {
            LocMast lcmst = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getSourceLocNo()));
            lcmst.setLocSts(LocStsType.LOC_STS_TYPE_O.type);
            if (!locMastService.updateById(lcmst)) {
                throw new CoolException("库位状态修改失败!!");
            }
        if (wrkMast.getIoType() !=2){
            if (!Objects.isNull(wrkMast.getWrkCode())) {
                LocMast lcmst = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", wrkMast.getSourceLocNo()));
                lcmst.setLocSts(LocStsType.LOC_STS_TYPE_O.type);
                if (!locMastService.updateById(lcmst)) {
                    throw new CoolException("库位状态修改失败!!");
                }
            LocAroundBind bLocNo = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_no", wrkMast.getSourceLocNo()));
            if (Objects.isNull(bLocNo)) {
                throw new CoolException("工位不存在 !!");
            }
            bLocNo.setLocType(LocStsType.LOC_STS_TYPE_O.type);
            if (!locAroundBindService.updateById(bLocNo)) {
                throw new CoolException("工位状态修改失败!!");
            }
                LocAroundBind bLocNo = locAroundBindService.selectOne(new EntityWrapper<LocAroundBind>().eq("b_loc_no", wrkMast.getSourceLocNo()));
                if (Objects.isNull(bLocNo)) {
                    throw new CoolException("工位不存在 !!");
                }
                bLocNo.setLocType(LocStsType.LOC_STS_TYPE_O.type);
                if (!locAroundBindService.updateById(bLocNo)) {
                    throw new CoolException("工位状态修改失败!!");
                }
            locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no", wrkMast.getSourceLocNo()));
                locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no", wrkMast.getSourceLocNo()));
            }
        }
        return SUCCESS;
    }
src/main/java/com/zy/asrs/utils/OrderExcelListener.java
@@ -126,7 +126,7 @@
        detl.setModel(data.getModel());
        detl.setBrand(data.getBrand());
        detl.setSpecs(data.getSpecs());
        detl.setBatch(Objects.isNull(data.getBatch()) ? "1" : data.getBatch());
        detl.setBatch(Objects.isNull(data.getBatch()) ? "" : data.getBatch());
        detl.setVolume(mat.getVolume());
        detl.setSafeQty(mat.getSafeQty());
        detl.setAnfme(data.getAnfme());
src/main/java/com/zy/asrs/utils/Utils.java
@@ -203,6 +203,23 @@
    }
    /**
     * 将 1-1-1 格式的库位转换为 0100101 格式 (排-列-层)
     * 兼容 1-11-1 -> 0101101
     * @param locStr 1-1-1
     * @return 0100101
     */
    public static String convertLocFormat(String locStr) {
        if (Cools.isEmpty(locStr)) {
            return null;
        }
        String[] split = locStr.split("-");
        if (split.length != 3) {
            return locStr;
        }
        return zerofill(split[0].trim(), 2) + zerofill(split[1].trim(), 3) + zerofill(split[2].trim(), 2);
    }
    /**
     * 通过库位号获取 列
     */
    public static int getBay(String locNo) {
@@ -665,4 +682,40 @@
        return sdf.format(date);
    }
    //将wms库位号转换成wcs库位号
    public static String WMSLocToWCSLoc(String locNo) {
        String row = locNo.substring(0, 2);
        int i = 0;
        for (char c : row.toCharArray()) {
            if (c == '0') {
                i++;
            }else {
                break;
            }
        }
        row = row.substring(i);
        int j = 0;
        String boy = locNo.substring(2, 5);
        for (char c : boy.toCharArray()) {
            if (c == '0') {
                j++;
            }else {
                break;
            }
        }
        boy = boy.substring(j);
        int k = 0;
        String lev = locNo.substring(5);
        for (char c : lev.toCharArray()) {
            if (c == '0') {
                k++;
            }else {
                break;
            }
        }
        lev = lev.substring(k);
        return row + "-" + boy + "-" + lev;
    }
}
src/main/java/com/zy/common/model/DetlDto.java
@@ -35,6 +35,9 @@
    private Double anfme;
    //机台
    private String devNo;
    public DetlDto() {
    }
src/main/java/com/zy/common/model/LocTypeDto.java
@@ -26,10 +26,10 @@
    }
    public LocTypeDto(BasDevp basDevp) {
        if (basDevp.getLocType1() == null || basDevp.getLocType1() == 0) {
        if (basDevp.getLocType1() == null) {
            throw new CoolException("plc高低检测异常");
        }
        if (basDevp.getLocType1() == 1) {
        if (basDevp.getLocType1() == 0) {
            this.locType1 = 1; // 低库位
        } else {
            this.locType1 = 2; // 高库位
src/main/java/com/zy/common/model/StartupDto.java
@@ -18,4 +18,10 @@
    private Integer workNo;
    private Integer taskNo;
    private String barcode;
    private Integer taskPri;
}
src/main/java/com/zy/common/service/CommonService.java
@@ -130,14 +130,13 @@
            RowLastno rowLastno = rowLastnoService.selectById(whsType);
            RowLastnoType rowLastnoType = rowLastnoTypeService.selectById(rowLastno.getTypeId());
            /**
             * 库型 1: 标准堆垛机库  2: 平库  3: 穿梭板  4: 四向车  5: AGV  0: 未知
             * 库型 1: 标准堆垛机库  2: 同巷道找库位  3: 穿梭板  4: 四向车  5: AGV  0: 未知
             */
            switch (rowLastnoType.getType()) {
                case 1:
                    return getLocNoRun(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 0, locTypeDto, 0);
                case 2:
                    log.error("站点={} 未查询到对应的规则", sourceStaNo);
                    break;
                    return getLocNoRun(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 0, locTypeDto, 0);
                case 3:
                    log.error("站点={} 未查询到对应的规则", sourceStaNo);
                    break;
@@ -154,6 +153,33 @@
            log.error("站点={} 未查询到对应的规则", sourceStaNo);
        }
        return null;
    }
    /**
     * 检索库位号
     */
    @Transactional
    public StartupDto getLocNo1(Integer crnNo) {
        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                .eq("crn_no", crnNo)
                .eq("loc_sts","O")
                .eq("whs_type",1)
                .orderBy("lev1,bay1"));
        if (Cools.isEmpty(locMast)) {
            return null;
        }
        StartupDto startupDto = new StartupDto();
        String locNo = locMast.getLocNo();
        // 生成工作号
        int workNo = getWorkNo(0);
        // 返回dto
        startupDto.setWorkNo(workNo);
        startupDto.setCrnNo(crnNo);
//        startupDto.setSourceStaNo(sourceStaNo);
        startupDto.setLocNo(locNo);
        return startupDto;
    }
    /**
@@ -374,65 +400,15 @@
        // 1.按规则查找库位
        if (Cools.isEmpty(locMast) && crnNo != 0) {
            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
                    .eq("row1", nearRow)
                    .eq("frozen", 0).eq("deleted", 0)
                    .eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue())
                    .orderBy("lev1", true).orderBy("bay1", true));
            for (LocMast locMast1 : locMasts) {
                if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
                    continue;
                }
                if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
                    String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
                    LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
                            .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
                    if (!Cools.isEmpty(locMast2)) {
                        locMast = locMast2;
                        break;
                    }
                } else {
                    if (!Cools.isEmpty(locMast1)) {
            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().eq("loc_sts", "O").eq("crn_no", crnNo).eq("whs_type", rowLastnoType.getType().longValue()).orderBy("lev1").orderBy("bay1"));
            if (!locMasts.isEmpty()) {
                for (LocMast locMast1 : locMasts) {
                    if (basCrnpService.checkSiteError(crnNo, true)) {
                        locMast = locMast1;
                        break;
                    }
                }
            }
            if (Cools.isEmpty(locMast) && Utils.BooleanWhsTypeStaIoType(rowLastno)) {
                for (LocMast locMast1 : locMasts) {
                    if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
                        continue;
                    }
                    if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
                        String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
                        LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
                                .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
                        if (!Cools.isEmpty(locMast2)) {
                            locMast = locMast2;
                            break;
                        } else {
                            locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
                                    .eq("loc_no", shallowLoc).eq("loc_sts", "F").eq("whs_type", rowLastnoType.getType().longValue()));
                            if (!Cools.isEmpty(locMast2)) {
                                locMast = locMast1;
                                break;
                            } else {
                                locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
                                        .eq("loc_no", shallowLoc).eq("loc_sts", "D").eq("whs_type", rowLastnoType.getType().longValue()));
                                if (!Cools.isEmpty(locMast2)) {
                                    locMast = locMast1;
                                    break;
                                }
                            }
                        }
                    } else {
                        if (!Cools.isEmpty(locMast1)) {
                            locMast = locMast1;
                            break;
                        }
                    }
                }
            }
        }
src/main/java/com/zy/common/web/WcsController.java
@@ -9,11 +9,15 @@
import com.zy.asrs.entity.param.EmptyPlateOutParam;
import com.zy.asrs.entity.result.FindLocNoAttributeVo;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.MatServiceImpl;
import com.zy.asrs.utils.Utils;
import com.zy.common.CodeRes;
import com.zy.common.model.LocTypeDto;
import com.zy.common.model.StartupDto;
import com.zy.common.service.CommonService;
import com.zy.common.web.param.SearchLocParam;
import com.zy.system.entity.Config;
import com.zy.system.service.impl.ConfigServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@@ -50,6 +54,10 @@
    private RowLastnoService rowLastnoService;
    @Autowired
    private WorkService workService;
    @Autowired
    private ConfigServiceImpl configService;
    @Autowired
    private MatServiceImpl matService;
    @PostMapping("/pakin/loc/v1")
    @ResponseBody
@@ -63,8 +71,55 @@
        }
        List<WaitPakin> waitPakins = null;
        if (param.getIoType() == 1) {
            //处理托盘码
            //3S19000677895,M22003772,3  ,KP, 0A2030  ,0A2030202306050023
            //3S箱码号      ,端子物料号 ,数量,单位,供应商编号,供应商批次号
            //数量和重量转换出来的是否差不多
            //weight 为 43.39  去皮2.35  = 41.05
            //托盘码例子  845000820308,M11000787,1000,MT,0A1263,0A126320260120
            //换算需要41.05*24.36约等于1000
            if (Cools.isEmpty(param.getBarcode())) {
                return R.error("条码不能为空");
            }
            String[] split = param.getBarcode().split(",");
            String barcode = split[0];
            String matnr = split[1];
            Double weight = Double.valueOf(split[2]);
            String unit = split[3];
            String manu = split[4];
            String batch = split[5];
            String threeCode = param.getBarcode();
            param.setBarcode(barcode);
            //实际称重数量
            Double m = param.getWeight() -2.35;
            Mat mat = matService.selectByMatnr(matnr);
            if(mat==null){
                log.info("没有找到该物料档案--"+matnr+"组托时自动新增物料,默认24.36KG/M");
                mat = new Mat();
                mat.setTagId(1L);
                mat.setLocType(1L);
                mat.setMatnr(matnr);
                mat.setUnit(unit);
                mat.setManu(manu);
                mat.setMaktx(matnr);
                mat.setVolume(24.36);
                matService.insert(mat);
            }else {
                //暂定
            }
            m=m*mat.getVolume();
            //Double val = Math.round((m - matnr.getSafeQty()) * 10000) / 10000.0;
            Config config = configService.selectConfigByCode("SimulationInbound");
            if (config != null && config.getValue().equals("Y")) {
                WaitPakin waitPakin1 = waitPakinService.selectOne(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
                if (Cools.isEmpty(waitPakin1)) {
                    WaitPakin waitPakin = waitPakinService.selectOne(new EntityWrapper<WaitPakin>().eq("io_status", "N"));
                    if (waitPakin != null) {
                        waitPakinService.updateForSet("zpallet = '" + param.getBarcode() + "'", new EntityWrapper<WaitPakin>().eq("zpallet", waitPakin.getZpallet()));
                    }
                }
            }
            waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
            if (Cools.isEmpty(waitPakins)) {
@@ -72,8 +127,31 @@
                if (wrkMast != null && wrkMast.getIoType() == 103) {
                    return R.parse(CodeRes.PICK_600);
                }
                return R.parse(CodeRes.NO_COMB_700);
                WaitPakin waitPakin = new WaitPakin();
                waitPakin.sync(mat);
                waitPakin.setZpallet(param.getBarcode());
                waitPakin.setAnfme(m);
                waitPakin.setThreeCode(threeCode);
                waitPakinService.insert(waitPakin);
            }else {
                for(WaitPakin waitPakin : waitPakins){
                    waitPakin.setAnfme(m);
                    waitPakinService.update(waitPakin,new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
                }
            }
            //实际长度
            WaitPakin waitPakin = waitPakinService.selectOne(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
            if (Cools.isEmpty(waitPakin)) {
                return R.error(CodeRes.NO_COMB_700);
            }
            boolean flag = false;
            if(Cools.isEmpty(waitPakin.getBeBatch())||waitPakin.getBeBatch()!=1){
                flag = true;
            }
            if (flag && (weight - m < -2.0 || weight - m > 2.0)) {
                return R.error("二维码="+threeCode+"的物料实际称重转换成的米数和物料标签提供的米数相差较大需要退回或者标记后才能入库!");
            }
            int countLoc = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet",param.getBarcode()));
            int countWrk = wrkDetlService.selectCount(new EntityWrapper<WrkDetl>().eq("zpallet",param.getBarcode()));
            if (countLoc > 0 || countWrk > 0) {
@@ -102,6 +180,8 @@
                break;
        }
        log.info("WCS入库接口返参:{},托盘码:{}", dto, param.getBarcode());
        String wcsLoc = Utils.WMSLocToWCSLoc(dto.getLocNo());
        dto.setLocNo(wcsLoc);
        return R.ok().add(dto);
    }
@@ -168,6 +248,9 @@
//        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(matnrs.get(0), batchs.get(0));
        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0));
        StartupDto dto = commonService.getLocNo( 1, devpNo,findLocNoAttributeVo, locTypeDto);
        if (Cools.isEmpty(dto)) {
            throw new CoolException("没有找到库位");
        }
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
@@ -234,6 +317,9 @@
        } else {
            throw new CoolException(dto.getLocNo()+"目标库位已被占用");
        }
        dto.setBarcode(barcode);
        dto.setTaskNo(workNo);
        dto.setTaskPri(wrkMast.getIoPri().intValue());
        return dto;
    }
src/main/java/com/zy/common/web/param/SearchLocParam.java
@@ -17,4 +17,7 @@
    // 库位规格( 0:未知, 1:低库位, 2:高库位)
    private Short locType1;
    //重量
    private Double weight;
}
src/main/resources/application-dev.yml
@@ -12,8 +12,8 @@
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: sa
    password: sa@123
    url: jdbc:sqlserver://192.168.4.15:1433;databasename=jxhcwms
#    url: jdbc:sqlserver://127.0.0.1:1433;databasename=jxhcwms
#    url: jdbc:sqlserver://192.168.4.15:1433;databasename=jxhcwms
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=jxhcwms
  mvc:
    static-path-pattern: /**
  redis:
@@ -41,7 +41,7 @@
    path: /stock/out/@pom.build.finalName@/logs
super:
  pwd: asrs2023
  pwd: xltys1995
swagger:
  enable: false
@@ -98,16 +98,12 @@
    #登录地址
    loginaddress: K3CLOUD/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc
    #单据,商品档案地址
    inaddress: K3CLOUD/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc
    #结果上报(保存)单地址
    outaddressSave: K3CLOUD/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc
    #结果上报(提交)单地址
    outaddressSubmit: K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit.common.kdsvc
    #结果上报(审核)单地址
    outaddressAudit: K3CLOUD/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit.common.kdsvc
  #  登录账号管理
  login :
    acctID: "647e849ab6fa0f"
    username: "llw"
    password: "666666"
    lcid: 2052
#wcs对接
wcs:
  address:
    URL: http://127.0.0.1:9090/hcwcs
    deviceStatus: openapi/deviceStatus
    createOutTask: openapi/createOutTask
    createLocMoveTask: openapi/createLocMoveTask
    createInTask: openapi/createInTask
src/main/resources/mapper/LocAroundBindMapper.xml
@@ -8,7 +8,9 @@
        <result column="dev_id" property="devId" />
        <result column="dev_no" property="devNo" />
        <result column="b_loc_id" property="bLocId" />
        <result column="b_loc_no" property="bLocNo" />
        <result column="b_loc_no" property="blocNo" />
        <result column="order_no" property="orderNo" />
        <result column="freeze" property="freeze" />
    </resultMap>
src/main/resources/mapper/StaDescMapper.xml
@@ -21,7 +21,7 @@
    <select id="queryOutStaNosByLocNo" resultType="java.lang.Integer">
        select
        distinct asd.stn_no
        distinct asd.crn_stn
        from asr_sta_desc asd
        left join asr_loc_mast alm on asd.crn_no = alm.crn_no
        where 1=1
src/main/resources/mapper/WrkMastLogMapper.xml
@@ -61,6 +61,7 @@
        <result column="full_plt" property="fullPlt" />
        <result column="pre_have" property="preHave" />
        <result column="take_none" property="takeNone" />
        <result column="log_id" property="logId" />
    </resultMap>
    <sql id="queryWhere">
        <where>
src/main/resources/mapper/WrkMastMapper.xml
@@ -70,8 +70,8 @@
        select * from asr_wrk_mast
        where wrk_sts=5
        or (wrk_sts=15 and ove_mk='Y' and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and dateadd(mi,3,crn_end_time) &lt;= getdate() and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and crn_end_time is null and wrk_no not in (select wrk_no from asr_bas_devp))
        or (wrk_sts=15 and dateadd(mi,3,crn_end_time) &lt;= getdate() and wrk_no not in (select wrk_no from asr_bas_devp) and ove_mk='Y')
        or (wrk_sts=15 and crn_end_time is null and wrk_no not in (select wrk_no from asr_bas_devp) and ove_mk='Y')
        order by io_time,wrk_no asc
    </select>
src/main/webapp/static/js/locMast/locMast.js
@@ -62,7 +62,7 @@
            // ,{field: 'scWeight', align: 'center',title: ''}
            // ,{field: 'invWh', align: 'center',title: ''}
            // ,{field: 'mk', align: 'center',title: ''}
            // ,{field: 'barcode', align: 'center',title: ''}
            ,{field: 'barcode', align: 'center',title: '托盘码'}
            // ,{field: 'PdcType', align: 'center',title: ''}
            // ,{field: 'ctnNo', align: 'center',title: ''}
            ,{field: 'locType1$', align: 'center',title: '高低类型', hide:true}
src/main/webapp/static/js/orderPakout/order.js
@@ -191,6 +191,7 @@
                            layer.msg('数量不能小于已作业数量', {icon: 2});
                            return false;
                        }
                        console.log(nList[xi]);
                    }
                    layer.load(2);
                    $.ajax({
src/main/webapp/static/js/waitPakin/waitPakin.js
@@ -24,6 +24,16 @@
                return html;
            }
        }
        , {
            field: 'beBatch', align: 'center', title: '是否允许', templet: function (row) {
                var html = "<input value='beBatch' type='checkbox' lay-skin='switch' lay-text='是|否' lay-filter='beBatchSwitch' table-index='" + row.LAY_TABLE_INDEX + "'";
                if (row.beBatch === 1) {
                    html += " checked ";
                }
                html += ">";
                return html;
            }
        }
        , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
        , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true})
    return cols;
@@ -84,6 +94,43 @@
        }
    });
    // 监听是否批次开关
    form.on('switch(beBatchSwitch)', function (obj) {
        var _index = $(obj.elem).attr('table-index');
        var cacheData = table.cache['waitPakin'];
        var row = cacheData[_index];
        if (!row) {
            layer.msg("无法获取行数据", {icon: 2});
            return;
        }
        var newState = obj.elem.checked ? 1 : 0;
        $.ajax({
            url: baseUrl + "/waitPakin/update/beBatch/auth",
            headers: {'token': localStorage.getItem('token')},
            data: JSON.stringify({zpallet: row.zpallet, beBatch: newState}),
            contentType: 'application/json;charset=UTF-8',
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    layer.msg(res.msg, {icon: 1});
                    row.beBatch = newState; // 更新缓存
                } else {
                    layer.msg(res.msg, {icon: 2});
                    obj.elem.checked = !obj.elem.checked;
                    form.render('checkbox');
                }
            },
            error: function () {
                layer.msg("请求失败", {icon: 2});
                obj.elem.checked = !obj.elem.checked;
                form.render('checkbox');
            }
        });
    });
    // 监听排序事件
    table.on('sort(locMast)', function (obj) {
        var searchData = {};
src/main/webapp/views/locMast/locMast.html
@@ -68,6 +68,11 @@
        </div>
        <div class="layui-inline">
            <div class="layui-input-inline">
                <input class="layui-input" type="text" name="barcode" placeholder="托盘码" autocomplete="off">
            </div>
        </div>
        <div class="layui-inline">
            <div class="layui-input-inline">
                <input class="layui-input" type="text" name="crn_no" placeholder="堆垛机号" autocomplete="off">
            </div>
        </div>
src/main/webapp/views/locMast/locMast_detail.html
@@ -95,6 +95,12 @@
            </div>
        </div>
        <div class="layui-inline"  style="width:80%;">
            <label class="layui-form-label">托盘码:</label>
            <div class="layui-input-inline">
                <input id="barcode" class="layui-input" type="text" autocomplete="off" >
            </div>
        </div>
        <div class="layui-inline"  style="width:80%;">
            <label class="layui-form-label">堆垛机号:</label>
            <div class="layui-input-inline">
                <input id="crnNo" class="layui-input" type="text" autocomplete="off" disabled="disabled">
@@ -218,12 +224,6 @@
            <label class="layui-form-label">:</label>
            <div class="layui-input-inline">
                <input id="mk" class="layui-input" type="text">
            </div>
        </div>
        <div class="layui-inline"  style="width:31%;display: none">
            <label class="layui-form-label">:</label>
            <div class="layui-input-inline">
                <input id="barcode" class="layui-input" type="text">
            </div>
        </div>
        <div class="layui-inline"  style="width:31%;display: none">