自动化立体仓库 - WMS系统
0cac4ab2975a4dd01c937aa4f33ffa88c45b604b..08fc5462a5b82cf6cee38fc564d79c7b5f98160d
10 天以前 lty
#
08fc54 对比 | 目录
10 天以前 lty
#erp开发新增库存检查表
220241 对比 | 目录
10 天以前 lty
#erp开发
044e94 对比 | 目录
7个文件已添加
17个文件已修改
952 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/OpenController.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/CheckDetl.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/Mat.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/Tag.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/MatSyncParam.java 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/OpenOrderPakinParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/OpenOrderPakoutParam.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/CheckDetlMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocDetlMapper.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/CheckDetlService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/LocDetlService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OpenService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/CheckDetlServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/LocDetlServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/OrderReportScheduler.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/OrderMoveHistoryHandler.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/OrderReportHander.java 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/DetlDto.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/CheckDetlMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -33,16 +33,29 @@
    @Autowired
    private OpenService openService;
    @PostMapping("/order/matSync/default/v1")
    @PostMapping("/mat/sync/auth/v1")
    @AppAuth(memo = "商品信息同步接口")
    public synchronized R syncMatInfo(@RequestHeader(required = false) String appkey,
                                      @RequestBody(required = false) MatSyncParam param,
                                      @RequestBody(required = false) List<MatSyncParam> param,
                                      HttpServletRequest request){
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        }
        openService.syncMat(param);
        return R.ok();
    }
    @PostMapping("/stock/upload/auth/v1")
    @AppAuth(memo = "库存上报")
    public synchronized R syncStockUpload(@RequestHeader(required = false) String appkey,
                                      @RequestBody(required = false) List<MatSyncParam> param,
                                      HttpServletRequest request){
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        }
        openService.check(param);
        return R.ok();
    }
@@ -66,7 +79,7 @@
    /**
     * 添加入库单
     */
    @PostMapping("/order/pakin/default/v1")
    @PostMapping("/pakin/execute/auth/v1")
    public synchronized R pakinOrderCreate(@RequestHeader(required = false) String appkey,
                                           @RequestBody OpenOrderPakinParam param,
                                           HttpServletRequest request) {
@@ -77,11 +90,14 @@
        if (Cools.isEmpty(param.getOrderNo())) {
            return R.error("单据编号[orderNo]不能为空");
        }
        if (Cools.isEmpty(param.getOrderType())) {
            return R.error("单据类型[orderType]不能为空");
        if (Cools.isEmpty(param.getBillType())) {
            return R.error("单据类型[billType]不能为空");
        }
        if (Cools.isEmpty(param.getOrderDetails())) {
            return R.error("单据明细[orderDetails]不能为空");
        if (Cools.isEmpty(param.getCreateTime())) {
            return R.error("单据明细[createTime]不能为空");
        }
        if (Cools.isEmpty(param.getMatList())) {
            return R.error("单据明细[matList]不能为空");
        }
        openService.pakinOrderCreate(param);
        return R.ok();
@@ -101,7 +117,7 @@
    /**
     * 添加出库单
     */
    @PostMapping("/order/pakout/default/v1")
    @PostMapping("/pakout/execute/auth/v1")
    @AppAuth(memo = "添加订单出库")
    public synchronized R pakoutOrderCreate(@RequestHeader(required = false) String appkey,
                                            @RequestBody OpenOrderPakoutParam param,
@@ -110,20 +126,20 @@
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        }
        if (Cools.isEmpty(param.getLgort())) {
            return R.error("单据编号[lgort]不能为空");
        }
        if (!param.getLgort().equals("5006")) {
            return R.ok();
        }
//        if (Cools.isEmpty(param.getLgort())) {
//            return R.error("单据编号[lgort]不能为空");
//        }
//        if (!param.getLgort().equals("5006")) {
//            return R.ok();
//        }
        if (Cools.isEmpty(param.getOrderNo())) {
            return R.error("单据编号[orderNo]不能为空");
        }
        if (Cools.isEmpty(param.getOrderType())) {
            return R.error("单据类型[orderType]不能为空");
        if (Cools.isEmpty(param.getBillType())) {
            return R.error("单据类型[billType]不能为空");
        }
        if (Cools.isEmpty(param.getOrderDetails())) {
            return R.error("单据明细[orderDetails]不能为空");
        if (Cools.isEmpty(param.getMatList())) {
            return R.error("单据明细[matList]不能为空");
        }
        openService.pakoutOrderCreate(param);
        return R.ok();
@@ -173,7 +189,7 @@
        param.setOrderType("打包上线单");
        param.setOrderTime(DateUtils.convert(new Date()));
        List<DetlDto> orderDetails = new ArrayList<>();
        param.setOrderDetails(orderDetails);
        param.setMatList(orderDetails);
        for (int i = 0; i < 3; i++) {
            DetlDto detlDto = new DetlDto();
            switch (i) {
src/main/java/com/zy/asrs/entity/CheckDetl.java
New file
@@ -0,0 +1,50 @@
package com.zy.asrs.entity;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;
import com.core.common.Cools;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@TableName("asr_check_detl")
@ExcelIgnoreUnannotated
public class CheckDetl implements Serializable {
    @ApiModelProperty(value= "数量")
    @ExcelProperty("数量")
    private Double anfme;
    @ApiModelProperty(value= "商品编号")
    @ExcelProperty("商品编号")
    private String matnr;
    @ApiModelProperty(value= "商品名称")
    @ExcelProperty("商品名称")
    private String maktx;
    @ApiModelProperty(value= "规格")
    @ExcelProperty("规格")
    private String specs;
    @ApiModelProperty(value= "批号")
    @ExcelProperty("批号")
    private String batch;
    @ApiModelProperty(value= "添加时间")
    @TableField("create_time")
    private Date createTime;
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
}
src/main/java/com/zy/asrs/entity/Mat.java
@@ -56,6 +56,7 @@
    @TableField("tag_id")
    private Long tagId;
    /**
     * 商品编号
     */
src/main/java/com/zy/asrs/entity/Tag.java
@@ -30,7 +30,7 @@
     * 编号
     */
    @ApiModelProperty(value= "编号")
    private String uuid;
    private Long uuid;
    /**
     * 名称
@@ -149,7 +149,7 @@
    public Tag() {}
    public Tag(String uuid,String name,Long parentId,String parentName,String path,String pathName,Integer type,String leading,String img,String brief,Integer count,Integer level,Integer sort,Integer status,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) {
    public Tag(Long uuid,String name,Long parentId,String parentName,String path,String pathName,Integer type,String leading,String img,String brief,Integer count,Integer level,Integer sort,Integer status,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) {
        this.uuid = uuid;
        this.name = name;
        this.parentId = parentId;
@@ -201,11 +201,11 @@
        this.id = id;
    }
    public String getUuid() {
    public Long getUuid() {
        return uuid;
    }
    public void setUuid(String uuid) {
    public void setUuid(Long uuid) {
        this.uuid = uuid;
    }
src/main/java/com/zy/asrs/entity/param/MatSyncParam.java
@@ -11,34 +11,109 @@
@Data
public class MatSyncParam {
    /**
     *  创建时间
     */
    public String createTime;
//    /**
//     *  创建时间
//     */
//    public String createTime;
    public List<MatParam> matDetails;
    public List<MatParam> data;
    @Data
    public class MatParam{
    public static class MatParam{
        /**
         * 商品编号
         * 存货编码
         */
        private String matnr;
        /**
         * 商品名称
         * 存货名称
         */
        private String maktx;
//        /**
//         * 商品分类
//         */
//        private String groupCode;
//
//        /**
//         * 分类名称
//         */
//        private String groupName;
        /**
         * 商品分类
         * 存货大类编码
         */
        private String groupCode;
        private Long tagId;
        /**
         * 分类名称
         * 存货大类名称
         */
        private String groupName;
        private String tagIdName;
        /**
         * 存货检验员
         */
        private String inspectName;
        /**
         * 计量单位组编码
         */
        private String groupUnitId;
        /**
         * 主计量单位编码
         */
        private String unitId;
        /**
         * 销售默认计量单位编码
         */
        private String saleUnitId;
        /**
         * 销售默认计量单位名称
         */
        private String saleUnit;
        /**
         * 采购默认计量单位名称
         */
        private String procureUnit;
        /**
         * 采购默认计量单位编码
         */
        private String procureUnitId;
        /**
         * 库存默认计量单位编码
         */
        private String inventoryUnitId;
        /**
         * 库存默认计量单位名称
         */
        private String inventoryUnit;
        /**
         * 生产计量单位编码
         */
        private String produceUnitId;
        /**
         * 生产计量单位名称
         */
        private String produceUnit;
        /**
         * 默认仓库编码
         */
        private String warehouse;
        /**
         * 默认仓库名称
         */
        private String warehouseName;
        /**
         * 别名
@@ -66,7 +141,7 @@
        private String brand;
        /**
         * 单位
         * 主计量单位名称
         */
        private String unit;
@@ -194,6 +269,11 @@
         * 备注
         */
        private String memo;
        /**
         * 数量
         */
        private Double anfme;
    }
}
src/main/java/com/zy/asrs/entity/param/OpenOrderPakinParam.java
@@ -1,8 +1,10 @@
package com.zy.asrs.entity.param;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zy.common.model.DetlDto;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
@@ -15,8 +17,14 @@
    private String orderType;
    private String billType;
    private String orderTime;
    private List<DetlDto> orderDetails;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    private List<DetlDto> matList;
}
src/main/java/com/zy/asrs/entity/param/OpenOrderPakoutParam.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zy.common.model.DetlDto;
import lombok.Data;
@@ -19,10 +20,15 @@
    private String orderType;
    private String billType;
    private String orderTime;
    private List<DetlDto> orderDetails;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    private List<DetlDto> orderDetails;
    private List<DetlDto> matList;
    private String lgort;
    public static void main(String[] args) {
src/main/java/com/zy/asrs/mapper/CheckDetlMapper.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.CheckDetl;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface CheckDetlMapper extends BaseMapper<CheckDetl> {
}
src/main/java/com/zy/asrs/mapper/LocDetlMapper.java
@@ -40,6 +40,7 @@
    List<String> selectSameDetlTodayBatch(@Param("matnr") String matnr,@Param("batch") String batch, @Param("start") Integer start, @Param("end") Integer end);
    List<LocDetl> getStockStatis(Map<String, Object> map);
    Double getAnfmeByMatnr(@Param("matnr") String matnr);
    Integer getStockStatisCount(Map<String, Object> map);
src/main/java/com/zy/asrs/service/CheckDetlService.java
New file
@@ -0,0 +1,7 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.CheckDetl;
public interface CheckDetlService extends IService<CheckDetl> {
}
src/main/java/com/zy/asrs/service/LocDetlService.java
@@ -69,4 +69,6 @@
    List<Map<String, Object>> selectLocDetlUnilateralMoveShuttleMap(Integer crnNo);
    List<LocDetl> selectLocDetlUnilateralMoveShuttle(String matnr,String batch,String grade,Integer crnNo);
    Double getAnfmeByMatnr(String matnr);
}
src/main/java/com/zy/asrs/service/OpenService.java
@@ -42,5 +42,10 @@
     * 同步商品信息
     * @param param
     */
    void syncMat(MatSyncParam param);
    void syncMat(List<MatSyncParam> param);
    /**
     * 检查erp与立库系统物料数量
     */
    void check(List<MatSyncParam> param);
}
src/main/java/com/zy/asrs/service/impl/CheckDetlServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.CheckDetl;
import com.zy.asrs.mapper.CheckDetlMapper;
import com.zy.asrs.service.CheckDetlService;
import org.springframework.stereotype.Service;
@Service
public class CheckDetlServiceImpl extends ServiceImpl<CheckDetlMapper, CheckDetl> implements CheckDetlService {
}
src/main/java/com/zy/asrs/service/impl/LocDetlServiceImpl.java
@@ -6,6 +6,7 @@
import com.zy.asrs.entity.result.StockVo;
import com.zy.asrs.mapper.LocDetlMapper;
import com.zy.asrs.service.LocDetlService;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -63,6 +64,11 @@
    }
    @Override
    public Double getAnfmeByMatnr(String matnr){
        return this.baseMapper.getAnfmeByMatnr(matnr);
    }
    @Override
    public Double getSumAnfme(String matnr) {
        return this.baseMapper.selectSumAnfmeByMatnr(matnr);
    }
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -430,7 +430,7 @@
            openParam.setOrderNo(orderNo);
            openParam.setOrderTime(DateUtils.convert(now));
            openParam.setOrderType("打包入库单");
            openParam.setOrderDetails(detlDtos);
            openParam.setMatList(detlDtos);
            openService.pakinOrderCreate(openParam);
            Order order = orderService.selectByNo(orderNo);
            if (null == order) {
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -18,7 +18,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zy.asrs.entity.CheckDetl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -48,6 +48,8 @@
    private TagService tagService;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private CheckDetlService checkDetlService;
    @Override
    @Transactional
@@ -56,7 +58,7 @@
        if (!Cools.isEmpty(order)) {
            throw new CoolException(param.getOrderNo() + "单据已存在,请勿重复提交");
        }
        DocType docType = docTypeService.selectOrAdd(param.getOrderType(), Boolean.TRUE);
        DocType docType = docTypeService.selectOrAdd(param.getBillType(), Boolean.TRUE);
        Date now = new Date();
        // 单据主档
        order = new Order(
@@ -100,7 +102,7 @@
        }
        // 单据明细档
        List<DetlDto> list = new ArrayList<>();
        List<DetlDto> orderDetails = param.getOrderDetails();
        List<DetlDto> orderDetails = param.getMatList();
        for (DetlDto detail : orderDetails) {
            DetlDto dto = new DetlDto(detail.getMatnr(), detail.getBatch(), detail.getAnfme());
            if (DetlDto.has(list, dto)) {
@@ -191,7 +193,7 @@
            }
            orderService.remove(order.getId());
        }
        DocType docType = docTypeService.selectOrAdd(param.getOrderType(), Boolean.FALSE);
        DocType docType = docTypeService.selectOrAdd(param.getBillType(), Boolean.FALSE);
        Date now = new Date();
        // 单据主档
        order = new Order(
@@ -235,7 +237,7 @@
        }
        // 单据明细档
        List<DetlDto> list = new ArrayList<>();
        List<DetlDto> orderDetails = param.getOrderDetails();
        List<DetlDto> orderDetails = param.getMatList();
        for (DetlDto detail : orderDetails) {
            DetlDto dto = new DetlDto(detail.getMatnr(), detail.getBatch(), detail.getAnfme());
            if (DetlDto.has(list, dto)) {
@@ -435,113 +437,215 @@
        }
    }
//    @Override
//    @Transactional
//    public void syncMat(List<MatSyncParam> param) {
//        if (Cools.isEmpty(param.getMatDetails()) || param.getMatDetails().size() <=0 ) {
//            throw new CoolException("商品数据为空");
//        }
//
//        for(MatSyncParam.MatParam matParam : param.getMatDetails()){
//            if(Cools.isEmpty(matParam.getMatnr())){
//                throw new CoolException("商品编码不能为空");
//            }
//
//            Date now = new Date();
//            Mat mat = matService.selectByMatnr(matParam.getMatnr());
//            if (mat == null) {
//                mat = new Mat();
//                // 分类
//                Long tagId;
//                // 一级分类
//                if (!Cools.isEmpty(matParam.getTagId()) && !Cools.isEmpty(matParam.getTagIdName())) {
//                    Tag priTag = tagService.selectByName(matParam.getTagIdName(), 2);
//                    if (priTag == null) {
//                        Tag top = tagService.getTop();
//                        NodeUtils nodeUtils = new NodeUtils();
//                        nodeUtils.executePath(top.getId());
//                        priTag = new Tag(
//                                null,    // 编号
//                                matParam.getTagIdName(),    // 名称
//                                top.getId(),    // 父级
//                                top.getName(),    // 父级名称
//                                nodeUtils.path.toString(),    // 关联路径
//                                nodeUtils.pathName.toString(),    // 关联路径名
//                                0,    // 类型
//                                null,    // 负责人
//                                null,    // 图片
//                                null,    // 简要描述
//                                null,    // 数量
//                                2,    // 等级
//                                null,    // 排序
//                                1,    // 状态
//                                now,    // 添加时间
//                                null,    // 添加人员
//                                now,    // 修改时间
//                                null,    // 修改人员
//                                null    // 备注
//                        );
//                        if (tagMapper.insert(priTag) == 0) {
//                            throw new CoolException("服务器内部错误,请联系管理员");
//                        }
//                    }
//                } else {
//                    tagId = tagService.getTop().getId();
//                }
//                mat.sync(param);
////            mat.setMatnr(param.getMatnr());
////            mat.setMaktx(param.getMaktx());
////            mat.setSpecs(param.getSpecs());
////            mat.setModel(param.getModel());
//
//                mat.setTagId(1L);
//                mat.setStatus(1);
//                mat.setCreateTime(now);
//                mat.setUpdateTime(now);
//                if (!matService.insert(mat)) {
//                    throw new CoolException("服务器内部错误,请联系管理员");
//                } else {
//                    log.info("同步新物料[商品编号:{}]", mat.getMatnr());
//                }
//            } else {
//                mat.sync(param);
//                if (!matService.update(mat, new EntityWrapper<Mat>().eq("matnr",matParam.getMatnr()))) {
//                    throw new CoolException("更新已存在商品信息失败,请联系管理员");
//                }
//            }
//        }
//
//    }
        @Override
        @Transactional
        public void syncMat(List<MatSyncParam> paramList) {
            if (Cools.isEmpty(paramList)) {
                throw new CoolException("同步数据为空");
            }
            for (MatSyncParam param : paramList) {
                if (Cools.isEmpty(param.getData()) || param.getData().isEmpty()) {
                    throw new CoolException("商品数据为空");
                }
                for (MatSyncParam.MatParam matParam : param.getData()) {
                    if (Cools.isEmpty(matParam.getMatnr())) {
                        throw new CoolException("商品编码不能为空");
                    }
                    Date now = new Date();
                    Mat mat = matService.selectByMatnr(matParam.getMatnr());
                    if (mat == null) {
                        mat = new Mat();
                        // 分类
                        Long tagId;
                        if (!Cools.isEmpty(matParam.getTagId()) && !Cools.isEmpty(matParam.getTagIdName())) {
                            // 如果提供了 tagId 和 tagIdName,查询是否已有相同的分类
                            Tag priTag = tagService.selectByName(matParam.getTagIdName(), 2);
                            if (priTag == null) {
                                // 如果分类不存在,创建新的分类
                                Tag top = tagService.getTop();
                                NodeUtils nodeUtils = new NodeUtils();
                                nodeUtils.executePath(top.getId());
                                priTag = new Tag(
                                        matParam.getTagId(),
                                        matParam.getTagIdName(),
                                        top.getId(),
                                        top.getName(),
                                        nodeUtils.path.toString(),
                                        nodeUtils.pathName.toString(),
                                        0,
                                        null,
                                        null,
                                        null,
                                        null,
                                        2,
                                        null,
                                        1,
                                        now,
                                        null,
                                        now,
                                        null,
                                        null
                                );
                                if (tagMapper.insert(priTag) == 0) {
                                    throw new CoolException("服务器内部错误,请联系管理员");
                                }
                                tagId = priTag.getId();
                            } else {
                                // 如果分类已存在,使用现有的 tagId
                                tagId = priTag.getId();
                            }
                        } else {
                            // 如果没有提供 tagId 和 tagIdName,则使用默认的分类
                            tagId = tagService.getTop().getId();
                        }
                        mat.sync(matParam);  //
                        mat.setTagId(tagId);
                        mat.setStatus(1);
                        mat.setCreateTime(now);
                        mat.setUpdateTime(now);
                        if (!matService.insert(mat)) {
                            throw new CoolException("服务器内部错误,请联系管理员");
                        } else {
                            log.info("同步新物料[商品编号:{}]", mat.getMatnr());
                        }
                    } else {
                        Tag priTag = tagService.selectByName(matParam.getTagIdName(), 2);
                        matParam.setTagId(priTag.getId());
                        mat.sync(matParam);  // ⚠️ 同上
                        if (!matService.update(mat, new EntityWrapper<Mat>().eq("matnr", matParam.getMatnr()))) {
                            throw new CoolException("更新已存在商品信息失败,请联系管理员");
                        }
                    }
                }
            }
        }
    @Override
    @Transactional
    public void syncMat(MatSyncParam param) {
        if (Cools.isEmpty(param.getMatDetails()) || param.getMatDetails().size() <=0 ) {
            throw new CoolException("商品数据为空");
    public void check(List<MatSyncParam> paramList){
        if (Cools.isEmpty(paramList)) {
            throw new CoolException("上报数据为空");
        }
        for(MatSyncParam.MatParam matParam : param.getMatDetails()){
            if(Cools.isEmpty(matParam.getMatnr())){
                throw new CoolException("商品编码不能为空");
        for (MatSyncParam param : paramList) {
            if (Cools.isEmpty(param.getData()) || param.getData().isEmpty()) {
                throw new CoolException("物料数据为空");
            }
            Date now = new Date();
            Mat mat = matService.selectByMatnr(matParam.getMatnr());
            if (mat == null) {
                mat = new Mat();
                // 分类
                Long tagId;
                // 一级分类
                if (!Cools.isEmpty(matParam.getGroupCode()) && !Cools.isEmpty(matParam.getGroupName())) {
                    Tag priTag = tagService.selectByName(matParam.getGroupCode(), 2);
                    if (priTag == null) {
                        Tag top = tagService.getTop();
                        NodeUtils nodeUtils = new NodeUtils();
                        nodeUtils.executePath(top.getId());
                        priTag = new Tag(
                                null,    // 编号
                                matParam.getGroupCode(),    // 名称
                                top.getId(),    // 父级
                                top.getName(),    // 父级名称
                                nodeUtils.path.toString(),    // 关联路径
                                nodeUtils.pathName.toString(),    // 关联路径名
                                0,    // 类型
                                null,    // 负责人
                                null,    // 图片
                                null,    // 简要描述
                                null,    // 数量
                                2,    // 等级
                                null,    // 排序
                                1,    // 状态
                                now,    // 添加时间
                                null,    // 添加人员
                                now,    // 修改时间
                                null,    // 修改人员
                                null    // 备注
                        );
                        if (tagMapper.insert(priTag) == 0) {
                            throw new CoolException("服务器内部错误,请联系管理员");
                        }
                    }
                    // 二级分类
                    Tag secTag = tagService.selectByName(matParam.getGroupName(), 3);
                    if (secTag == null) {
                        NodeUtils nodeUtils = new NodeUtils();
                        nodeUtils.executePath(priTag.getId());
                        secTag = new Tag(
                                null,    // 编号
                                matParam.getGroupName(),    // 名称
                                priTag.getId(),    // 父级
                                priTag.getName(),    // 父级名称
                                nodeUtils.path.toString(),    // 关联路径
                                nodeUtils.pathName.toString(),    // 关联路径名
                                0,    // 类型
                                null,    // 负责人
                                null,    // 图片
                                null,    // 简要描述
                                null,    // 数量
                                3,    // 等级
                                null,    // 排序
                                1,    // 状态
                                now,    // 添加时间
                                null,    // 添加人员
                                now,    // 修改时间
                                null,    // 修改人员
                                null    // 备注
                        );
                        if (tagMapper.insert(secTag) == 0) {
                            throw new CoolException("服务器内部错误,请联系管理员");
                        }
                    }
                    tagId = secTag.getId();
                } else {
                    tagId = tagService.getTop().getId();
            for (MatSyncParam.MatParam matParam : param.getData()) {
                if (Cools.isEmpty(matParam.getMatnr())) {
                    throw new CoolException("商品编码为空");
                }
                mat.sync(param);
//            mat.setMatnr(param.getMatnr());
//            mat.setMaktx(param.getMaktx());
//            mat.setSpecs(param.getSpecs());
//            mat.setModel(param.getModel());
                mat.setTagId(tagId);
                mat.setStatus(1);
                mat.setCreateTime(now);
                mat.setUpdateTime(now);
                if (!matService.insert(mat)) {
                    throw new CoolException("服务器内部错误,请联系管理员");
                } else {
                    log.info("同步新物料[商品编号:{}]", mat.getMatnr());
                Double LKAnfme = locDetlService.getAnfmeByMatnr(matParam.getMatnr());
                if (LKAnfme == null) {
                    LKAnfme = 0.0;
                }
            } else {
                mat.sync(param);
                if (!matService.update(mat, new EntityWrapper<Mat>().eq("matnr",matParam.getMatnr()))) {
                    throw new CoolException("更新已存在商品信息失败,请联系管理员");
                // 计算差值
                double diff = matParam.getAnfme() - LKAnfme;
                if (diff != 0) {
                    CheckDetl checkDetl = new CheckDetl();
                    checkDetl.setAnfme(diff);  //这里记录差值
                    checkDetl.setMatnr(matParam.getMatnr());
                    checkDetl.setMaktx(matParam.getMaktx());
                    checkDetl.setSpecs(matParam.getSpecs());
                    checkDetl.setCreateTime(new Date());
                    checkDetlService.insert(checkDetl);  // 插入差异记录
                }
            }
        }
    }
}
src/main/java/com/zy/asrs/service/impl/OrderServiceImpl.java
@@ -116,7 +116,7 @@
                openParam.setOrderNo(orderNo);
                openParam.setOrderTime(DateUtils.convert(wrkMast.getModiTime()));
                openParam.setOrderType("手动入库单");
                openParam.setOrderDetails(detlDtos);
                openParam.setMatList(detlDtos);
                openService.pakinOrderCreate(openParam);
            } else {
                // 生成出库单据
src/main/java/com/zy/asrs/task/OrderReportScheduler.java
New file
@@ -0,0 +1,21 @@
package com.zy.asrs.task;
import com.zy.asrs.task.handler.OrderMoveHistoryHandler;
import com.zy.asrs.task.handler.OrderReportHander;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class OrderReportScheduler {
    @Autowired
    private OrderReportHander orderReportHander;
    /**
     * 将已作业数量与完成数量相同的订单明细上报,若已上报将标识改为2
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void execute(){
        orderReportHander.startPakIn();
        orderReportHander.startPakOut();
    }
}
src/main/java/com/zy/asrs/task/handler/OrderMoveHistoryHandler.java
@@ -26,10 +26,18 @@
    public ReturnT<String> start(){
        List<Order> settleEqual6 = orderService.selectList(new EntityWrapper<Order>()
                .eq("settle", 6));
        boolean result = true;
        for (Order order : settleEqual6) {
            List<OrderDetl> orderDetls = orderDetlService.selectList(new EntityWrapper<OrderDetl>()
                    .eq("order_no", order.getOrderNo()));
            moveBoth(order,orderDetls);
            for (OrderDetl orderDetl : orderDetls) {
                if(orderDetl.getMemo().isEmpty()){//若订单里仍有未上报的停止转历史档
                    result = false;
                }
            }
            if(result){
                moveBoth(order,orderDetls);
            }
            log.info("已完成单据移动至历史表成功 =====>" +order);
        }
        return SUCCESS;
src/main/java/com/zy/asrs/task/handler/OrderReportHander.java
New file
@@ -0,0 +1,292 @@
package com.zy.asrs.task.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.DocType;
import com.zy.asrs.entity.Order;
import com.zy.asrs.entity.OrderDetl;
import com.zy.asrs.service.ApiLogService;
import com.zy.asrs.service.DocTypeService;
import com.zy.asrs.service.OrderDetlService;
import com.zy.asrs.service.OrderService;
import com.zy.asrs.task.AbstractHandler;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.kingdee.handler.LoginAuthenticationHandler;
import com.zy.common.utils.HttpHandler;
import com.zy.erp.kingdee.enums.KingDeeUtilType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
@Slf4j
public class OrderReportHander extends AbstractHandler<String> {
    @Value("${erp.address.URL}")
    //端口
    private String URL;
    @Value("${erp.address.inaddressSave}")
    //上报入库地址
    private String inaddressSave;
    @Value("${erp.address.outaddressSave}")
    //上报出库地址
    private String outaddressSave;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetlService orderDetlService;
    @Autowired
    private ApiLogService apiLogService;
    @Autowired
    private DocTypeService docTypeService;
    @Autowired
    private LoginAuthenticationHandler loginAuthenticationHandler;
    public ReturnT<String> startPakIn() {
        // 查出所有数据入库单
        List<Order> orderList = orderService.selectList(new EntityWrapper<Order>().eq("doc_type", 34));
        for(Order order : orderList){
            List<OrderDetl> orderMemoList = orderDetlService.selectList(new EntityWrapper<OrderDetl>()
                    .isNull("memo")
                    .eq("order_No", order.getOrderNo()));//memo为空表示仍未上报
            List<OrderDetl> toReportList = new ArrayList<>();
            // 循环判断 anfme 和 qty 是否相等,相等则表示已完成入库
            for (OrderDetl orderDetl : orderMemoList) {
                if (orderDetl.getAnfme() != null && orderDetl.getQty() != null
                        && orderDetl.getAnfme().doubleValue() == orderDetl.getQty().doubleValue()) {
                    toReportList.add(orderDetl);
                }
            }
            // 如果有符合条件的数据,执行上报
            if (!toReportList.isEmpty()) {
                reportPakIn(toReportList);
                for (OrderDetl detl : toReportList) {
                    detl.setMemo("1");
                    orderDetlService.updateById(detl);
                    log.info("已完成单据上报 =====> " + detl);
                }
            }
        }
        return SUCCESS;
    }
    private void reportPakIn(List<OrderDetl> orderDetls) {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 构建主单 JSON 数据
        JSONObject requestBody = new JSONObject();
        requestBody.put("billType", "入库单");
        // 从第一个明细中提取订单号等信息
        if (!orderDetls.isEmpty()) {
            OrderDetl first = orderDetls.get(0);
            requestBody.put("orderNo", first.getOrderNo());
        }
        requestBody.put("createTime", sdf.format(now));
        // 构建物料列表
        JSONArray matList = new JSONArray();
        for (OrderDetl detl : orderDetls) {
            JSONObject mat = new JSONObject();
            mat.put("matnr", detl.getMatnr());
            mat.put("maktx", detl.getMaktx());
            mat.put("batch", detl.getBatch());
            mat.put("qty", detl.getQty());
            mat.put("anfme", detl.getAnfme());
            mat.put("units", detl.getUnits());
            matList.add(mat);
        }
        requestBody.put("matList", matList);
        // 发送 POST 请求
        String response = "";
        boolean success = false;
        try {
            HashMap<String, Object> headers = new HashMap<>();
            //  cookie
            headers.put("Cookie", loginAuthenticationHandler.start().getContent());
            response = new HttpHandler.Builder()
                    .setHeaders(headers)
                    .setUri(URL)
                    .setPath(inaddressSave) // 设置你的接口路径
                    .setJson(requestBody.toJSONString())
                    .build()
                    .doPost();
            JSONObject data = JSON.parseObject(response);
            Object isSuccess = findValueByKey(data, "IsSuccess");
            String bool = isSuccess != null ? isSuccess.toString() : "false";
            if ("true".equals(bool)) {
                success = true;
            }
        } catch (Exception e) {
            log.error("上报ERP失败", e);
        } finally {
            try {
                apiLogService.save(
                        "入库上报",
                        URL + inaddressSave,
                        null,
                        "127.0.0.1",
                        requestBody.toJSONString(),
                        response,
                        success
                );
            } catch (Exception e) {
                log.error("日志保存失败", e);
            }
        }
    }
    public ReturnT<String> startPakOut() {
        // 所有数据出库单
        List<Order> orderList = orderService.selectList(new EntityWrapper<Order>().eq("doc_type", 33));
        for(Order order : orderList){
            List<OrderDetl> orderMemoList = orderDetlService.selectList(new EntityWrapper<OrderDetl>()
                    .isNull("memo")
                    .eq("order_No", order.getOrderNo()));
            List<OrderDetl> toReportList = new ArrayList<>();
            // 循环判断 anfme 和 qty 是否相等
            for (OrderDetl orderDetl : orderMemoList) {
                if (orderDetl.getAnfme() != null && orderDetl.getQty() != null
                        && orderDetl.getAnfme().doubleValue() == orderDetl.getQty().doubleValue()) {
                    toReportList.add(orderDetl);
                }
            }
            // 如果有符合条件的数据,执行上报
            if (!toReportList.isEmpty()) {
                reportPakOut(toReportList);
                for (OrderDetl detl : toReportList) {
                    detl.setMemo("1");
                    orderDetlService.updateById(detl);
                    log.info("已完成单据上报 =====> " + detl);
                }
            }
        }
        return SUCCESS;
    }
    private void reportPakOut(List<OrderDetl> orderDetls) {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 构建主单 JSON 数据
        JSONObject requestBody = new JSONObject();
        requestBody.put("billType", "出库单");
        // 从第一个明细中提取订单号等信息
        if (!orderDetls.isEmpty()) {
            OrderDetl first = orderDetls.get(0);
            requestBody.put("orderNo", first.getOrderNo());
        }
        requestBody.put("createTime", sdf.format(now));
        // 构建物料列表
        JSONArray matList = new JSONArray();
        for (OrderDetl detl : orderDetls) {
            JSONObject mat = new JSONObject();
            mat.put("matnr", detl.getMatnr());
            mat.put("maktx", detl.getMaktx());
            mat.put("batch", detl.getBatch());
            mat.put("qty", detl.getQty());
            mat.put("anfme", detl.getAnfme());
            mat.put("units", detl.getUnits());
            matList.add(mat);
        }
        requestBody.put("matList", matList);
        // 发送 POST 请求
        String response = "";
        boolean success = false;
        try {
            HashMap<String, Object> headers = new HashMap<>();
            //cookie
            headers.put("Cookie", loginAuthenticationHandler.start().getContent());
            response = new HttpHandler.Builder()
                    .setHeaders(headers)
                    .setUri(URL)
                    .setPath(inaddressSave) // 设置你的接口路径
                    .setJson(requestBody.toJSONString())
                    .build()
                    .doPost();
            JSONObject data = JSON.parseObject(response);
            Object isSuccess = findValueByKey(data, "IsSuccess");
            String bool = isSuccess != null ? isSuccess.toString() : "false";
            if ("true".equals(bool)) {
                success = true;
            }
        } catch (Exception e) {
            log.error("上报ERP失败", e);
        } finally {
            try {
                apiLogService.save(
                        "出库上报",
                        URL + outaddressSave,
                        null,
                        "127.0.0.1",
                        requestBody.toJSONString(),
                        response,
                        success
                );
            } catch (Exception e) {
                log.error("日志保存失败", e);
            }
        }
    }
    public static Object findValueByKey(JSONObject json, String key) {
        Set<String> keySet = json.keySet();
        for (String k : keySet) {
            Object v = json.get(k);
            if (k.equals(key)) {
                return v;
            } else if (v instanceof JSONArray) {
                int size = ((JSONArray) v).size();
                for (int i = 0; i <= size - 1; i++) {
                    Object result = findValueByKey((JSONObject) ((JSONArray) v).get(i), key);
                    if (result != null){
                        return result;
                    }
                }
            } else if (v instanceof JSONObject){
                Object result = findValueByKey((JSONObject) v, key);
                if (result != null){
                    return result;
                }
            }
        }
        return null;
    }
}
src/main/java/com/zy/common/model/DetlDto.java
@@ -21,6 +21,8 @@
    private Double anfme;
    private Double units;
    public DetlDto() {
    }
@@ -40,6 +42,13 @@
        this.anfme = anfme;
    }
    public DetlDto(String matnr, String batch, Double anfme, Double units) {
        this.matnr = matnr;
        this.batch = batch;
        this.anfme = anfme;
        this.units = units;
    }
    public DetlDto(String orderNo, String matnr, String batch, Double anfme) {
        this.orderNo = orderNo;
        this.matnr = matnr;
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=dlzasrs
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=tzglasrs
    username: sa
    password: sa@123
  mvc:
src/main/resources/mapper/CheckDetlMapper.xml
New file
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.CheckDetlMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.CheckDetl">
        <result column="anfme" property="anfme"/>
        <result column="matnr" property="matnr"/>
        <result column="maktx" property="maktx"/>
        <result column="specs" property="specs"/>
        <result column="batch" property="batch"/>
        <result column="create_time" property="createTime"/>
    </resultMap>
</mapper>
src/main/resources/mapper/LocDetlMapper.xml
@@ -150,6 +150,14 @@
         ) t where t.row between ((#{pageNumber}-1)*#{pageSize}+1) and (#{pageNumber}*#{pageSize})
    </select>
    <select id="getAnfmeByMatnr" resultType="com.zy.asrs.entity.LocDetl">
        select
            sum(a.anfme) as anfme
        from asr_loc_detl a
        where matnr = #{matnr}
    </select>
    <select id="getStockStatisCount" parameterType="java.util.Map" resultType="java.lang.Integer">
     select count(1) as count from
        (