src/main/java/com/zy/asrs/controller/MatController.java
@@ -14,6 +14,7 @@ import com.zy.asrs.entity.MatPrint; import com.zy.asrs.entity.OrderDetl; import com.zy.asrs.entity.param.EmptyPlateOutParam; import com.zy.asrs.entity.param.MatSyncParam; import com.zy.asrs.entity.result.KeyValueVo; import com.zy.asrs.service.MatService; import com.zy.asrs.utils.MatExcelListener; @@ -58,6 +59,13 @@ return R.ok().add(mats); } @RequestMapping(value = "mat/sync") @ManagerAuth public R sync(@RequestBody MatSyncParam matSyncParam){ return matService.sync(matSyncParam); } // @RequestMapping(value = "/mat/search/pda/auth") // @ManagerAuth // public R pdaSearch(@RequestParam(required = false)String condition){ src/main/java/com/zy/asrs/controller/OpenController.java
@@ -1,11 +1,16 @@ package com.zy.asrs.controller; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.annotations.AppAuth; import com.core.annotations.ManagerAuth; import com.core.common.*; import com.core.exception.CoolException; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.entity.param.*; import com.zy.asrs.service.OpenService; import com.zy.asrs.service.WorkService; import com.zy.asrs.service.impl.WrkMastServiceImpl; import com.zy.common.model.DetlDto; import com.zy.common.web.BaseController; import lombok.extern.slf4j.Slf4j; @@ -16,6 +21,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.HashMap; /** * Created by vincent on 2022/4/8 @@ -34,6 +41,10 @@ @Autowired private OpenService openService; @Autowired private WorkService workService; @Autowired private WrkMastServiceImpl wrkMastService; @PostMapping("/order/matSync/default/v2") // @AppAuth(memo = "商品信息同步接口") @@ -429,4 +440,30 @@ return R.error("任务号不存在"); } /** * 心跳接口 */ @PostMapping("/wmsHeartbeat") public R heartbeat(@RequestBody Map<String, Object> param) { if (param != null && param.get("timeStamp") != null) { return R.ok("操作成功"); } return R.error("失败"); } @RequestMapping("/taskCancel") @ManagerAuth(memo = "手动处理工作档") public R handControlWrkMast(@RequestHeader(required = false) String appkey,@RequestBody TaskCancelParam taskCancelParam,HttpServletRequest request){ auth(appkey, taskCancelParam, request); if (taskCancelParam.getTaskStatus() == 2) { workService.completeWrkMast(taskCancelParam.getTaskNo(),null); return R.ok("工作档已完成"); } else if (taskCancelParam.getTaskStatus() == 1) { workService.cancelWrkMast(taskCancelParam.getTaskNo(), null); return R.ok("工作档已取消"); } return R.ok(); } } src/main/java/com/zy/asrs/entity/param/MatSyncParam.java
@@ -23,17 +23,20 @@ /** * 商品编号 */ private String matnr; private String matNr; /** * 商品名称 */ private String maktx; private String makTx; /** * 商品分类 */ private String groupCode; private String groupId; /** * 分类名称 @@ -48,12 +51,17 @@ /** * 规格 */ private String specs; private String spec; /** * 型号 */ private String model; /** * 尺寸 */ private String size; /** * 颜色 @@ -194,6 +202,16 @@ * 备注 */ private String memo; /** * 描述 */ private String describle; /** * 操作类型,1 新增(默认);2 修改;3 禁用;4 启用; */ private Integer operateType; } } src/main/java/com/zy/asrs/entity/param/TaskCancelParam.java
New file @@ -0,0 +1,9 @@ package com.zy.asrs.entity.param; import lombok.Data; @Data public class TaskCancelParam { private String taskNo; private Integer taskStatus; } src/main/java/com/zy/asrs/entity/param/TaskStatusFeedbackParam.java
New file @@ -0,0 +1,39 @@ package com.zy.asrs.entity.param; import lombok.Data; import java.util.Date; /** * 任务状态反馈参数 */ @Data public class TaskStatusFeedbackParam { /** * 工作号 */ private String taskNo; /** * 1:取消 * 2:完结 * 3:拣选、盘点出库上报(任务未结束,需要回库) */ private Integer status; /** * 1:出库,2:移库,3:入库 */ private Integer ioType; /** * 托盘码 */ private String barcode; /** * 上报时间 */ private Date reportTime; } src/main/java/com/zy/asrs/service/MatService.java
@@ -2,7 +2,9 @@ import com.baomidou.mybatisplus.plugins.Page; import com.baomidou.mybatisplus.service.IService; import com.core.common.R; import com.zy.asrs.entity.Mat; import com.zy.asrs.entity.param.MatSyncParam; import java.util.List; @@ -20,5 +22,6 @@ Mat selectNewUpdateTime(); String getOldMatnr(Long id); R sync(MatSyncParam matSyncParam); } src/main/java/com/zy/asrs/service/OpenService.java
@@ -50,4 +50,14 @@ void taskArmWorkOrderStatus(OrderArmEndParam param); boolean TaskArmWorkOrderSign(OrderArmEndParam param); boolean TaskAgvReport(TaskAgvReportParam param); /** * 任务状态反馈上报 * @param taskNo 工作号 * @param status 状态 1:取消 2:完结 3:拣选、盘点出库上报 * @param ioType 类型 1:出库,2:移库,3:入库 * @param barcode 托盘码 * @return 是否成功 */ boolean reportTaskStatus(String taskNo, Integer status, Integer ioType, String barcode); } src/main/java/com/zy/asrs/service/impl/MatServiceImpl.java
@@ -1,17 +1,35 @@ package com.zy.asrs.service.impl; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.plugins.Page; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.core.common.R; import com.core.exception.CoolException; import com.zy.asrs.entity.Tag; import com.zy.asrs.entity.param.MatSyncParam; import com.zy.asrs.service.ApiLogService; import com.zy.asrs.service.TagService; import com.zy.common.config.CoolExceptionHandler; import com.zy.erp.kingdee.enums.KingDeeUtilType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zy.asrs.entity.Mat; import com.zy.asrs.mapper.MatMapper; import com.zy.asrs.service.MatService; import org.springframework.transaction.annotation.Transactional; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; @Service("matService") public class MatServiceImpl extends ServiceImpl<MatMapper, Mat> implements MatService { @Autowired private ApiLogService apiLogService; @Autowired private TagService tagService; @Override public Page<Mat> getPage(Page page, String tagId, Object matnr, Object maktx) { return page.setRecords(baseMapper.listByPage(page, tagId, matnr, maktx)); @@ -56,11 +74,159 @@ page.setTotal(16); return page; }; @Override public String getOldMatnr(Long id){ return this.baseMapper.getOldMatnr(id); } private Tag getOrCreateTag(MatSyncParam.MatParam param) { Tag tag = tagService.selectOne( new EntityWrapper<Tag>() .eq("name", param.getGroupName()) .eq("uuid", param.getGroupId()) ); Tag tagAll = tagService.selectOne(new EntityWrapper<Tag>().eq("name", "全部")); if (tag == null) { tag = new Tag(); tag.setUuid(param.getGroupId()); tag.setName(param.getGroupName()); tag.setParentId(tagAll.getId()); tag.setParentName("全部"); tag.setPath(String.valueOf(tagAll.getId())); tag.setPathName("全部"); tag.setStatus(1); tag.setLevel(2); if (!tagService.insert(tag)) { throw new CoolException("新建目录失败"); } } return tag; } @Override public R sync(MatSyncParam matSyncParam) { List<String> errors = new ArrayList<>(); Date now = new Date(); for (MatSyncParam.MatParam param : matSyncParam.getMatDetails()) { try { if (param.getOperateType() == 1 || param.getOperateType() == 2) { Tag tag = getOrCreateTag(param); Mat mat = this.selectOne( new EntityWrapper<Mat>().eq("matnr", param.getMatNr()) ); if (mat == null) { mat = new Mat(); mat.setMatnr(param.getMatNr()); mat.setStatus(1); fillMat(mat, param, tag); mat.setCreateTime(now); if (!this.insert(mat)) { errors.add("新增物料失败:" + param.getMatNr()); } } else { if (fillMat(mat, param, tag)) { mat.setUpdateTime(now); if (!this.updateById(mat)) { errors.add("更新物料失败:" + param.getMatNr()); } } } } if (param.getOperateType() == 3 || param.getOperateType() == 4) { Mat mat = this.selectOne( new EntityWrapper<Mat>().eq("matnr", param.getMatNr()) ); if (mat == null) { errors.add("物料不存在:" + param.getMatNr()); continue; } mat.setStatus(param.getOperateType() == 3 ? 0 : 1); if (!this.updateById(mat)) { errors.add("状态更新失败:" + param.getMatNr()); } } } catch (Exception e) { errors.add("处理异常:" + param.getMatNr()); } } if (errors.isEmpty()) { return R.ok("同步成功"); } R r = R.error("同步完成,存在失败数据"); r.put("errors", errors); return r; } private boolean fillMat(Mat mat, MatSyncParam.MatParam param, Tag tag) { boolean changed = false; if (!Objects.equals(mat.getMaktx(), param.getMakTx())) { mat.setMaktx(param.getMakTx()); changed = true; } if (!Objects.equals(mat.getMemo(), param.getDescrible())) { mat.setMemo(param.getDescrible()); changed = true; } if (!Objects.equals(mat.getWeight(), param.getWeight())) { mat.setWeight(param.getWeight()); changed = true; } if (!Objects.equals(mat.getSpecs(), param.getSpec())) { mat.setSpecs(param.getSpec()); changed = true; } if (!Objects.equals(mat.getModel(), param.getModel())) { mat.setModel(param.getModel()); changed = true; } if (!Objects.equals(mat.getColor(), param.getColor())) { mat.setColor(param.getColor()); changed = true; } if (!Objects.equals(mat.getBrand(), param.getSize())) { mat.setBrand(param.getSize()); changed = true; } if (!Objects.equals(mat.getUnit(), param.getUnit())) { mat.setUnit(param.getUnit()); changed = true; } if (!Objects.equals(mat.getUuid(), param.getGroupId())) { mat.setUuid(param.getGroupId()); changed = true; } Long tagId = tag == null ? null : tag.getId(); if (!Objects.equals(mat.getTagId(), tagId)) { mat.setTagId(tagId); changed = true; } return changed; } public void callApiLogSaveMat(Mat mat, String response, Boolean bool) { apiLogService.save("商品档案同步", "mat/sync", "null", "localhost", "物料编号:" + mat.getMatnr() + "、物料名称:" + mat.getMaktx() + "、毛重:" + mat.getWeight() + "、状态:" + mat.getStatus$(), response, bool); } } src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -1,6 +1,7 @@ package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.DateUtils; @@ -16,16 +17,16 @@ import com.zy.asrs.utils.OrderInAndOutUtil; import com.zy.asrs.utils.Utils; import com.zy.common.model.DetlDto; import com.zy.common.utils.HttpHandler; import com.zy.common.utils.NodeUtils; 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 org.springframework.transaction.annotation.Transactional; import javax.rmi.CORBA.Util; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.*; /** * Created by vincent on 2022/4/9 @@ -62,7 +63,10 @@ private BasAgvMastService basAgvMastService; @Autowired private LocOwnerService locOwnerService; @Autowired private ApiLogService apiLogService; @Value("${wms.url}") private String wmsUrl; @Override @Transactional public void pakinOrderCreate(OpenOrderPakinParam param) { @@ -519,12 +523,12 @@ } for(MatSyncParam.MatParam matParam : param.getMatDetails()){ if(Cools.isEmpty(matParam.getMatnr())){ if(Cools.isEmpty(matParam.getMatNr())){ throw new CoolException("商品编码不能为空"); } Date now = new Date(); Mat mat = matService.selectByMatnr(matParam.getMatnr()); Mat mat = matService.selectByMatnr(matParam.getMatNr()); if (mat == null) { mat = new Mat(); // 分类 @@ -612,7 +616,7 @@ } } else { mat.sync(matParam); if (!matService.update(mat, new EntityWrapper<Mat>().eq("matnr",matParam.getMatnr()))) { if (!matService.update(mat, new EntityWrapper<Mat>().eq("matnr",matParam.getMatNr()))) { throw new CoolException("更新已存在商品信息失败,请联系管理员"); } } @@ -778,4 +782,62 @@ } @Override public boolean reportTaskStatus(String taskNo, Integer status, Integer ioType, String barcode) { try { TaskStatusFeedbackParam param = new TaskStatusFeedbackParam(); param.setTaskNo(taskNo); param.setStatus(status); param.setIoType(ioType); param.setBarcode(barcode); param.setReportTime(new Date()); Map<String, Object> headers = new HashMap<>(); headers.put("appkey", "ea1f0459efc02a79f046f982767939ae"); String response = new HttpHandler.Builder() .setUri(wmsUrl) .setPath("/taskStatusFeedback") .setJson(JSON.toJSONString(param)) .setHeaders(headers) .build() .doPost(); boolean success = false; log.info("任务状态反馈上报结果:{}", response); if (response != null) { try { JSONObject jsonObject = JSON.parseObject(response); // 假设返回code为200表示成功 if (jsonObject != null && jsonObject.containsKey("code") && jsonObject.getInteger("code") == 200) { success = true; } } catch (Exception e) { log.warn("解析响应失败", e); } } // 记录日志 try { apiLogService.save("任务状态反馈上报", "/taskStatusFeedback", "ea1f0459efc02a79f046f982767939ae", wmsUrl, JSON.toJSONString(param), response, success); } catch (Exception e) { log.error("保存API日志异常", e); } return success; } catch (Exception e) { log.error("任务状态反馈上报异常", e); } return false; } } src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -103,6 +103,7 @@ @Resource private BasAgvWrkDetlService basAgvWrkDetlService; private OpenService openService; @Override @Transactional @@ -991,6 +992,7 @@ @Transactional public void completeWrkMast(String workNo, Long userId) { WrkMast wrkMast = wrkMastService.selectById(workNo); Integer ioType = 0; if (Cools.isEmpty(wrkMast)){ throw new CoolException(workNo+"工作档不存在"); } @@ -1000,9 +1002,15 @@ // 入库 + 库位转移 if (wrkMast.getWrkSts() < 4 || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()==11)) { wrkMast.setWrkSts(4L); if(wrkMast.getIoType() == 11){ ioType = 2; }else{ ioType = 3; } // 出库 } else if (wrkMast.getWrkSts() > 10) { wrkMast.setWrkSts(14L); ioType = 1; } Date now = new Date(); wrkMast.setCrnStrTime(DateUtils.calculate(now, 1L, TimeUnit.SECONDS, true)); src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -41,6 +41,8 @@ private OrderDetlPakinService orderDetlPakinService; @Autowired private OrderDetlPakoutService orderDetlPakoutService; @Autowired private OpenService openService; public ReturnT<String> start(WrkMast wrkMast) { // 4.入库完成 @@ -56,6 +58,8 @@ private ReturnT<String> doIn(WrkMast wrkMast){ Date now = new Date(); LocMast locMast = locMastService.selectById(wrkMast.getLocNo()); Integer status = 0; Integer ioType = 0; try { if (null == locMast) { // exceptionHandle("工作档[workNo={0}]库位号错误[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo()); @@ -79,6 +83,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("空板入库 ===>> 修改库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } status = 2; ioType = 3; } break; // 全板入库 @@ -166,6 +172,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("全板入库 ===>> 修改库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } status = 2; ioType = 3; } break; // 拣料途中并板 @@ -271,6 +279,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("拣料入库 ===>> 修改库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } status = 2; ioType = 3; } break; // 并板入库 @@ -372,6 +382,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("盘点入库 ===>> 修改库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } status = 2; ioType = 3; } break; // 库位移转 @@ -411,6 +423,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("库位移转 ===>> 修改目标库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } status = 2; ioType = 2; break; default: break; @@ -423,6 +437,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("更新入库完成状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); } openService.reportTaskStatus(String.valueOf(wrkMast.getWrkNo()),status,ioType,wrkMast.getBarcode()); } catch (Exception e) { log.error("fail", e); e.printStackTrace(); @@ -435,6 +451,8 @@ private ReturnT<String> doOut(WrkMast wrkMast){ Date now = new Date(); LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo()); Integer status = 0; Integer ioType = 0; try { if (null == locMast && wrkMast.getIoType() !=12) { // exceptionHandle("工作档[workNo={0}]库位号错误[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo()); @@ -497,6 +515,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("全板出库 ===>> 修改源库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]"); } status = 2; ioType = 1; } break; // 并板途中捡料 @@ -545,6 +565,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("空板出库 ===>> 修改源库位状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]"); } status = 2; ioType = 1; } break; //3号堆垛机衔接 @@ -561,6 +583,8 @@ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("更新出库完成状态失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]"); } openService.reportTaskStatus(String.valueOf(wrkMast.getWrkNo()),status,ioType,wrkMast.getBarcode()); } catch (Exception e) { log.error("fail", e); e.printStackTrace(); src/main/resources/application.yml
@@ -69,7 +69,8 @@ autoLocMoveBoolean: false # 自动移库功能开关 穿梭 autoLocMoveUnilateralBoolean: false wms: url: localhost:8080 comb: limit: 5000