自动化立体仓库 - WMS系统
pang.jiabao
2024-11-26 e6ec6cd0e0fab11bf79f052be352a66db2dd51d3
项目搭建完成
1个文件已删除
33个文件已修改
2个文件已添加
1014 ■■■■■ 已修改文件
license.lic 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LocDetlController.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MobileController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/NodeController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ReportQueryController.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/WorkController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocDetl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocMastMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/ManLocDetlMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MobileService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/WorkService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/ManLocDetlServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/NodeServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/SaasUtils.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/LocTypeDto.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/license.lic 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasDevpMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocMastMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ManLocDetlMapper.xml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/image/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/common.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/manLocDetl/manLocDetl.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/nodeLoc/nodeLoc.js 490 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/nodeLoc/nodeLocTree.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/login.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/nodeLoc/nodeLoc.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/report/locDetl.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/saasLog/saasLog.html 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
license.lic
Binary files differ
pom.xml
@@ -115,7 +115,7 @@
    </dependencies>
    <build>
        <finalName>wms</finalName>
        <finalName>jsjwms</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
src/main/java/com/zy/asrs/controller/LocDetlController.java
@@ -13,16 +13,16 @@
import com.core.common.DateUtils;
import com.core.common.R;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.ManLocDetl;
import com.zy.asrs.entity.Mat;
import com.zy.asrs.mapper.LocDetlMapper;
import com.zy.asrs.mapper.ManLocDetlMapper;
import com.zy.asrs.service.LocDetlService;
import com.zy.asrs.service.ManLocDetlService;
import com.zy.asrs.service.MatService;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
@@ -38,6 +38,9 @@
    private LocDetlMapper locDetlMapper;
    @Autowired
    private MatService matService;
    @Resource
    private ManLocDetlMapper manLocDetlMapper;
    @RequestMapping(value = "/locDetl/update")
    public R update1() {
@@ -98,6 +101,17 @@
                  @RequestParam(required = false)String orderByType,
                  @RequestParam(required = false)String condition,
                  @RequestParam Map<String, Object> param){
        String locNo = (String) param.get("loc_no");
        if (!Cools.isEmpty(locNo)) {
            // 判断是否是平库在库库存
            if (locNo.startsWith("09") || locNo.startsWith("10")) {
                List<LocDetl> locDetls = manLocDetlMapper.selectLocDetlByLocNo(locNo);
                Page<LocDetl> page = new Page<>();
                page.setRecords(locDetls);
                page.setTotal(locDetls.size());
                return R.ok(page);
            }
        }
//        String row = "";
        EntityWrapper<LocDetl> wrapper = new EntityWrapper<>();
//        if (param.get("row") != null) {
src/main/java/com/zy/asrs/controller/MobileController.java
@@ -2,7 +2,6 @@
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.BaseRes;
import com.core.common.Cools;
@@ -23,7 +22,6 @@
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.List;
/**
 * 移动端接口控制器
@@ -63,14 +61,15 @@
    @RequestMapping("/mat/onSale/auth")
    @ManagerAuth
    public R matOnSale(@RequestBody CombParam combParam){
        mobileService.onSale(combParam);
        mobileService.onSale(combParam, getUserId());
        return R.ok("上架成功");
    }
    // 商品下架
    @RequestMapping("/mat/offSale/auth")
    //@ManagerAuth
    public R matOffSale(@RequestBody OffSaleParam offSaleParam){
        mobileService.offSale(offSaleParam);
        mobileService.offSale(offSaleParam, getUserId());
        return R.ok("下架成功");
    }
src/main/java/com/zy/asrs/controller/NodeController.java
@@ -13,7 +13,6 @@
import com.core.common.DateUtils;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.entity.ManLocDetl;
import com.zy.asrs.entity.Node;
import com.zy.asrs.entity.param.InitPakoutParam;
import com.zy.asrs.entity.param.PakinParam;
@@ -34,8 +33,6 @@
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import static jdk.nashorn.api.scripting.ScriptUtils.convert;
@RestController
public class NodeController extends BaseController {
@@ -65,7 +62,11 @@
        convert(param, wrapper);
        hostEq(wrapper);
        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
        return R.ok(nodeService.selectPage(new Page<>(curr, limit), wrapper));
        Page<Node> nodePage = nodeService.selectPage(new Page<>(curr, limit), wrapper);
        if (nodePage.getRecords().isEmpty()) {
            nodePage = nodeService.selectPage(new Page<>(curr, limit), new EntityWrapper<Node>().eq("id",param.get("parent_id")));
        }
        return R.ok(nodePage);
    }
    @RequestMapping(value = "/node/list/tree/auth")
src/main/java/com/zy/asrs/controller/ReportQueryController.java
@@ -6,6 +6,7 @@
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.*;
import com.zy.asrs.mapper.ManLocDetlMapper;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.asrs.service.LocDetlService;
import com.zy.common.web.BaseController;
@@ -15,6 +16,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -33,6 +35,9 @@
    private LocDetlService locDetlService;
    @Autowired
    private ReportQueryMapper reportQueryMapper;
    @Resource
    private ManLocDetlMapper manLocDetlMapper;
    //------------------库位使用统计--------------------------------------
    @RequestMapping("/viewStockUseList.action")
@@ -91,11 +96,80 @@
    //-----------------库存MAP图--------------------------------------
    @RequestMapping("/viewLocMapList/rows.action")
    public R queryViewLocMapRows(){
        return R.ok().add(reportQueryMapper.getViewLocRowTotal());
        List<Integer> viewLocRowTotal = reportQueryMapper.getViewLocRowTotal();
        viewLocRowTotal.add(9);
        viewLocRowTotal.add(10);
        return R.ok().add(viewLocRowTotal);
    }
    @RequestMapping("/viewLocMapList.action")
    public R queryViewLocMapListByPages(@RequestParam(defaultValue = "1")Integer row){
    public R queryViewLocMapListByPages(@RequestParam(defaultValue = "1")Integer row) {
        if (row == 9) {
            // 获取排级数据
            // 表格标题:列 ===>> 升序
//            List<String> bays = new ArrayList<>();
            String[] bays = new String[33];
            for (int i = 1; i <= 32; i ++) {
                bays[i] = String.valueOf(i);
            }
            // !表格第一列放层级数
            bays[0] = "";
            // 表格行:层 ====>> 倒序
            List<String> levs = new ArrayList<>();
            for (int i = 5; i>= 1; i --) {
                levs.add(String.valueOf(i));
            }
            List<Map<String, Object>> body = new ArrayList<>();
            for (String lev : levs){
                // 获取层级数据
//                List<ViewLocMapDto> dtos = reportQueryMapper.getViewLocBays(row, Integer.parseInt(lev));
                List<ViewLocMapDto> dtos = manLocDetlMapper.getViewLocBays(String.valueOf(row), lev);
                // !表格第一列放层级数
                dtos.add(0, new ViewLocMapDto(null ,null, lev));
                Map<String, Object> map = new HashMap<>();
                map.put("loc", dtos);
                body.add(map);
            }
            Map<String, Object> result = new HashMap<>();
            result.put("title", bays);
            result.put("body", body);
            return R.ok(result);
        } else if( row == 10) {
            // 获取排级数据
            // 表格标题:列 ===>> 升序
//            List<String> bays = new ArrayList<>();
            String[] bays = new String[33];
            for (int i = 1; i <= 32; i ++) {
                bays[i] = String.valueOf(i);
            }
            // !表格第一列放层级数
            bays[0] = "";
            // 表格行:层 ====>> 倒序
            List<String> levs = new ArrayList<>();
            for (int i = 5; i>= 1; i --) {
                levs.add(String.valueOf(i));
            }
            List<Map<String, Object>> body = new ArrayList<>();
            for (String lev : levs){
                // 获取层级数据
//                List<ViewLocMapDto> dtos = reportQueryMapper.getViewLocBays(row, Integer.parseInt(lev));
                List<ViewLocMapDto> dtos = manLocDetlMapper.getViewLocBays(String.valueOf(row), lev);
                // !表格第一列放层级数
                dtos.add(0, new ViewLocMapDto(null ,null, lev));
                for (int i = 15;i <= 18; i ++) {
                    dtos.add(i,new ViewLocMapDto(null ,i, "X"));
                }
                Map<String, Object> map = new HashMap<>();
                map.put("loc", dtos);
                body.add(map);
            }
            Map<String, Object> result = new HashMap<>();
            result.put("title", bays);
            result.put("body", body);
            return R.ok(result);
        } else {
        // 获取排级数据
        // 表格标题:列 ===>> 升序
        List<String> bays = reportQueryMapper.getViewLocBayCount(row);
@@ -118,6 +192,7 @@
        result.put("body", body);
        return R.ok(result);
    }
    }
    //------------------站点日入出库次数统计--------------------------------------
src/main/java/com/zy/asrs/controller/WorkController.java
@@ -3,14 +3,12 @@
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.WaitPakin;
import com.zy.asrs.entity.param.EmptyPlateOutParam;
import com.zy.asrs.entity.param.FullStoreParam;
import com.zy.asrs.entity.param.LocDetlAdjustParam;
import com.zy.asrs.entity.param.StockOutParam;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.WorkService;
import com.zy.common.model.StartupDto;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
@@ -163,12 +161,12 @@
        return R.ok();
    }
    @RequestMapping("/create/waitPain/wrkMast/start")
    @ManagerAuth(memo = "生成任务")
    public R createWaitPainWrkMastStart(@RequestBody List<WaitPakin> list) {
        StartupDto startupDto = workService.createWaitPainWrkMastStart(list, getUserId());
        return R.ok("任务号:" + startupDto.getWorkNo() + ";目标库位:" + startupDto.getLocNo());
    }
//    @RequestMapping("/create/waitPain/wrkMast/start")
//    @ManagerAuth(memo = "生成任务")
//    public R createWaitPainWrkMastStart(@RequestBody List<WaitPakin> list) {
//        StartupDto startupDto = workService.createWaitPainWrkMastStart(list, getUserId());
//        return R.ok("任务号:" + startupDto.getWorkNo() + ";目标库位:" + startupDto.getLocNo());
//    }
    @RequestMapping("/deal/preHave/start")
    @ManagerAuth(memo = "先入品处理")
src/main/java/com/zy/asrs/entity/LocDetl.java
@@ -251,7 +251,7 @@
    public long getStoreDate(){
        long timeNow = new Date().getTime();
        long timeCreate = this.appeTime.getTime();
        long timeCreate = new Date().getTime();
        return (timeNow - timeCreate) /24/60/60/1000;
    }
src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -53,4 +53,13 @@
//    LocMast selectLocByLocStsPakInO2(@Param("locNos") List<String> locNos,@Param("whsType") Long whsType);
    LocMast selectLocByLocStsPakInO2(@Param("crnNo") Integer crnNo,@Param("bay") Integer bay,@Param("lev") Integer lev,@Param("gro") Integer gro,@Param("whsType") Long whsType);
    /**
     *
     * 根据库位类型来搜索空库位(站点的不同限制堆垛机)
     * @param locType1 0123
     * @param crnNo 堆垛机号
     * @return 库位集合
     */
    List<LocMast> selectLocByTypeToList(@Param("locType1") int locType1,@Param("crnNo") int crnNo);
}
src/main/java/com/zy/asrs/mapper/ManLocDetlMapper.java
@@ -1,7 +1,9 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.ManLocDetl;
import com.zy.asrs.entity.ViewLocMapDto;
import com.zy.asrs.entity.result.StockVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -83,4 +85,12 @@
    List<ManLocDetl> selectAllPage(Map<String, Object> condition);
    long selectAllPageSize(Map<String, Object> condition);
    List<ViewLocMapDto> getViewLocBays(@Param("row") String row, @Param("lev") String lev);
    /**
     * 按库位号查询平库库存
     * @param locNo 库位号
     */
    List<LocDetl> selectLocDetlByLocNo(@Param("locNo") String locNo);
}
src/main/java/com/zy/asrs/service/MobileService.java
@@ -20,12 +20,12 @@
    /**
     * 上架
     */
    void onSale(CombParam param);
    void onSale(CombParam param,Long userId);
    /**
     * 下架
     */
    void offSale(OffSaleParam param);
    void offSale(OffSaleParam param, Long userId);
    /**
     * 盘点
src/main/java/com/zy/asrs/service/WorkService.java
@@ -1,14 +1,12 @@
package com.zy.asrs.service;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.WaitPakin;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.entity.param.EmptyPlateOutParam;
import com.zy.asrs.entity.param.FullStoreParam;
import com.zy.asrs.entity.param.LocDetlAdjustParam;
import com.zy.asrs.entity.param.StockOutParam;
import com.zy.common.model.LocDetlDto;
import com.zy.common.model.StartupDto;
import com.zy.common.model.TaskDto;
import com.zy.common.model.enums.IoWorkType;
@@ -88,7 +86,7 @@
    /**
     * 通知档手动生成任务
     */
    StartupDto createWaitPainWrkMastStart(List<WaitPakin> list, Long userId);
//    StartupDto createWaitPainWrkMastStart(List<WaitPakin> list, Long userId);
    /**
     * 通知档手动生成任务
src/main/java/com/zy/asrs/service/impl/ManLocDetlServiceImpl.java
@@ -172,7 +172,7 @@
            manLocDetl.setUnit(mat.getUnit());
            manLocDetl.setBarcode(mat.getBarcode());
            manLocDetl.setPrice(mat.getPrice());
            SaasUtils.insertLog(3,manLocDetl.getLocNo(), manLocDetl.getMatnr(),manLocDetl.getAnfme());
            SaasUtils.insertLog(3,manLocDetl.getLocNo(), manLocDetl.getMatnr(),manLocDetl.getAnfme(),userId);
            this.baseMapper.insert(manLocDetl);
        }
    }
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -14,7 +14,7 @@
import com.zy.asrs.mapper.ManLocDetlMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.MatUtils;
import com.zy.common.CodeRes;
import com.zy.asrs.utils.SaasUtils;
import com.zy.common.constant.MesConstant;
import com.zy.common.entity.Parameter;
import com.zy.common.model.DetlDto;
@@ -204,13 +204,19 @@
    // 商品上架
    @Override
    public void onSale(CombParam param) {
    public void onSale(CombParam param, Long userId) {
        Date now = new Date();
        // 获取库位号
        String locno = param.getLocno();
        Node node = nodeService.selectByUuid(locno);
        if (Cools.isEmpty(node)) {
            throw new CoolException(param.getLocno() + ":库位不存在");
        }
        String barcode = param.getBarcode();
        if (Cools.isEmpty(barcode)) {
            throw new CoolException("条码不能为空!");
        }
        // 获取商品列表
@@ -222,26 +228,38 @@
            if (Cools.isEmpty(combMat.getAnfme()) || combMat.getAnfme()==0){
                throw new CoolException(combMat.getMatnr() + ":商品数量有误!");
            }
            if (Cools.isEmpty(combMat.getBatch())){
//                throw new CoolException(combMat.getMatnr() + ":商品批号有误!");
            }
            ManLocDetl manLocDetl = new ManLocDetl();
            manLocDetl.setLocNo(locno);
//            manLocDetl.setBarcode(barcode);
            manLocDetl.setZpallet(barcode);
            manLocDetl.setNodeId(node.getId());
            manLocDetl.setMaktx(mat.getMaktx());
            manLocDetl.setMatnr(mat.getMatnr());
            manLocDetl.setSpecs(mat.getSpecs());
            manLocDetl.setBatch(Cools.isEmpty(combMat.getBatch()) ? "" : combMat.getBatch());
            manLocDetl.setAnfme(combMat.getAnfme());
            manLocDetl.setCreateBy(userId);
            manLocDetl.setCreateTime(now);
            manLocDetl.setUpdateBy(userId);
            manLocDetl.setModiTime(now);
            if (!manLocDetlService.insert(manLocDetl)) {
                throw new CoolException("商品上架失败!");
            }
            // 更新库位条码
            node.setBarcode(barcode);
            node.setUpdateBy(userId);
            node.setUpdateTime(now);
            nodeService.updateById(node);
            SaasUtils.insertLog(0,manLocDetl.getLocNo(), manLocDetl.getMatnr(),combMat.getAnfme(),userId);
        }
    }
    // 商品下架
    @Override
    public void offSale(OffSaleParam offSaleParam) {
    public void offSale(OffSaleParam offSaleParam, Long userId) {
        ManLocDetl manLocDetl = manLocDetlMapper.selectLocNo0(offSaleParam.getLocNo(), offSaleParam.getMatnr());
        if (Cools.isEmpty(manLocDetl)){
            throw new CoolException("无此商品!");
@@ -250,7 +268,13 @@
        if (anfme < 0) {
            throw new CoolException("商品库存不足!");
        } else if (anfme == 0){
            SaasUtils.insertLog(1,manLocDetl.getLocNo(), manLocDetl.getMatnr(),offSaleParam.getAnfme(),userId);
            manLocDetlMapper.deleteLocNo0(offSaleParam.getLocNo(), offSaleParam.getMatnr());
            // 清空库位条码
            Node node = nodeService.selectByUuid(offSaleParam.getLocNo());
            node.setUpdateTime(new Date());
            node.setUpdateBy(userId);
            node.setBarcode("");
        }
        manLocDetlMapper.updateAnfme0(anfme,manLocDetl.getNodeId());
    }
src/main/java/com/zy/asrs/service/impl/NodeServiceImpl.java
@@ -12,18 +12,15 @@
import com.zy.asrs.entity.param.InitPakoutParam;
import com.zy.asrs.entity.param.MatnrDto;
import com.zy.asrs.entity.param.PakinParam;
import com.zy.asrs.entity.result.Pakin;
import com.zy.asrs.mapper.NodeMapper;
import com.zy.asrs.service.ManLocDetlService;
import com.zy.asrs.service.MatService;
import com.zy.asrs.service.NodeService;
import com.zy.asrs.utils.SaasUtils;
import com.zy.asrs.utils.VersionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.beans.Transient;
import java.util.Date;
import java.util.List;
@@ -70,12 +67,12 @@
    @Override
    public Node selectByUuid(String uuid, Long hostId, Integer type) {
        return selectOne(new EntityWrapper<Node>().eq("host_id", hostId).eq("uuid", uuid).eq("type", type));
        return selectOne(new EntityWrapper<Node>().isNull("host_id").eq("uuid", uuid).eq("type", type));
    }
    @Override
    public Node selectByUuid(String uuid, Long hostId, Integer type, Long parentId) {
        return selectOne(new EntityWrapper<Node>().eq("host_id", hostId).eq("uuid", uuid).eq("type", type).eq("parent_id", parentId));
        return selectOne(new EntityWrapper<Node>().isNull("host_id").eq("uuid", uuid).eq("type", type).eq("parent_id", parentId));
    }
    @Override
@@ -115,7 +112,7 @@
                manLocDetl.setCreateTime(now);
                manLocDetl.setModiTime(now);
                manLocDetl.setCreateBy(userId);
                SaasUtils.insertLog(0,manLocDetl.getLocNo(),manLocDetl.getMatnr(), manLocDetl.getAnfme());
                SaasUtils.insertLog(0,manLocDetl.getLocNo(),manLocDetl.getMatnr(), manLocDetl.getAnfme(),userId);
                manLocDetlService.insert(manLocDetl);
            }else {
                check.setAnfme(dto.getCount() + check.getAnfme());
@@ -149,17 +146,22 @@
                if (manLocDetl.getAnfme() - param.getCount() < 0) {
                    return R.error("物料:"+ param.getMatnr() + " 在库位中数量不足");
                } else if (manLocDetl.getAnfme() - param.getCount() == 0) {
                    SaasUtils.insertLog(1,manLocDetl.getLocNo(), manLocDetl.getMatnr(),param.getCount());
                    SaasUtils.insertLog(1,manLocDetl.getLocNo(), manLocDetl.getMatnr(),param.getCount(),userId);
                    manLocDetlService.delete(new EntityWrapper<ManLocDetl>()
                            .eq("loc_no",node.getUuid())
                            .eq("matnr",param.getMatnr()));
                    // 清空库位条码
                    node.setBarcode("");
                    node.setUpdateBy(userId);
                    node.setUpdateTime(now);
                    nodeService.updateById(node);
                } else {
                    manLocDetl.setAnfme(manLocDetl.getAnfme() - param.getCount());
                    manLocDetlService.update(manLocDetl,new EntityWrapper<ManLocDetl>()
                            .eq("loc_no",node.getUuid())
                            .eq("matnr",param.getMatnr()));
                    SaasUtils.insertLog(1,manLocDetl.getLocNo(), manLocDetl.getMatnr(),param.getCount());
                    SaasUtils.insertLog(1,manLocDetl.getLocNo(), manLocDetl.getMatnr(),param.getCount(),userId);
                }
            }
        }
@@ -187,7 +189,7 @@
                source.setLocNo(targetNode.getUuid());
                source.setNodeId(targetNode.getId());
                SaasUtils.insertLog(2,source.getLocNo(), source.getMatnr(), source.getAnfme());
                SaasUtils.insertLog(2,source.getLocNo(), source.getMatnr(), source.getAnfme(),userId);
                manLocDetlService.insert(source);
            }else {
                check.setAnfme(check.getAnfme() + source.getAnfme());
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -449,6 +449,9 @@
                    .eq("stn_no", param.getOutSite())
                    .eq("crn_no", locMast.getCrnNo());
            StaDesc staDesc = staDescService.selectOne(wrapper);
            if (staDesc == null) {
                throw new CoolException("路径不存在");
            }
            Integer sourceStaNo = staDesc.getCrnStn();
            if (Cools.isEmpty(sourceStaNo)) {
                throw new CoolException("检索源站失败");
@@ -1022,15 +1025,15 @@
        }
    }
    @Override
    public StartupDto createWaitPainWrkMastStart(List<WaitPakin> list, Long userId) {
        if (Cools.isEmpty(list)) {
            throw new CoolException("入库通知档不能为空");
        }
        LocTypeDto locTypeDto = new LocTypeDto();
        locTypeDto.setLocType1((short) 1);
        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list);
    }
//    @Override
//    public StartupDto createWaitPainWrkMastStart(List<WaitPakin> list, Long userId) {
//        if (Cools.isEmpty(list)) {
//            throw new CoolException("入库通知档不能为空");
//        }
//        LocTypeDto locTypeDto = new LocTypeDto();
//        locTypeDto.setLocType1((short) 1);
//        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list);
//    }
    @Override
    @Transactional
src/main/java/com/zy/asrs/utils/SaasUtils.java
@@ -1,14 +1,13 @@
package com.zy.asrs.utils;
import com.core.common.SpringUtils;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.zy.system.entity.SaasLog;
import com.zy.system.service.SaasLogService;
import java.util.Date;
public class SaasUtils {
    public static void insertLog(Integer type, String locNo, String matnr,Double anfme){
    public static void insertLog(Integer type, String locNo, String matnr,Double anfme, Long userId){
        SaasLogService bean = SpringUtils.getBean(SaasLogService.class);
        SaasLog saasLog = new SaasLog();
        saasLog.setType(type);
@@ -16,7 +15,7 @@
        saasLog.setMatnr(matnr);
        saasLog.setIoTime(new Date());
        saasLog.setAnfme(anfme);
        saasLog.setCreateBy(1L);
        saasLog.setCreateBy(userId);
        bean.insert(saasLog);
    }
}
src/main/java/com/zy/common/model/LocTypeDto.java
@@ -1,6 +1,5 @@
package com.zy.common.model;
import com.alibaba.fastjson.JSON;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasDevp;
import lombok.Data;
@@ -26,15 +25,16 @@
    }
    public LocTypeDto(BasDevp basDevp) {
        if (basDevp.getLocType1() == null || basDevp.getLocType1() == 0) {
        this.locType1 = basDevp.getLocType1();
        if (basDevp.getLocType1() == null) {
            throw new CoolException("plc高低检测异常");
        }
        if (basDevp.getLocType1() == 1) {
            this.locType1 = 1; // 低库位
        } else {
            this.locType1 = 2; // 高库位
        }
        log.info(JSON.toJSONString(this));
//        if (basDevp.getLocType1() == 1) {
//            this.locType1 = 1; // 低库位
//        } else {
//            this.locType1 = 2; // 高库位
//        }
//        log.info(JSON.toJSONString(this));
    }
}
src/main/java/com/zy/common/service/CommonService.java
@@ -3,16 +3,14 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.core.common.Arith;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.result.KeyValueVo;
import com.zy.asrs.mapper.LocMastMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
import com.zy.asrs.utils.VersionUtils;
import com.zy.common.model.LocTypeDto;
import com.zy.common.model.Shelves;
import com.zy.common.model.StartupDto;
import com.zy.common.properties.SlaveProperties;
import lombok.extern.slf4j.Slf4j;
@@ -20,11 +18,9 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
/**
 * 货架核心功能
@@ -56,6 +52,9 @@
    private SlaveProperties slaveProperties;
    @Autowired
    private WrkDetlService wrkDetlService;
    @Resource
    private LocMastMapper locMastMapper;
    /**
     * 生成工作号
@@ -150,7 +149,72 @@
        }catch (Exception e){
            log.error("站点={} 未查询到对应的规则",sourceStaNo);
        }
        return null;
        throw new CoolException("获取库位异常");
    }
    /**
     * 获取库位,杰上杰用
     * @param ioType 1全板入库,10空托盘组入库
     * @param sourceSite 源站点
     * @param locType 库位检测信息 0空托1列,1一层,2.2-4层,3.5-9层
     * @return 目标库位信息
     */
    @Transactional
    public StartupDto getLocNoRunNew(Integer ioType, Integer sourceSite, Integer locType) {
        // 根据入库类型和源站点获取工作路径
        StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("type_no", ioType).eq("crn_stn", sourceSite));
        if (staDesc == null) {
            throw new CoolException("获取工作路径异常:" + ioType + " , " + sourceSite);
        }
        // 寻找到的库位
        LocMast locMast = null;
        // 按库位类型获取库位
        List<LocMast> locMasts = locMastMapper.selectLocByTypeToList(locType, staDesc.getCrnNo());
        // todo 如果当前类型库位剩余不多,是一直放满,还是兼容到下一种库位类型
        // 考虑移库需要同类型库位,这里限制不能放满,兼容下一种库位类型
        if (locMasts.size() <= 4) {
            switch (locType) {
                case 0:
                case 2:
                    return getLocNoRunNew(ioType, sourceSite, 3);
                case 1:
                case 3:
                    throw new CoolException("当前库位剩余四个用于移库,无法占用:" + locType);
                default:
            }
        }
        // 先取深库位
        Optional<LocMast> first = locMasts.stream().filter(o -> o.getRow1() == 1 || o.getRow1() == 4 || o.getRow1() == 5 || o.getRow1() == 8).findFirst();
        if (first.isPresent()) {
               locMast = first.get();
        } else {
            // 深库位里面没有从浅库位里面取
            Optional<LocMast> first2 = locMasts.stream().filter(o -> o.getRow1() == 2 || o.getRow1() == 3 || o.getRow1() == 5 || o.getRow1() == 7).findFirst();
            if(first2.isPresent()) {
                locMast = first2.get();
            }
        }
        if (locMast == null) {
            throw new CoolException("没有找到合适空库位");
        }
        // 生成工作号
        int workNo = getWorkNo(0);
        // 返回dto
        StartupDto startupDto = new StartupDto();
        startupDto.setWorkNo(workNo);
        startupDto.setCrnNo(staDesc.getCrnNo());
        startupDto.setSourceStaNo(staDesc.getStnNo());
        startupDto.setStaNo(sourceSite);
        startupDto.setLocNo(locMast.getLocNo());
        return startupDto;
    }
    /**
src/main/java/com/zy/common/web/WcsController.java
@@ -21,7 +21,6 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * Created by vincent on 2020/10/30
@@ -92,10 +91,10 @@
        switch (param.getIoType()) {
            case 1://满托盘入库
                assert waitPakins != null;
                dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakins);
                dto = startupFullPutStore(sourceStaNo, param.getBarcode(), locTypeDto, waitPakins);
                break;
            case 10://空托盘入库
                dto = emptyPlateIn(param.getSourceStaNo(), locTypeDto, param.getBarcode());
                dto = emptyPlateIn(sourceStaNo, locTypeDto, param.getBarcode());
                break;
            default:
                break;
@@ -156,13 +155,14 @@
     * 全板入库
     */
    @Transactional
    public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<WaitPakin> waitPakins) {
    public StartupDto startupFullPutStore(BasDevp sourceStaNo, String barcode, LocTypeDto locTypeDto, List<WaitPakin> waitPakins) {
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
//        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
        // 检索库位
        List<String> matnrs = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList());
        List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList());
        StartupDto dto = commonService.getLocNo( 1, devpNo, matnrs.get(0),batchs.get(0),null, locTypeDto);
//        List<String> matnrs = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList());
//        List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList());
//        StartupDto dto = commonService.getLocNo( 1, devpNo, matnrs.get(0),batchs.get(0),null, locTypeDto);
        StartupDto dto = commonService.getLocNoRunNew(1, sourceStaNo.getDevNo(), Integer.valueOf(locTypeDto.getLocType1()));
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
@@ -233,11 +233,12 @@
    }
    @Transactional
    public StartupDto emptyPlateIn(Integer devpNo, LocTypeDto locTypeDto, String barcode) {
    public StartupDto emptyPlateIn(BasDevp sourceStaNo, LocTypeDto locTypeDto, String barcode) {
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
//        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
        // 检索库位
        StartupDto dto = commonService.getLocNo( 10, devpNo, null,null,null, locTypeDto);
//        StartupDto dto = commonService.getLocNo( 10, devpNo, null,null,null, locTypeDto);
        StartupDto dto = commonService.getLocNoRunNew(10, sourceStaNo.getDevNo(), Integer.valueOf(locTypeDto.getLocType1()));
        int workNo = dto.getWorkNo();
        // 生成工作档
        WrkMast wrkMast = new WrkMast();
src/main/resources/application.yml
@@ -10,7 +10,7 @@
    enabled: false
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=phJsJasrs
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=jsjasrs
    username: sa
    password: sa@123
  mvc:
@@ -39,7 +39,7 @@
#License相关配置
license:
  subject: phJsJasrs
  subject: jsjasrs
  publicAlias: publicCert
  storePass: public_zhongyang_123456789
  licensePath: license.lic
@@ -50,13 +50,13 @@
  # 双深
  doubleDeep: true
  # 双深库位排号
  doubleLocs: 1,4,5,8,9,12,13,16
  doubleLocs: 1,4,5,8
  # 一个堆垛机负责的货架排数
  groupCount: 4
  # 左深库位排号
  doubleLocsLeft: 1,5,9,13
  doubleLocsLeft: 1,4
  # 右深库位排号
  doubleLocsRight: 4,8,12,16
  doubleLocsRight: 5,8
# wms参数配置
wms-parameter:
  # 自动补空板功能开关
src/main/resources/license.lic
Binary files differ
src/main/resources/mapper/BasDevpMapper.xml
@@ -48,7 +48,7 @@
        select
        abd.dev_no
        from asr_bas_devp abd
        left join asr_sta_desc asd on abd.dev_no = asd.stn_no
        left join asr_sta_desc asd on abd.dev_no = asd.crn_stn
        where 1=1
        and asd.type_no = #{typeNo}
        -- and abd.in_enable = 'Y'
src/main/resources/mapper/LocMastMapper.xml
@@ -192,5 +192,8 @@
        and gro1 = #{gro}
        AND loc_sts in ('O') order by row1
    </select>
    <select id="selectLocByTypeToList" resultType="com.zy.asrs.entity.LocMast">
        select loc_no locNo,loc_type1 locType1,crn_no crnNo,row1 from asr_loc_mast where loc_sts = 'O' and loc_type1 = #{locType1} AND crn_no = #{crnNo} order by lev1,bay1,row1
    </select>
</mapper>
src/main/resources/mapper/ManLocDetlMapper.xml
@@ -28,7 +28,7 @@
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="modiTime" />
        <result column="modi_time" property="modiTime" />
        <result column="memo" property="memo" />
    </resultMap>
@@ -295,6 +295,37 @@
        WHERE 1=1
        <include refid="locDetlCondition2"></include>
    </select>
    <select id="getViewLocBays" resultType="com.zy.asrs.entity.ViewLocMapDto">
        select
            uuid as locNo,
            SUBSTRING(uuid, 4, 2) as bay1,
            CASE
                WHEN barcode = '' THEN 'O'
                ELSE 'F'
                END AS locSts
        from
            man_node
        where
            level = 3
          and parent_name = #{row} + '排'
          and SUBSTRING(uuid, 7, 1) = #{lev}
    </select>
    <select id="selectLocDetlByLocNo" resultType="com.zy.asrs.entity.LocDetl">
        select
            loc_no as locNo,
            matnr,
            maktx,
            doc_num as orderNo,
            specs,
            zpallet,
            batch,
            anfme,
            unit
        from
            man_loc_detl
        where
            loc_no = #{locNo}
    </select>
    <update id="updateLocNo0">
src/main/resources/mapper/WrkMastMapper.xml
@@ -70,7 +70,7 @@
        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,15,crn_end_time) &lt;= getdate() 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))
        order by io_time,wrk_no asc
    </select>
src/main/webapp/static/image/logo.png

src/main/webapp/static/js/common.js
@@ -1,4 +1,4 @@
var baseUrl = "/wms";
var baseUrl = "/jsjwms";
// 详情窗口-高度
var detailHeight = '80%';
src/main/webapp/static/js/manLocDetl/manLocDetl.js
@@ -4,11 +4,11 @@
        {field: 'locNo', align: 'center',title: '库位号'},
        {field: 'matnr', align: 'center',title: '商品编号', sort:true}
        ,{field: 'maktx', align: 'center',title: '商品名称', sort:true}
        ,{field: 'anfme', align: 'center',title: '数量'}
        ,{field: 'orderNo', align: 'center',title: '单据编号', hide: false}
        ,{field: 'batch', align: 'center',title: '批号', width: 300, sort:true}
        ,{field: 'anfme', align: 'center',title: '数量'}
        //,{field: 'zpallet', align: 'center',title: '托盘条码'}
        ,{field: 'specs', align: 'center',title: '配置'}
        ,{field: 'specs', align: 'center',title: '规格'}
        ,{field: 'model', align: 'center',title: '代码', hide: true}
        ,{field: 'color', align: 'center',title: '颜色', hide: true}
        ,{field: 'brand', align: 'center',title: '品牌', hide: true}
@@ -38,8 +38,8 @@
    ];
    // cols.push.apply(cols, detlCols);
    cols.push({field: 'modiUser$', align: 'center',title: '修改人员',hide: true}
        ,{field: 'modiTime$', align: 'center',title: '修改时间'}
    cols.push({field: 'createBy$', align: 'center',title: '创建人',hide: true}
        ,{field: 'createTime$', align: 'center',title: '创建时间'}
    )
    return cols;
}
src/main/webapp/static/js/nodeLoc/nodeLoc.js
New file
@@ -0,0 +1,490 @@
var pageCurr;
var printMatCodeNos = [];
var admin;
function getCol() {
    var cols = [
        {type: 'checkbox'}
        ,{field: 'tagId$', align: 'center',title: '归类', templet: '#tagTpl'}
    ];
    cols.push.apply(cols, matCols);
    cols.push(
        {fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:150}
    )
    return cols;
}
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).extend({
    dropdown: 'dropdown/dropdown',
}).use(['table','laydate', 'form', 'treeTable', 'admin', 'xmSelect', 'dropdown', 'element'], function(){
    var table = layui.table;
    var $ = layui.jquery;
    var layer = layui.layer;
    var layDate = layui.laydate;
    var form = layui.form;
    admin = layui.admin;
    var treeTable = layui.treeTable;
    var xmSelect = layui.xmSelect;
    // 商品分类数据
    var insTb = treeTable.render({
        elem: '#tag',
        url: baseUrl+'/node/list/auth',
        headers: {token: localStorage.getItem('token')},
        tree: {
            iconIndex: 2,           // 折叠图标显示在第几列
            isPidData: true,        // 是否是id、pid形式数据
            idName: 'id',           // id字段名称
            pidName: 'parentId'     // pid字段名称
        },
        cols: [],
        done: function (data) {
            $('.ew-tree-table-box').css('height', '100%');
            insTb.expandAll();
        }
    });
    // 数据渲染
    tableIns = table.render({
        elem: '#mat',
        headers: {token: localStorage.getItem('token')},
        url: baseUrl+'/node/list/auth',
        page: true,
        limit: 16,
        limits: [16, 30, 50, 100, 200, 500],
        toolbar: '#toolbar',
        cellMinWidth: 50,
        height: 'full-105',
        cols: [[
            {type: 'checkbox'},
            {field: 'name', align: 'center',title: '库位名', hide: false},
            {field: 'parentName', align: 'center',title: '库区', hide: false},
            {field: 'barcode', align: 'center',title: '托盘条码', hide: false},
            {field: 'updateTime$', align: 'center',title: '更新时间', hide: false},
            // {field: 'createBy$', align: 'center',title: '创建人', hide: false},
            // {field: 'createTime$', align: 'center',title: '创建时间', hide: false},
            {field: 'type$', align: 'center',title: '类型', templet: '#tagTpl', hide: false}
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            }
        },
        response: {
            statusCode: 200
        },
        done: function(res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
            }
            pageCurr=curr;
            limit();
            form.on('checkbox(tableCheckbox)', function (data) {
                var _index = $(data.elem).attr('table-index')||0;
                if(data.elem.checked){
                    res.data[_index][data.value] = 'Y';
                }else{
                    res.data[_index][data.value] = 'N';
                }
            });
        }
    });
    // 监听排序事件
    table.on('sort(locMast)', function (obj) {
        var searchData = {};
        $.each($('#search-box [name]').serializeArray(), function() {
            searchData[this.name] = this.value;
        });
        searchData['orderByField'] = obj.field;
        searchData['orderByType'] = obj.type;
        tableIns.reload({
            where: searchData,
            page: {
                curr: 1
            },
            done: function (res, curr, count) {
                if (res.code === 403) {
                    top.location.href = baseUrl+"/";
                }
                pageCurr=curr;
                limit();
            }
        });
    });
    // 监听头工具栏事件
    table.on('toolbar(mat)', function (obj) {
        var checkStatus = table.checkStatus(obj.config.id);
        switch(obj.event) {
            case 'addData':
                showEditModel()
                break;
            case 'deleteData':
                var data = checkStatus.data;
                if (data.length === 0){
                    layer.msg('请选择数据');
                } else {
                    layer.confirm('确定删除'+(data.length===1?'此':data.length)+'条数据吗', function(){
                        $.ajax({
                            url: baseUrl+"/node/delete/auth",
                            headers: {'token': localStorage.getItem('token')},
                            data: {param: JSON.stringify(data)},
                            method: 'POST',
                            traditional:true,
                            success: function (res) {
                                if (res.code === 200){
                                    layer.closeAll();
                                    tableReload(false);
                                } else if (res.code === 403){
                                    top.location.href = baseUrl+"/";
                                } else {
                                    layer.msg(res.msg)
                                }
                            }
                        })
                    });
                }
                break;
            case 'exportData':
                layer.confirm('确定导出Excel吗', {shadeClose: true}, function(){
                    var titles=[];
                    var fields=[];
                    obj.config.cols[0].map(function (col) {
                        if (col.type === 'normal' && col.hide === false && col.toolbar == null) {
                            titles.push(col.title);
                            fields.push(col.field);
                        }
                    });
                    var exportData = {};
                    $.each($('#search-box [name]').serializeArray(), function() {
                        exportData[this.name] = this.value;
                    });
                    var param = {
                        'mat': exportData,
                        'fields': fields
                    };
                    $.ajax({
                        url: baseUrl+"/node/export/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: JSON.stringify(param),
                        dataType:'json',
                        contentType:'application/json;charset=UTF-8',
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll();
                            if (res.code === 200) {
                                table.exportFile(titles,res.data,'xls');
                            } else if (res.code === 403) {
                                top.location.href = baseUrl+"/";
                            } else {
                                layer.msg(res.msg)
                            }
                        }
                    });
                });
                break;
            // 批量打印
            case "btnPrintBatch":
                printMatCodeNos = [];
                var data = checkStatus.data;
                if (data.length === 0){
                    layer.msg('请选择打印数据');
                } else {
                    layer.open({
                        type: 1,
                        title: '批量打印 [数量'+ data.length +']',
                        area: ['500px'],
                        shadeClose: true,
                        content: $('#printDataDiv'),
                        success: function(layero, index){
                            for (var i = 0; i<data.length;i++) {
                                printMatCodeNos.push(data[i].matnr);
                            }
                        },
                        end: function () {
                        }
                    });
                }
                break;
        }
    });
    // 监听行工具事件
    table.on('tool(mat)', function(obj){
        var data = obj.data;
        switch (obj.event) {
            // 打印
            case "btnPrint":
                printMatCodeNos = [];
                layer.open({
                    type: 1,
                    title: data.matnr + ' [数量:1]',
                    area: ['500px'],
                    shadeClose: true,
                    content: $('#printDataDiv'),
                    success: function(layero, index){
                        layer.iframeAuto(index);
                        printMatCodeNos.push(data.matnr);
                    },
                    end: function () {
                    }
                });
                break;
            // 编辑
            case 'edit':
                showEditModel(data)
                break;
        }
    });
    /* 显示表单弹窗 */
    function showEditModel(mData) {
        admin.open({
            type: 1,
            area: '600px',
            title: (mData ? '修改' : '添加') + '商品',
            content: $('#editDialog').html(),
            success: function (layero, dIndex) {
                // 回显表单数据
                form.val('detail', mData);
                // 新增自动生成商品编号
                if (!mData) {
                    http.get(baseUrl + "/node/auto/matnr/auth", null, function (res) {
                        $('#matnr').val(res.data);
                    })
                }
                // 表单提交事件
                form.on('submit(editSubmit)', function (data) {
                    console.log(data)
                    data.field.tagId = insXmSel.getValue('valueStr');
                    if (isEmpty(data.field.tagId)) {
                        layer.msg('分类不能为空', {icon: 2});
                        return false;
                    }
                    var loadIndex = layer.load(2);
                    $.ajax({
                        url: baseUrl+"/node/"+(mData?'update':'add')+"/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: data.field,
                        method: 'POST',
                        success: function (res) {
                            layer.close(loadIndex);
                            if (res.code === 200){
                                layer.close(dIndex);
                                layer.msg(res.msg, {icon: 1});
                                $(".layui-laypage-btn")[0].click();
                            } else if (res.code === 403){
                                top.location.href = baseUrl+"/";
                            }else {
                                layer.msg(res.msg, {icon: 2});
                            }
                        }
                    })
                    return false;
                });
                // 渲染下拉树
                var insXmSel = xmSelect.render({
                    el: '#tagSel',
                    height: '250px',
                    data: insTb.options.data,
                    initValue: mData ? [mData.tagId] : [],
                    model: {label: {type: 'text'}},
                    prop: {
                        name: 'name',
                        value: 'id'
                    },
                    radio: true,
                    clickClose: true,
                    tree: {
                        show: true,
                        indent: 15,
                        strict: false,
                        expandedKeys: true
                    }
                });
                // 弹窗不出现滚动条
                $(layero).children('.layui-layer-content').css('overflow', 'visible');
                layui.form.render('select');
            }
        });
    }
    // 模板选择
    form.on('radio(selectTemplateRadio)', function (data) {
        $('.template-preview').hide();
        $('#template-preview-'+data.value).show();
    });
    // 开始打印
    form.on('submit(doPrint)', function (data) {
        var templateNo = data.field.selectTemplate;
        $.ajax({
            url: baseUrl+"/node/print/auth",
            headers: {'token': localStorage.getItem('token')},
            data: {param: printMatCodeNos},
            method: 'POST',
            async: false,
            success: function (res) {
                if (res.code === 200){
                    layer.closeAll();
                    for (let i=0;i<res.data.length;i++){
                        var templateDom = $("#templatePreview"+templateNo);
                        var className = templateDom.attr("class");
                        if (className === 'template-barcode') {
                            res.data[i]["barcodeUrl"]=baseUrl+"/mac/code/auth?type=1&param="+res.data[i].matnr;
                        } else {
                            res.data[i]["barcodeUrl"]=baseUrl+"/mac/code/auth?type=2&param="+res.data[i].matnr;
                        }
                    }
                    var tpl = templateDom.html();
                    var template = Handlebars.compile(tpl);
                    var html = template(res);
                    var box = $("#box");
                    box.html(html);box.show();
                    box.print({mediaPrint:true});
                    box.hide();
                } else if (res.code === 403){
                    top.location.href = baseUrl+"/";
                }else {
                    layer.msg(res.msg)
                }
            }
        })
    });
    // 搜索栏搜索事件
    form.on('submit(search)', function (data) {
        pageCurr = 1;
        tableReload(false);
    });
    // 搜索栏重置事件
    form.on('submit(reset)', function (data) {
        pageCurr = 1;
        clearFormVal($('#search-box'));
        tableReload(false);
    });
    // 时间选择器
    layDate.render({
        elem: '#createTime\\$',
        type: 'datetime'
    });
    layDate.render({
        elem: '#updateTime\\$',
        type: 'datetime'
    });
});
// excel导入模板下载
function excelMouldDownload(){
    layer.load(1, {shade: [0.1,'#fff']});
    location.href = baseUrl + "/node/excel/import/mould";
    layer.closeAll('loading');
}
// excel导入
function importExcel() {
    $("#importExcel").trigger("click");
}
function upload(obj){
    if(!obj.files) {
        return;
    }
    var file = obj.files[0];
    admin.confirm('确认同步 [' + file.name +'] 文件吗?', function (index) {
        layer.load(1, {shade: [0.1,'#fff']});
        var url = baseUrl + "/node/excel/import/auth";
        var form = new FormData();
        form.append("file", file);
        xhr = new XMLHttpRequest();
        xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
        xhr.setRequestHeader('token', localStorage.getItem('token'));
        xhr.onload = uploadComplete; //请求完成
        xhr.onerror =  uploadFailed; //请求失败
        xhr.onloadend = function () { // // 上传完成重置文件流
            layer.closeAll('loading');
            $("#importExcel").val("");
        };
        // xhr.upload.onprogress = progressFunction;//【上传进度调用方法实现】
        xhr.upload.onloadstart = function(){//上传开始执行方法
            ot = new Date().getTime();   //设置上传开始时间
            oloaded = 0;//设置上传开始时,以上传的文件大小为0
        };
        xhr.send(form);
    }, function(index){
        $("#importExcel").val("");
    });
}
function uploadComplete(evt) {
    var res = JSON.parse(evt.target.responseText);
    if(res.code === 200) {
        layer.msg(res.msg, {icon: 1});
        loadTree("");
    } else {
        layer.msg(res.msg, {icon: 2});
    }
}
function uploadFailed(evt) {
    var res = JSON.parse(evt.target.responseText);
    layer.msg(res.msg, {icon: 2});
}
// excel导出
function exportExcel() {
}
function tableReload(child) {
    var searchData = {};
    $.each($('#search-box [name]').serializeArray(), function() {
        searchData[this.name] = this.value;
    });
    (child ? parent.tableIns : tableIns).reload({
        where: searchData,
        page: {
            curr: pageCurr
        },
        done: function (res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
            }
            pageCurr=curr;
            if (res.data.length === 0 && count !== 0) {
                tableIns.reload({
                    where: searchData,
                    page: {
                        curr: pageCurr-1
                    }
                });
                pageCurr -= 1;
            }
            limit(child);
        }
    });
}
function clearFormVal(el) {
    $(':input', el)
        .val('')
        .removeAttr('checked')
        .removeAttr('selected');
}
$('body').keydown(function () {
    if (event.keyCode === 13) {
        $("#search").click();
    }
});
src/main/webapp/static/js/nodeLoc/nodeLocTree.js
New file
@@ -0,0 +1,86 @@
var currentTemId;
var currentTemName;
var currentTemSsbm;
var init = false;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"  // 配置模块所在的目录
}).use(['table','laydate', 'form', 'tree', 'xmSelect'], function() {
    var table = layui.table;
    var $ = layui.jquery;
    var layer = layui.layer;
    var layDate = layui.laydate;
    var form = layui.form;
    var tree = layui.tree;
    var xmSelect = layui.xmSelect;
    var selObj, treeData;  // 左树选中数据
    var organizationTree;
    window.loadTree = function(condition){
        var loadIndex = layer.load(2);
        $.ajax({
            url: baseUrl+"/node/tree/auth",
            headers: {'token': localStorage.getItem('token')},
            data: {
                'condition': condition
            },
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    layer.close(loadIndex);
                    // 树形图
                    organizationTree = tree.render({
                        elem: '#organizationTree',
                        id: 'organizationTree',
                        onlyIconControl: true,
                        data: res.data,
                        click: function (obj) {
                            currentTemId = obj.data.id;
                            currentTemName = obj.data.title.split(" - ")[0];
                            currentTemSsbm = obj.data.title.split(" - ")[1];
                            selObj = obj;
                            $('#organizationTree').find('.ew-tree-click').removeClass('ew-tree-click');
                            $(obj.elem).children('.layui-tree-entry').addClass('ew-tree-click');
                            tableIns.reload({
                                where: {parent_id: obj.data.id},
                                page: {curr: 1}
                            });
                        }
                    });
                    treeData = res.data;
                    if (isEmpty(condition) && init) {
                        tableIns.reload({
                            where: {parent_id: ""},
                            page: {curr: 1}
                        });
                    }
                    if (!init) {
                        init = true;
                    }
                } else if (res.code === 403){
                    top.location.href = baseUrl+"/";
                } else {
                    layer.msg(res.msg)
                }
            }
        })
    }
    loadTree();
    /* 树形图重置 */
    $('#treeReset').click(function () {
        $("#condition").val("");
        loadTree("");
    })
})
function closeDialog() {
    layer.closeAll();
}
/* 树形图搜索 */
function findData(el) {
    var condition = $(el).val();
    loadTree(condition)
}
src/main/webapp/views/index.html
@@ -6,7 +6,7 @@
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />
<!--  <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />-->
  <link rel="stylesheet" href="../static/layui/css/layui.css" media="all">
  <link rel="stylesheet" href="../static/css/admin.css?v=318" media="all">
  <link rel="stylesheet" href="../static/css/loader.css" media="all">
src/main/webapp/views/login.html
@@ -10,7 +10,7 @@
    <meta name="theme-color" content="#111111">
    <meta name="msapplication-TileImage" content="/sketch-threejs/img/common/ms_tileimage.png">
    <meta name="msapplication-TileColor" content="#111111">
    <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />
<!--    <link rel="icon" type="image/x-icon" href="../static/image/favicon.ico" />-->
    <link rel="stylesheet" href="../static/css/font/font-awesome-4.7.0/css/font-awesome.css">
    <link rel="stylesheet" href="../static/css/main.min.css">
    <link rel="stylesheet" href="../static/css/login.css">
src/main/webapp/views/nodeLoc/nodeLoc.html
@@ -88,7 +88,7 @@
                        <div class="layui-inline">
                            <label class="layui-form-label" style="padding: 8px 15px 8px 15px">库区:</label>
                            <div class="layui-input-inline">
                                <input name="parent_name" class="layui-input" placeholder="输入商品编号"/>
                                <input name="parent_name" class="layui-input" placeholder="库区名"/>
                            </div>
                        </div>
                        <div class="layui-inline">&emsp;
src/main/webapp/views/report/locDetl.html
@@ -33,7 +33,7 @@
    var pageCur;
    function getCol() {
        var cols = [
            {field: 'locNo$', align: 'center',title: '库位号'}
            {field: 'locNo', align: 'center',title: '库位号'}
        ];
        cols.push.apply(cols, detlCols);
        return cols;
src/main/webapp/views/saasLog/saasLog.html
@@ -20,9 +20,16 @@
                    <div class="layui-inline">
                        <label class="layui-form-label">编号:</label>
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off">
                            <input class="layui-input" type="text" name="loc_no" placeholder="库位" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <label class="layui-form-label">物料编号:</label>
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="matnr" placeholder="物料编号" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline">&emsp;
                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                            <i class="layui-icon">&#xe615;</i>搜索