自动化立体仓库 - WMS系统
7个文件已添加
16个文件已修改
956 ■■■■ 已修改文件
src/main/java/com/zy/api/controller/HmesApiController.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/WcsApiController.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/params/PageRequestParams.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/params/WorkTaskParams.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/HmesApiService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/WcsApiService.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocAroundBindController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OutController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocAroundBind.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/InitDeviceLocParams.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/constant/MesConstant.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locAroundBind/locAroundBind.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakout/order.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakout/out.js 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/wrkMast/wrkMast.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locAroundBind/locAroundBind.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderPakout/out.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/api/controller/HmesApiController.java
@@ -1,14 +1,67 @@
package com.zy.api.controller;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.service.HmesApiService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@Api(value = "HMES对接")
@RestController
@RequestMapping("/api")
public class HmesApiController {
    @Autowired
    private HmesApiService hmesApiService;
    /**
     * 人工穿线
     * @author Ryan
     * @date 2026/1/10 10:40
     * @return com.core.common.R
     */
    @ManagerAuth
    @ApiOperation("下发生产任务")
    @PostMapping("/work/tasks")
    public R menauWork(ReceviceTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
            return R.error("机台号不能为空!!");
        }
        return hmesApiService.pubWorkTask(params);
    }
    /**
     * 穿线完成,释放机台周边库位
     * @author Ryan
     * @date 2026/1/10 11:06
     * @param params
     * @return com.core.common.R
     */
    @ManagerAuth
    @ApiOperation("下发生产任务")
    @PostMapping("/work/release/lock")
    public R releaseLock(ReceviceTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
            return R.error("机台号不能为空!!");
        }
        return hmesApiService.releaseLock(params);
    }
}
src/main/java/com/zy/api/controller/WcsApiController.java
New file
@@ -0,0 +1,82 @@
package com.zy.api.controller;
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 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 java.util.Objects;
@Api("WCS交互接口")
@RequestMapping("/wcs")
@RestController
public class WcsApiController {
    @Autowired
    private WcsApiService wcsApiService;
    /**
     * 通知WCS锁定周边库位,及禁止任务执行
     * @author Ryan
     * @date 2026/1/10 11:13
     * @return com.core.common.R
     */
    @ManagerAuth
    @ApiOperation("锁定机台周边库位执行任务")
    @PostMapping("/lock/locs")
    public R reportLockLocs(@RequestBody ReceviceTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        if (Objects.isNull(params.getDeviceNo())) {
            return R.error("机台号不能为空!!");
        }
        return wcsApiService.lockLocs(params);
    }
    /**
     * 回库搬运指令
     * @author Ryan
     * @date 2026/1/10 13:08
     * @param params
     * @return com.core.common.R
     */
    @ManagerAuth
    @ApiOperation("堆垛机回库搬运指令")
    @PostMapping("/back/loc")
    public R backLoc(@RequestBody WorkTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        return wcsApiService.backLocs(params);
    }
    /**
     * 下发任务至WCS
     * @author Ryan
     * @date 2026/1/10 13:57
     * @param params
     * @return com.core.common.R
     */
    @ManagerAuth
    @ApiOperation("下发任务至WCS")
    @PostMapping("/pub/wrks")
    public R pubWrkToWcs(@RequestBody WorkTaskParams params) {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
        return wcsApiService.pubWrkToWcs(params);
    }
}
src/main/java/com/zy/api/controller/params/PageRequestParams.java
@@ -13,7 +13,4 @@
    private Integer limit = 50;
    private String pro_komcode;
    private String pro_id;
}
src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java
New file
@@ -0,0 +1,18 @@
package com.zy.api.controller.params;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@ApiModel(value = "ReceviceTaskParams", description = "穿线墙参数")
public class ReceviceTaskParams implements Serializable {
    @ApiModelProperty("机台号")
    private String deviceNo;
}
src/main/java/com/zy/api/controller/params/WorkTaskParams.java
New file
@@ -0,0 +1,39 @@
package com.zy.api.controller.params;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@ApiModel(value = "WorkTaskParams", description = "执行任务参数")
public class WorkTaskParams implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("协议任务编号(对应出库任务号)")
    private String taskNo;
    @ApiModelProperty("工作档任务号")
    private String wrkNo;
    @ApiModelProperty("库位编码")
    private String locNo;
    @ApiModelProperty("条码")
    private String barcode;
    @ApiModelProperty("优先级")
    private String taskPri;
    @ApiModelProperty("出库站点")
    private String staNo;
    @ApiModelProperty("作业类型,in: 入库, out:出库")
    private String type;
}
src/main/java/com/zy/api/service/HmesApiService.java
New file
@@ -0,0 +1,11 @@
package com.zy.api.service;
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
public interface HmesApiService {
    R pubWorkTask(ReceviceTaskParams params);
    R releaseLock(ReceviceTaskParams params);
}
src/main/java/com/zy/api/service/WcsApiService.java
New file
@@ -0,0 +1,47 @@
package com.zy.api.service;
import com.core.common.R;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.controller.params.WorkTaskParams;
import java.util.Set;
public interface WcsApiService {
    /**
     * 锁定库位信息
     * @author Ryan
     * @date 2026/1/10 11:17
     * @param params
     * @return com.core.common.R
     */
    R lockLocs(ReceviceTaskParams params);
    /**
     * 回库搬运指令
     * @author Ryan
     * @date 2026/1/10 13:08
     * @param params
     * @return com.core.common.R
     */
    R backLocs(WorkTaskParams params);
    /**
     * 下发任务至WCS
     * @author Ryan
     * @date 2026/1/10 13:57
     * @param params
     * @return com.core.common.R
     */
    R pubWrkToWcs(WorkTaskParams params);
    /**
     * 锁定或释放库位
     * @author Ryan
     * @date 2026/1/10 14:35
     * @param locs
     * @param type
     */
    void reportLockLocs(Set<String> locs, String type);
}
src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java
@@ -519,12 +519,12 @@
    @Override
    public XSR getStockInfo(PageRequestParams params) {
        EntityWrapper<LocDetl> wrapper = new EntityWrapper<>();
        if (!Objects.isNull(params.getPro_id())) {
            wrapper.eq("supp_code", params.getPro_id());
        }
        if (!Objects.isNull(params.getPro_komcode())) {
            wrapper.eq("matnr", params.getPro_komcode());
        }
//        if (!Objects.isNull(params.getPro_id())) {
//            wrapper.eq("supp_code", params.getPro_id());
//        }
//        if (!Objects.isNull(params.getPro_komcode())) {
//            wrapper.eq("matnr", params.getPro_komcode());
//        }
        Page<LocDetl> locDetls = locDetlService.selectPage(new Page<>(params.getCurr(), params.getLimit()),  wrapper);
src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java
New file
@@ -0,0 +1,130 @@
package com.zy.api.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.R;
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.enums.LocStsType;
import com.zy.asrs.service.BasDeviceService;
import com.zy.asrs.service.LocAroundBindService;
import com.zy.asrs.service.LocMastService;
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.stream.Collectors;
@Service
public class HmesApiServiceImpl implements HmesApiService {
    @Autowired
    private BasDeviceService basDeviceService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private WcsApiService wcsApiService;
    /**
     * 接收MES穿线任务
     * @author Ryan
     * @date 2026/1/10 10:54
     * @param params
     * @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>()
                .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("工作台周边库位禁用失败,不可执行穿线操作!!");
            }
        });
        return R.ok("可执行穿线动作!!");
    }
    /**
     * 穿线完成,释放机台周边库位
     * @author Ryan
     * @date 2026/1/10 11:07
     * @param params
     * @return com.core.common.R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R releaseLock(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());
        List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>().in("loc_no", locs).eq("loc_sts", LocStsType.LOC_STS_TYPE_X.type));
        if (Objects.isNull(locMasts) || locMasts.isEmpty()) {
            throw new CoolException("没有禁用库位,不需要释放!!");
        }
        locMasts.forEach(loc -> {
           loc.setLocSts(LocStsType.LOC_STS_TYPE_O.type);
           if (!locMastService.updateById(loc)) {
               throw new CoolException("库位释放失败,请检查后再操作!!");
           }
        });
        wcsApiService.reportLockLocs(locs, "lock");
        return R.ok("释放成功 !!");
    }
}
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
New file
@@ -0,0 +1,178 @@
package com.zy.api.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.R;
import com.core.exception.CoolException;
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.BasDevice;
import com.zy.asrs.entity.LocAroundBind;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasDeviceService;
import com.zy.asrs.service.LocAroundBindService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.constant.MesConstant;
import com.zy.common.utils.HttpHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class WcsApiServiceImpl implements WcsApiService {
    @Autowired
    private BasDeviceService basDeviceService;
    @Autowired
    private LocAroundBindService locAroundBindService;
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private WrkMastService wrkMastService;
    /**
     * 通知WCS锁定库位,及禁止当前库位的一切操作
     * @author Ryan
     * @date 2026/1/10 11:18
     * @param params
     * @return com.core.common.R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R lockLocs(ReceviceTaskParams params) {
        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());
        reportLockLocs(locs, "lock");
        return R.ok("上报成功!!");
    }
    /**
     * 余料回库 (搬运余料回库)
     * @author Ryan
     * @date 2026/1/10 13:19
     * @param params
     * @return com.core.common.R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R backLocs(WorkTaskParams params) {
        if (Objects.isNull(params.getTaskNo())) {
            throw new CoolException("工作号不能为空!!");
        }
        String wrkCode = params.getTaskNo();
       if (wrkCode.contains("-1")) {
           throw new CoolException("配对任务编码错误,请检查后重新上传!!");
       }
        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_code", params.getTaskNo()));
       if (Objects.isNull(mast)) {
           throw new CoolException("任务不存在!!");
       }
       if (!mast.getWrkSts().equals(103L)) {
           throw new CoolException("当前任务并非余料出库任务!!");
       }
        mast.setWrkSts(53L);
       if (!wrkMastService.updateById(mast)) {
           throw new CoolException("任务状态更新失败!!");
       }
       return R.ok("接收成功,执行回库中...");
    }
    /**
     * 下发任务至WCS
     * @author Ryan
     * @date 2026/1/10 13:58
     * @param params
     * @return com.core.common.R
     */
    @Override
    public R pubWrkToWcs(WorkTaskParams params) {
        if (Objects.isNull(params.getTaskNo())) {
            return R.error("任务号不能为空!!");
        }
        if (Objects.isNull(params.getBarcode())) {
            return R.error("托盘码不能为空!!");
        }
        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 response;
        try {
            response =  new HttpHandler.Builder()
                    .setUri(MesConstant.URL)
                    .setPath(url)
                    .setJson(JSON.toJSONString(params))
                    .build()
                    .doPost();
            R result = JSON.parseObject(response, R.class);
            if (result.get("code").equals("200")) {
                //TODO 上报是否成功
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }
    /**
     * 上报锁定/释放库位信息
     * @author Ryan
     * @date 2026/1/10 12:50
     * @param locs
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reportLockLocs(Set<String> locs, String type) {
        String url = MesConstant.LOCK_LOCS_URL;
        if (!Objects.isNull(type)) {
            if (type.equals("release")) {
                url = MesConstant.RELEASE_LOCS_URL;
            }
        }
        String response;
        try {
          response =  new HttpHandler.Builder()
            .setUri(MesConstant.URL)
            .setPath(url)
            .setJson(JSON.toJSONString(locs))
            .build()
            .doPost();
          R result = JSON.parseObject(response, R.class);
          if (result.get("code").equals("200")) {
                //TODO 上报是否成功
          }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
src/main/java/com/zy/asrs/controller/LocAroundBindController.java
@@ -126,7 +126,7 @@
    }
    /**
     * 台机绑定作业库位
     * 机台绑定作业库位
     *
     * @param
     * @return
@@ -138,7 +138,7 @@
            return R.error("参数不能为空");
        }
        if (Cools.isEmpty(params.getDevNo())) {
            return R.error("台机号不能为空");
            return R.error("机台号不能为空");
        }
        if (Cools.isEmpty(params.getStartRow())) {
            return R.error("起始排不能为空");
src/main/java/com/zy/asrs/controller/OutController.java
@@ -224,8 +224,6 @@
            if (!Objects.isNull(taskDto.getDeviceNo())) {
                //生成出库任务
                workService.stockOut(staNo, taskDto, taskDto.getDeviceNo(), getUserId());
                //生成匹配的入库(出库)任务
                workService.genInStock(staNo, taskDto, taskDto.getDeviceNo(), getUserId());
            } else  {
                workService.stockOut(staNo, taskDto, null, getUserId());
            }
src/main/java/com/zy/asrs/entity/LocAroundBind.java
@@ -20,16 +20,16 @@
    private Long id;
    /**
     * 台机ID
     * 机台ID
     */
    @ApiModelProperty(value= "台机ID")
    @ApiModelProperty(value= "机台ID")
    @TableField("dev_id")
    private Long devId;
    /**
     * 台机号
     * 机台号
     */
    @ApiModelProperty(value= "台机号")
    @ApiModelProperty(value= "机台号")
    @TableField("dev_no")
    private String devNo;
@@ -57,8 +57,8 @@
    }
//    LocAroundBind locAroundBind = new LocAroundBind(
//            null,    // 台机ID[非空]
//            null,    // 台机号[非空]
//            null,    // 机台ID[非空]
//            null,    // 机台号[非空]
//            null,    // 库位ID[非空]
//            null    // 库位码[非空]
//    );
src/main/java/com/zy/asrs/entity/param/InitDeviceLocParams.java
@@ -7,13 +7,13 @@
import io.swagger.annotations.ApiModel;
@Data
@ApiModel(value = "InitDeviceLocParams", description = "初始化台机库位参数")
@ApiModel(value = "InitDeviceLocParams", description = "初始化机台库位参数")
@Accessors(chain = true)
public class InitDeviceLocParams implements Serializable {
    private static final long serialVersionUID = 1L;
    // 台机号
    // 机台号
    private String devNo;
    // 起始排
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -25,6 +25,8 @@
import com.zy.common.service.CommonService;
import com.zy.common.web.WcsController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -419,38 +421,8 @@
        //TODO 1. 如果是同一台堆垛机,生成移库(出库)任务  2. 如果不是,生成出库任务,再生成入库任务
        //TODO 另一种方案,不管是否当前巷道,统一出库,再入库
        if (!Objects.isNull(deviceNo)) {
            wrkCode = wrkCode + "-1";
//            BasDevice basDevice = basDeviceService.selectOne(new EntityWrapper<BasDevice>()
//                    .eq("status", 1)
//                    .eq("dev_no", deviceNo));
//            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 mast = locMastService.selectOne(new EntityWrapper<LocMast>()
//                    .in("loc_no", locs)
//                    .eq("loc_sts", LocStsType.LOC_STS_TYPE_O.type)
//                    .eq("dev_no", basDevice.getDevNo())
//                    .orderAsc(Arrays.asList("loc_no"))
//                    .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY"));
//
//            if (Objects.isNull(mast)) {
//                throw new CoolException("当前机台,无可用工作台!!");
//            }
//            //相同表示在同一个巷道
//            if (mast.getCrnNo().equals(locMast.getCrnNo())) {
//
//            } else {
//                wrkCode = wrkCode + "-1";
//
//            }
            wrkCode = workNo + "-1";
            generateOutStock(taskDto, userId, workNo, wrkCode, now, ioType, locMast, staDesc, deviceNo);
        } else {
            generateOutStock(taskDto, userId, workNo, wrkCode, now, ioType, locMast, staDesc, null);
        }
@@ -538,11 +510,10 @@
            OrderInAndOutUtil.updateOrder(Boolean.FALSE, orderDetl.getOrderId(), 2L, userId);
        }
        //todo 判断设备号,生成入库任务
        //TODO 判断设备号,生成入库任务。没有机台号,说明是普通出库任务
        if (!Objects.isNull(deviceNo)) {
            genInStock(wrkMast, deviceNo, userId);
        }
        // 修改库位状态:   F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中
        locMast = locMastService.selectById(taskDto.getLocNo());
        if (locMast.getLocSts().equals("F")) {
@@ -1505,36 +1476,48 @@
        }
        List<LocAroundBind> binds = locAroundBindService.selectList(new EntityWrapper<LocAroundBind>().eq("dev_no", basDevice.getDevNo()));
        if (Objects.isNull(binds) || binds.isEmpty()) {
            throw new CoolException("台机未绑定工作站台!!");
            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_O.type)
                .eq("dev_no", basDevice.getDevNo())
                .orderAsc(Arrays.asList("loc_no"))
                .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY"));
        if (Objects.isNull(locMasts)) {
            throw new CoolException("当前机台,无可用工作台!!");
        }
       List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locMasts.getLocNo(),1);
        int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(1));
        List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locMasts.getLocNo(),1);
        //TODO 1. 获取入库站点, 目标库位  3. 将出库明细添加至入库明细
        Integer staNo = staNos.stream().findFirst().get();
        if (Objects.isNull(outMast.getWrkCode())) {
            throw new CoolException("数据错误,上级任务编码为空!!");
        }
        String wrkCode;
        int indexOf = outMast.getWrkCode().indexOf("-");
        if (indexOf != -1) {
            String substring = outMast.getWrkCode().substring(0, indexOf);
            wrkCode = substring + "-2";
        } else {
            throw new CoolException("数据错误,上级任务编码错误!!");
        }
        WrkMast wrkMast = new WrkMast();
        StartupDto dto = commonService.getLocNo(1, sourceStaNo.getDevNo(), findLocNoAttributeVo, locTypeDto);
//        int workNo = dto.getWorkNo();
        // 生成工作档
        wrkMast.setWrkNo(workNo);
        wrkMast.setWrkCode(wrkCode);
        wrkMast.setIoTime(new Date());
        wrkMast.setWrkSts(2L); // 工作状态:生成入库ID
        wrkMast.setIoType(1); // 入出库状态:1.入库
        wrkMast.setCrnNo(dto.getCrnNo());
        wrkMast.setSourceStaNo(dto.getSourceStaNo() + "");
        wrkMast.setStaNo(dto.getStaNo() + "");
        wrkMast.setLocNo(dto.getLocNo());
        wrkMast.setCrnNo(locMasts.getCrnNo());
        wrkMast.setSourceStaNo(outMast.getStaNo());
//        wrkMast.setStaNo(staNo + "");
        wrkMast.setLocNo(locMasts.getLocNo());
        wrkMast.setIoPri(13D); // 优先级
        wrkMast.setBarcode(pakin.getZpallet()); // 托盘码
        wrkMast.setBarcode(outMast.getBarcode()); // 托盘码
        wrkMast.setFullPlt("Y"); // 满板:Y
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
@@ -1542,60 +1525,41 @@
        wrkMast.setLinkMis("Y");
        wrkMast.setModiUser(userId);
        wrkMast.setAppeUser(userId);
        wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型
        wrkMast.setCtnType(locMasts.getCtnType()); // 容器类型
        // 操作人员数据
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
        wrkMast.setAppeTime(new Date());
        wrkMast.setModiTime(new Date());
        boolean res = wrkMastService.insert(wrkMast);
        if (!res) {
            throw new CoolException("保存工作档失败");
        }
        // 更新源站点信息
        sourceStaNo.setWrkNo(workNo);
        sourceStaNo.setModiTime(now);
        if (!basDevpService.updateById(sourceStaNo)) {
            throw new CoolException("更新源站失败");
        }
//        sourceStaNo.setModiTime(now);
//        if (!basDevpService.updateById(sourceStaNo)) {
//            throw new CoolException("更新源站失败");
//        }
        // 更新目标库位状态
        LocMast locMast = locMastService.selectById(dto.getLocNo());
        if (locMast.getLocSts().equals("O")) {
            locMast.setLocSts("S"); // S.入库预约
            locMast.setModiTime(now);
            if (!locMastService.updateById(locMast)) {
//        LocMast locMast = locMastService.selectById(dto.getLocNo());
        if (locMasts.getLocSts().equals("O")) {
            locMasts.setLocSts("S"); // S.入库预约
            locMasts.setModiTime(new Date());
            if (!locMastService.updateById(locMasts)) {
                throw new CoolException("改变库位状态失败");
            }
        } else {
            throw new CoolException(dto.getLocNo() + "目标库位已被占用");
            throw new CoolException(locMasts.getLocNo() + "目标库位已被占用");
        }
        // 更新入库通知档 ioStatus ===>> Y
        Wrapper<WaitPakin> wrapper = new EntityWrapper<WaitPakin>()
                .eq("zpallet", pakin.getZpallet());
        WaitPakin setParam = new WaitPakin();
        setParam.setLocNo(dto.getLocNo());
        setParam.setIoStatus("Y");
        setParam.setModiTime(now);
        if (!waitPakinService.update(setParam, wrapper)) {
            throw new CoolException("更新通知档失败");
        List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", outMast.getWrkNo()));
        if (Objects.isNull(wrkDetls) || wrkDetls.isEmpty()) {
            throw new CoolException("任务明细为空!!");
        }
        wrkDetls.forEach(wrkDetl -> {
            WrkDetl detl = new WrkDetl();
            BeanUtils.copyProperties(wrkDetl, detl);
            detl.setWrkNo(wrkMast.getWrkNo());
            if (!wrkDetlService.insert(detl)) {
                throw new CoolException("任务明细保存失败!!");
            }
        });
    }
    // 生成工作档明细
        waitPakins.forEach(waitPakin ->
    {
        WrkDetl wrkDetl = new WrkDetl();
        wrkDetl.sync(waitPakin);
        wrkDetl.setWrkNo(wrkMast.getWrkNo());
        wrkDetl.setIoTime(wrkMast.getIoTime());
        double v = Math.round(waitPakin.getAnfme() * waitPakin.getVolume() * 100) / 100.0;
        wrkDetl.setAnfme(v);
        wrkDetl.setAppeTime(now);
        wrkDetl.setModiTime(now);
        if (!wrkDetlService.insert(wrkDetl)) {
            throw new CoolException("保存工作明细失败");
        }
    });
}
}
src/main/java/com/zy/common/constant/MesConstant.java
@@ -14,6 +14,18 @@
    public static final String PAKOUT_URL = "wmsFinprd/api/zy/v1/packOut/sendList";
    /***上报MES,锁定同边库位*/
    public static final String LOCK_LOCS_URL = "";
    /***释放库位链接*/
    public static final String RELEASE_LOCS_URL = "";
    /***申请入库任务*/
    public static final String PUB_TASK_IN = "/openapi/createInTask";
    /***申请出库任务*/
    public static final String PUB_TASK_OUT = "/openapi/createOutTask";
    /**
     * token通过header传递的名称
     */
src/main/resources/mapper/LocDetlMapper.xml
@@ -27,7 +27,7 @@
        <result column="item_num" property="itemNum" />
        <result column="safe_qty" property="safeQty" />
        <result column="weight" property="weight" />
        <result column="man_length" property="manLength" />
<!--        <result column="man_length" property="manLength" />-->
        <result column="volume" property="volume" />
        <result column="three_code" property="threeCode" />
        <result column="supp" property="supp" />
@@ -124,17 +124,17 @@
            <when test="batch != null and batch != ''">
                and a.batch = #{batch}
            </when>
            <otherwise>
                and (a.batch IS NULL OR a.batch = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.batch IS NULL OR a.batch = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="brand != null and brand != ''">
                and a.brand = #{brand}
            </when>
            <otherwise>
                and (a.brand IS NULL OR a.brand = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.brand IS NULL OR a.brand = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="standby1 != null and standby1 != ''">
@@ -148,41 +148,41 @@
            <when test="standby2 != null and standby2 != ''">
                and a.standby2 = #{standby2}
            </when>
            <otherwise>
                and (a.standby2 IS NULL OR a.standby2 = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.standby2 IS NULL OR a.standby2 = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="standby3 != null and standby3 != ''">
                and a.standby3 = #{standby3}
            </when>
            <otherwise>
                and (a.standby3 IS NULL OR a.standby3 = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.standby3 IS NULL OR a.standby3 = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="boxType1 != null and boxType1 != ''">
                and a.box_type1 = #{boxType1}
            </when>
            <otherwise>
                and (a.box_type1 IS NULL OR a.box_type1 = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.box_type1 IS NULL OR a.box_type1 = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="boxType2 != null and boxType2 != ''">
                and a.box_type2 = #{boxType2}
            </when>
            <otherwise>
                and (a.box_type2 IS NULL OR a.box_type2 = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.box_type2 IS NULL OR a.box_type2 = '')-->
<!--            </otherwise>-->
        </choose>
        <choose>
            <when test="boxType3 != null and boxType3 != ''">
                and a.box_type3 = #{boxType3}
            </when>
            <otherwise>
                and (a.box_type3 IS NULL OR a.box_type3 = '')
            </otherwise>
<!--            <otherwise>-->
<!--                and (a.box_type3 IS NULL OR a.box_type3 = '')-->
<!--            </otherwise>-->
        </choose>
    </sql>
    <sql id="batchSeqNew">
src/main/webapp/static/js/locAroundBind/locAroundBind.js
@@ -23,8 +23,8 @@
        cols: [[
            { type: 'checkbox' }
            , { field: 'id', align: 'center', title: 'ID' }
            , { field: 'devId', align: 'center', title: '台机ID' }
            , { field: 'devNo', align: 'center', title: '台机号' }
            , { field: 'devId', align: 'center', title: '机台ID' }
            , { field: 'devNo', align: 'center', title: '机台号' }
            , { field: 'blocId', align: 'center', title: '库位ID', hide: true }
            , { field: 'blocNo', align: 'center', title: '库位码' }
            , { fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 120 }
@@ -127,7 +127,7 @@
                        if (res.data) {
                            layer.open({
                                type: 1,
                                title: '台机绑定作业库位',
                                title: '机台绑定作业库位',
                                area: ["400px"],
                                maxmin: true,
                                shadeClose: true,
src/main/webapp/static/js/orderPakout/order.js
@@ -125,7 +125,7 @@
                            {field: 'matnr', title: '商品编码', width: 160},
                            {field: 'maktx', title: '商品名称', width: 160},
                            {field: 'batch', title: '批号'},
                            {field: 'standby1', title: '台机'},
                            {field: 'standby1', title: '机台'},
                            {field: 'anfme', title: '数量'},
                            {field: 'workQty', title: '作业数量'},
                            {field: 'qty', title: '完成数量', style: 'font-weight: bold'},
@@ -239,7 +239,7 @@
                        {field: 'maktx', title: '商品名称', width: 200},
                        {field: 'batch', title: '批号', edit: true},
                        {field: 'specs', title: '规格'},
                        {field: 'standby1', title: '台机', edit: true},
                        {field: 'standby1', title: '机台', edit: true},
                        {field: 'anfme', title: '数量(修改)', style: 'color: blue;font-weight: bold', edit: true, minWidth: 110, width: 110},
                        {field: 'workQty', title: '作业数量',  minWidth: 100, width: 100},
                        // {field: 'unit', title: '单位', width: 80},
src/main/webapp/static/js/orderPakout/out.js
@@ -4,7 +4,7 @@
    base: baseUrl + "/static/layui/lay/modules/"
}).extend({
    notice: 'notice/notice',
}).use(['table','laydate', 'form', 'util', 'admin', 'notice', 'treeTable', 'xmSelect', 'tableMerge', 'tableX'], function(){
}).use(['table', 'laydate', 'form', 'util', 'admin', 'notice', 'treeTable', 'xmSelect', 'tableMerge', 'tableX'], function () {
    var table = layui.table;
    var $ = layui.jquery;
    var layer = layui.layer;
@@ -21,7 +21,7 @@
    insTb2 = table.render({
        elem: '#orderDetlTable',
        headers: {token: localStorage.getItem('token')},
        url: baseUrl+'/order/pakout/orderDetl/pakout/list/auth',
        url: baseUrl + '/order/pakout/orderDetl/pakout/list/auth',
        page: true,
        limit: 15,
        limits: [15, 30, 50, 100, 200, 500],
@@ -30,19 +30,19 @@
        where: {order_id: 9999999999},
        cols: [[
            {type: 'checkbox'}
            ,{type: 'numbers', title: '#'}
            ,{field: 'orderNo', align: 'center',title: '单据编号', templet: '#orderNoTpl', width: 160}
            ,{field: 'matnr', align: 'center',title: '商品编码', width: 160}
            ,{field: 'maktx', align: 'center',title: '商品名称', width: 200}
            ,{field: 'standby1', align: 'center',title: '台机号'}
            ,{field: 'specs', align: 'center',title: '规格'}
            , {type: 'numbers', title: '#'}
            , {field: 'orderNo', align: 'center', title: '单据编号', templet: '#orderNoTpl', width: 160}
            , {field: 'matnr', align: 'center', title: '商品编码', width: 160}
            , {field: 'maktx', align: 'center', title: '商品名称', width: 200}
            , {field: 'standby1', align: 'center', title: '机台号'}
            , {field: 'specs', align: 'center', title: '规格'}
            // ,{field: 'anfme', align: 'center',title: '数量'}
            // ,{field: 'qty', align: 'center',title: '作业数量', style: 'font-weight: bold'}
            ,{field: 'enableQty', align: 'center',title: '待出数量', style: 'font-weight: bold'}
            , {field: 'enableQty', align: 'center', title: '待出数量', style: 'font-weight: bold'}
            // ,{field: 'name', align: 'center',title: '名称'}
            // ,{field: 'model', align: 'center',title: '型号'}
            ,{field: 'unit', align: 'center',title: '单位', hide: true}
            ,{field: 'barcode', align: 'center',title: '商品条码', hide: true}
            , {field: 'unit', align: 'center', title: '单位', hide: true}
            , {field: 'barcode', align: 'center', title: '商品条码', hide: true}
            // ,{field: 'supplier', align: 'center',title: '供应商'}
            // ,{field: 'unitPrice', align: 'center',title: '单价'}
            // ,{field: 'itemNum', align: 'center',title: '品项数'}
@@ -54,7 +54,7 @@
            // ,{field: 'updateBy$', align: 'center',title: '修改人员'}
            // ,{field: 'updateTime$', align: 'center',title: '修改时间'}
            // ,{field: 'memo', align: 'center',title: '备注'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width: 160}
            , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 160}
        ]],
        request: {
            pageName: 'curr',
@@ -71,11 +71,11 @@
        response: {
            statusCode: 200
        },
        done: function(res, curr, count) {
        done: function (res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
                top.location.href = baseUrl + "/";
            }
            pageCurr=curr;
            pageCurr = curr;
            limit();
        }
    });
@@ -134,20 +134,20 @@
            success: function (res) {
                layer.close(loadIndex);
                var tableCache;
                if (res.code === 200){
                if (res.code === 200) {
                    layer.open({
                        type: 1
                        ,title: false
                        ,closeBtn: false
                        ,offset: '50px'
                        ,area: ['1200px', '700px']
                        ,shade: 0.5
                        ,shadeClose: false
                        ,btn: ['立即出库', '稍后处理']
                        ,btnAlign: 'c'
                        ,moveType: 1 //拖拽模式,0或者1
                        ,content: $('#pakoutPreviewBox').html()
                        ,success: function(layero, index){
                        , title: false
                        , closeBtn: false
                        , offset: '50px'
                        , area: ['1200px', '700px']
                        , shade: 0.5
                        , shadeClose: false
                        , btn: ['立即出库', '稍后处理']
                        , btnAlign: 'c'
                        , moveType: 1 //拖拽模式,0或者1
                        , content: $('#pakoutPreviewBox').html()
                        , success: function (layero, index) {
                            stoPreTabIdx = table.render({
                                elem: '#stoPreTab',
                                data: res.data,
@@ -159,12 +159,36 @@
                                    // {type: 'checkbox', merge: ['orderNo']},
                                    {field: 'orderNo', title: '单据编号', merge: true, align: 'center'},
                                    {field: 'title', title: '商品', merge: true, align: 'center', width: 350},
                                    {field: 'standby1', title: '台机号', align: 'center'},
                                    {field: 'anfme', title: '数量', align: 'center', width: 90, style: 'font-weight: bold'},
                                    {field: 'standby1', title: '机台号', align: 'center'},
                                    {
                                        field: 'anfme',
                                        title: '数量',
                                        align: 'center',
                                        width: 90,
                                        style: 'font-weight: bold'
                                    },
                                    {field: 'locNo', title: '货位', align: 'center', width: 100, templet: '#locNoTpl'},
                                    {field: 'frozen$', title: '明细', align: 'center', width: 90, templet: '#locFrozen'},
                                    {field: 'frozenLoc$', title: '库位', align: 'center', width: 90, templet: '#locFrozenLoc'},
                                    {field: 'staNos', align: 'center', title: '出库站', merge: ['locNo'], templet: '#tbBasicTbStaNos'},
                                    {
                                        field: 'frozen$',
                                        title: '明细',
                                        align: 'center',
                                        width: 90,
                                        templet: '#locFrozen'
                                    },
                                    {
                                        field: 'frozenLoc$',
                                        title: '库位',
                                        align: 'center',
                                        width: 90,
                                        templet: '#locFrozenLoc'
                                    },
                                    {
                                        field: 'staNos',
                                        align: 'center',
                                        title: '出库站',
                                        merge: ['locNo'],
                                        templet: '#tbBasicTbStaNos'
                                    },
                                    {type: 'checkbox', merge: ['locNo']},
                                ]],
                                done: function (res) {
@@ -175,9 +199,9 @@
                            });
                            // 修改出库站
                            form.on('select(tbBasicTbStaNos)', function (obj) {
                                let index  = obj.othis.parents('tr').attr("data-index");
                                let index = obj.othis.parents('tr').attr("data-index");
                                let data = tableCache[index];
                                for (let i = 0; i<tableCache.length; i++) {
                                for (let i = 0; i < tableCache.length; i++) {
                                    if (tableCache[i].locNo === data.locNo) {
                                        tableCache[i]['staNo'] = Number(obj.elem.value);
                                    }
@@ -194,18 +218,18 @@
                                }
                                modifySta(stoPreTabData);
                            });
                            // 批量修改出库站 - 站点选择
                            function modifySta(stoPreTabData) {
                                // 出库站取交集
                                let staBatchSelectVal = [];
                                for(let i = 0; i<stoPreTabData.length; i++) {
                                for (let i = 0; i < stoPreTabData.length; i++) {
                                    let staNos = stoPreTabData[i].staNos;
                                    if (staNos !== null) {
                                        if (staBatchSelectVal.length === 0) {
                                            staBatchSelectVal = staNos;
                                        } else {
                                            staBatchSelectVal = staBatchSelectVal.filter(val =>
                                                {
                                            staBatchSelectVal = staBatchSelectVal.filter(val => {
                                                    return new Set(staNos).has(val)
                                                }
                                            )
@@ -231,8 +255,8 @@
                                            let loadIdx = layer.load(2);
                                            let batchSta = Number(obj.field.batchSta);
                                            let arr = [];
                                            for (let j = 0; j<stoPreTabData.length; j++) {
                                                for (let i = 0; i<tableCache.length; i++) {
                                            for (let j = 0; j < stoPreTabData.length; j++) {
                                                for (let i = 0; i < tableCache.length; i++) {
                                                    if (tableCache[i].orderNo === stoPreTabData[j].orderNo
                                                        && tableCache[i].matnr === stoPreTabData[j].matnr
                                                        && tableCache[i].locNo === stoPreTabData[j].locNo) {
@@ -249,7 +273,8 @@
                                            arr.forEach(item => {
                                                $('div[lay-id=stoPreTab] tr[data-index="' + item + '"] .layui-select-title').find("input").css("color", "blue");
                                            });
                                            layer.close(loadIdx); layer.close(ddIndex);
                                            layer.close(loadIdx);
                                            layer.close(ddIndex);
                                            return false;
                                        });
                                        // 弹窗不出现滚动条
@@ -260,18 +285,18 @@
                            }
                        }
                        ,yes: function(index, layero){
                        , yes: function (index, layero) {
                            //按钮【立即出库】的回调
                            pakout(tableCache, index);
                        }
                        ,btn2: function(index, layero){
                        , btn2: function (index, layero) {
                            //按钮【稍后处理】的回调
                            layer.close(index)
                            //return false 开启该代码可禁止点击该按钮关闭
                        }
                    });
                } else if (res.code === 403){
                    top.location.href = baseUrl+"/";
                } else if (res.code === 403) {
                    top.location.href = baseUrl + "/";
                } else {
                    layer.msg(res.msg, {icon: 2})
                }
@@ -305,7 +330,6 @@
    }
    /* 删除订单 */
    function doDelSensor(obj) {
        layer.confirm('确定要删除选中数据吗?', {
@@ -315,18 +339,18 @@
            layer.close(i);
            var loadIndex = layer.load(2);
            $.ajax({
                url: baseUrl+"/sensor/delete/auth",
                url: baseUrl + "/sensor/delete/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {ids: obj.ids},
                method: 'POST',
                success: function (res) {
                    layer.close(loadIndex);
                    if (res.code === 200){
                    if (res.code === 200) {
                        layer.msg(res.msg, {icon: 1});
                        $(".layui-laypage-btn")[0].click();
                    } else if (res.code === 403){
                        top.location.href = baseUrl+"/";
                    }else {
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg, {icon: 2});
                    }
                }
@@ -337,10 +361,10 @@
    // 修改状态
    form.on('switch(statusSwitch)', function (obj) {
        var index  = obj.othis.parents('tr').attr("data-index");
        var index = obj.othis.parents('tr').attr("data-index");
        var data = tableData[index];
        data[this.name] = obj.elem.checked?1:0;
        http.post(baseUrl+"/sensor/edit/auth", {id: data.id, status: data[this.name]}, function (res) {
        data[this.name] = obj.elem.checked ? 1 : 0;
        http.post(baseUrl + "/sensor/edit/auth", {id: data.id, status: data[this.name]}, function (res) {
            layer.msg(res.msg, {icon: 1});
        })
    })
@@ -351,7 +375,7 @@
function tableReload(child) {
    var searchData = {};
    $.each($('#search-box [name]').serializeArray(), function() {
    $.each($('#search-box [name]').serializeArray(), function () {
        searchData[this.name] = this.value;
    });
    (child ? parent.tableIns : tableIns).reload({
@@ -370,14 +394,14 @@
    $.ajax({
        url: baseUrl + "/out/pakout/orderDetlIds/auth",
        headers: {'token': localStorage.getItem('token')},
        data: { orderId : orderId },
        data: {orderId: orderId},
        method: 'POST',
        success: function (res) {
            layer.close(loadIndex);
            if (res.code === 200){
            if (res.code === 200) {
                pakoutPreview(res.data);
            } else if (res.code === 403){
                top.location.href = baseUrl+"/";
            } else if (res.code === 403) {
                top.location.href = baseUrl + "/";
            } else {
                layer.msg(res.msg, {icon: 2});
            }
src/main/webapp/static/js/wrkMast/wrkMast.js
@@ -21,15 +21,16 @@
        cols: [[
            {type: 'checkbox'}
            ,{field: 'wrkNo', align: 'center',title: '工作号',sort: true, width: 95}
            ,{field: 'wrkCode', align: 'center',title: '下发工作号',sort: true, width: 120}
            ,{field: 'ioTime$', align: 'center',title: '工作时间',sort: true, width: 170}
            ,{field: 'wrkSts$', align: 'center',title: '工作状态', width: 120}
            ,{field: 'ioType$', align: 'center',title: '入出库类型', width: 140}
            ,{field: 'ioPri', align: 'center',title: '优先级'}
            ,{field: 'taskType$', align: 'center',title: '任务类型'}
            ,{field: 'ioPri', align: 'center',title: '优先级', width: 95}
            ,{field: 'taskType$', align: 'center',title: '任务类型', width: 95}
            ,{field: 'barcode', align: 'center',title: '条码', width: 120}
            ,{field: 'crnNo$', align: 'center',title: '堆垛机'}
            ,{field: 'sourceStaNo$', align: 'center',title: '源站'}
            ,{field: 'staNo$', align: 'center',title: '目标站'}
            ,{field: 'crnNo$', align: 'center',title: '堆垛机', width: 95}
            ,{field: 'sourceStaNo$', align: 'center',title: '源站', width: 95}
            ,{field: 'staNo$', align: 'center',title: '目标站', width: 95}
            ,{field: 'sourceLocNo', align: 'center',title: '源库位', width: 120}
            ,{field: 'locNo', align: 'center',title: '目标库位', width: 120}
            ,{field: 'preHave', align: 'center',title: '先入品', hide: true}
src/main/webapp/views/locAroundBind/locAroundBind.html
@@ -68,7 +68,7 @@
                <div class="layui-form-item">
                    <label class="layui-form-label layui-form-required">机台: </label>
                    <div class="layui-input-block">
                        <input class="layui-input" name="devNo" placeholder="请输入台机号" lay-vertype="tips" lay-verify="required">
                        <input class="layui-input" name="devNo" placeholder="请输入机台号" lay-vertype="tips" lay-verify="required">
                    </div>
                </div>
                <div class="layui-form-item">
@@ -97,7 +97,7 @@
<div id="resetLocDiv" style="margin: 20px 0 10px 30px; display: none">
    <div class="layui-form layui-form-pane">
        <div class="layui-form-item">
            <label class="layui-form-label">台机号</label>
            <label class="layui-form-label">机台号</label>
            <div class="layui-input-inline">
                <input type="text" name="devNo" autocomplete="off" class="layui-input">
            </div>
src/main/webapp/views/orderPakout/out.html
@@ -107,9 +107,9 @@
                                </div>
                            </div>
                            <div class="layui-inline">
                                <label class="layui-form-label">台机号:</label>
                                <label class="layui-form-label">机台号:</label>
                                <div class="layui-input-inline">
                                    <input name="standby1" class="layui-input" placeholder="台机号"/>
                                    <input name="standby1" class="layui-input" placeholder="机台号"/>
                                </div>
                            </div>
                            <!--                            <div class="layui-inline">-->