pom.xml
@@ -9,13 +9,13 @@ <relativePath/> </parent> <groupId>com.zy</groupId> <artifactId>asrs</artifactId>t <artifactId>asrs</artifactId> <version>1.1.1</version> <packaging>war</packaging> <properties> <java.version>1.8</java.version> <cool.version>3.4.0</cool.version> <cool.version>3.2.0</cool.version> <mysql-driver.version>5.1.47</mysql-driver.version> <mybatis-plus.version>2.3.2</mybatis-plus.version> <fastjson.version>1.2.58</fastjson.version> @@ -44,6 +44,8 @@ <groupId>cn.cool</groupId> <artifactId>framework</artifactId> <version>${cool.version}</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/libs/framework-3.2.0.jar</systemPath> </dependency> <dependency> <groupId>org.apache.tika</groupId> @@ -103,6 +105,8 @@ <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <!-- <version>1.18.30</version>--> <!-- <optional>true</optional>--> <version>1.16.22</version> <scope>provided</scope> </dependency> @@ -120,13 +124,42 @@ </dependencies> <build> <finalName>wms</finalName> <finalName>djwms</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- <plugin>--> <!-- <groupId>org.apache.maven.plugins</groupId>--> <!-- <artifactId>maven-compiler-plugin</artifactId>--> <!-- <version>3.10.1</version>--> <!-- <configuration>--> <!-- <source>1.8</source>--> <!-- <target>1.8</target>--> <!-- <encoding>UTF-8</encoding>--> <!-- <compilerArgs>--> <!-- <arg>-parameters</arg>--> <!-- </compilerArgs>--> <!-- <compilerArguments>--> <!-- <extdirs>${project.basedir}/src/main/resources/libs</extdirs>--> <!-- </compilerArguments>--> <!-- </configuration>--> <!-- </plugin>--> </plugins> <!-- <resources>--> <!-- <resource>--> <!-- <directory>src/main/resources</directory>--> <!-- <includes>--> <!--<!– <include>**/log/**</include>–>--> <!-- <include>**/libs/**</include>--> <!--<!– <include>**/*.properties</include>–>--> <!--<!– <include>**/*.xml</include>–>--> <!-- </includes>--> <!-- <filtering>false</filtering>--> <!-- </resource>--> <!-- </resources>--> </build> </project> src/main/java/META-INF/MANIFEST.MF
New file @@ -0,0 +1,3 @@ Manifest-Version: 1.0 Main-Class: com.zy.Boot src/main/java/com/zy/asrs/controller/DigitalTwinController.java
New file @@ -0,0 +1,310 @@ package com.zy.asrs.controller; import com.core.common.R; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.digitaltwin.*; import com.zy.asrs.service.DigitalTwinService; import com.zy.common.web.BaseController; import org.springframework.web.bind.annotation.RequestMapping; 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.List; @RequestMapping("/digitalTwin") @RestController public class DigitalTwinController extends BaseController { @Resource private DigitalTwinService digitalTwinService; /** * 数据总览 * * @param areaId 库区编码 * @return */ @RequestMapping(value = "/overview") // @ManagerAuth public R overview(@RequestParam(required = false) String areaId){ //digitalTwinService.overview(areaId); DtOverviewVo dtOverviewVo = DtOverviewVo.builder() .totalLoc(999) .useLoc(900) .idleLoc(99) .todayOutbound(160) .todayWarehousing(170) .remainingStock(180) .build(); return R.ok().add(dtOverviewVo); } /** * 近期订单(默认7天) * * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentOrder") // @ManagerAuth public R recentOrder(@RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate){ // digitalTwinService.order(startDate, endDate); DtOrderVo dtOrderVo = DtOrderVo.builder() .orderDate("2025-10-22") .orderNum(156) .build(); DtOrderVo dtOrderVo2 = DtOrderVo.builder() .orderDate("2025-10-23") .orderNum(166) .build(); List<DtOrderVo> orderVoList = new ArrayList<>(); orderVoList.add(dtOrderVo); orderVoList.add(dtOrderVo2); return R.ok().add(orderVoList); } /** * 近期剩余库位(默认7天) * * @param areaId 库区编码 * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentIdleLoc") // @ManagerAuth public R recentIdleLoc(@RequestParam(required = false) String areaId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate){ // digitalTwinService.recentLoc(areaId, startDate, endDate); DtLocVo dtLocVo = DtLocVo.builder() .locDate("2025-10-22") .idleNum(208) .build(); DtLocVo dtLocVo2 = DtLocVo.builder() .locDate("2025-10-23") .idleNum(177) .build(); List<DtLocVo> locVoList = new ArrayList<>(); locVoList.add(dtLocVo); locVoList.add(dtLocVo2); return R.ok().add(locVoList); } /** * 近期出入库(默认7天) * * @param areaId 库区编码 * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentInAndOutBound") // @ManagerAuth public R recentInAndOutBound(@RequestParam(required = false) String areaId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate){ // digitalTwinService.inAndOutBound(areaId, startDate, endDate); DtInAndOutBoundVo dtInAndOutBoundVo = DtInAndOutBoundVo.builder() .boundDate("2025-10-22") .inBoundNum(237) .outBoundNum(487) .build(); DtInAndOutBoundVo dtInAndOutBoundVo2 = DtInAndOutBoundVo.builder() .boundDate("2025-10-23") .inBoundNum(187) .outBoundNum(287) .build(); List<DtInAndOutBoundVo> inAndOutBoundVoList = new ArrayList<>(); inAndOutBoundVoList.add(dtInAndOutBoundVo); inAndOutBoundVoList.add(dtInAndOutBoundVo2); return R.ok().add(inAndOutBoundVoList); } /** * 近期呆滞品(默认超30天) * * @param areaId 库区编码 * @param overDayNum 呆滞品天数,默认30天 * @return */ @RequestMapping(value = "/recentDetainMat") // @ManagerAuth public R recentDetainMat(@RequestParam(required = false) String areaId, @RequestParam(required = false) Integer overDayNum, @RequestParam(required = false) Integer pageIndex, @RequestParam(required = false) Integer pageSize){ // digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize); DtDetainMatVo dtDetainMatVo = DtDetainMatVo.builder() .belongAreaId("A1") .belongAreaName("刀具库") .matId("mat10001") .matName("道具把") .lokId("loc1001") .lokName("库位10001") .detainTime(765) .inBoundTime("2025-10-11T11:15:16") .build(); DtDetainMatVo dtDetainMatVo2 = DtDetainMatVo.builder() .belongAreaId("A1") .belongAreaName("刀具库") .matId("mat10002") .matName("道具把") .lokId("loc1002") .lokName("库位10002") .detainTime(665) .inBoundTime("2025-10-10T11:15:16") .build(); List<DtDetainMatVo> detainMatVoList = new ArrayList<>(); detainMatVoList.add(dtDetainMatVo); detainMatVoList.add(dtDetainMatVo2); return R.ok().add(detainMatVoList); } /** * 设备运行信息 * * @param areaId * @return */ @RequestMapping(value = "/equipment") // @ManagerAuth public R equipment(@RequestParam(required = false) String areaId){ DtEquipmentVo dtDetainMatVo = DtEquipmentVo.builder() .equipmentId("eq1001") .equipmentName("堆垛机1") .equipmentType(1) .belongAreaId("A1") .belongAreaName("刀具库") .verticalSpeed(288) .horizontalSpeed(203) .voltage(48) .status(1) .operateMethod(1) .build(); DtEquipmentVo dtDetainMatVo2 = DtEquipmentVo.builder() .equipmentId("eq1002") .equipmentName("堆垛机2") .equipmentType(1) .belongAreaId("A1") .belongAreaName("刀具库") .verticalSpeed(208) .horizontalSpeed(253) .voltage(48) .status(1) .operateMethod(1) .build(); List<DtEquipmentVo> dtEquipmentVoList = new ArrayList<>(); dtEquipmentVoList.add(dtDetainMatVo); dtEquipmentVoList.add(dtDetainMatVo2); return R.ok().add(dtEquipmentVoList); } /** * 库位和库存详情 * * @param areaId * @return */ @RequestMapping(value = "/warehouseDetail") // @ManagerAuth public R warehouseDetail(@RequestParam(required = false) String areaId){ // digitalTwinService.warehouseDetail(areaId); List<DtLocDetailVo> dtLocDetailVoList = new ArrayList<>(); DtLocDetailVo dtLocDetailVo = new DtLocDetailVo(); dtLocDetailVo.setLocNo("CA0100202"); dtLocDetailVo.setLocSts("O"); dtLocDetailVo.setAreaId(10010L); dtLocDetailVo.setAreaName("刀具库"); dtLocDetailVo.setRow1(1); dtLocDetailVo.setBay1(2); dtLocDetailVo.setLev1(2); LocMast locMast = new LocMast(); locMast.setLocNo("CA0100202"); locMast.setLocSts("O"); locMast.setRow1(1); locMast.setBay1(2); locMast.setLev1(2); dtLocDetailVo.setLocMast(locMast); LocDetl locDetl = new LocDetl(); locDetl.setLocNo("CA0100202"); locDetl.setAreaId(10010L); locDetl.setAreaName("刀具库"); locDetl.setMatnr("mat10001"); locDetl.setMaktx("物料名称"); locDetl.setAnfme(100.0); locDetl.setStandby3("AAA,BBB,CCC"); dtLocDetailVo.setLocDetl(locDetl); dtLocDetailVoList.add(dtLocDetailVo); DtLocDetailVo dtLocDetailVo2 = new DtLocDetailVo(); dtLocDetailVo2.setLocNo("CA0100202"); dtLocDetailVo2.setLocSts("O"); dtLocDetailVo2.setAreaId(10010L); dtLocDetailVo2.setAreaName("刀具库"); dtLocDetailVo2.setRow1(1); dtLocDetailVo2.setBay1(2); dtLocDetailVo2.setLev1(2); LocMast locMast2 = new LocMast(); locMast2.setLocNo("CA0100203"); locMast2.setLocSts("O"); locMast2.setRow1(1); locMast2.setBay1(2); locMast2.setLev1(3); dtLocDetailVo2.setLocMast(locMast2); LocDetl locDetl2 = new LocDetl(); locDetl2.setLocNo("CA0100203"); locDetl2.setAreaId(10010L); locDetl2.setAreaName("刀具库"); locDetl.setMatnr("mat10001"); locDetl.setMaktx("物料名称"); locDetl.setAnfme(100.0); locDetl.setStandby3("AAA1,BBB1,CCC1"); dtLocDetailVo2.setLocDetl(locDetl2); dtLocDetailVoList.add(dtLocDetailVo2); // LocDetl locDetl2 = new LocDetl(); // locDetl2.setLocNo("1001"); // locDetl2.setAreaId(10010L); // locDetl2.setAreaName("刀具库"); // locDetl2.setMatnr("mat10001"); // locDetl2.setMaktx("刀把"); // //// List<LocDetl> locDetlList = new ArrayList<>(); //// locDetlList.add(locDetl); //// locDetlList.add(locDetl2); return R.ok().add(dtLocDetailVoList); } } src/main/java/com/zy/asrs/controller/MesController.java
New file @@ -0,0 +1,100 @@ package com.zy.asrs.controller; import com.alibaba.fastjson.JSONObject; import com.core.common.R; import com.zy.asrs.entity.mes.*; import com.zy.asrs.service.MesService; import com.zy.common.web.BaseController; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController public class MesController extends BaseController { @Resource private MesService mesService; // 物料信息同步 @PostMapping("/api/mes/synMatInfo") public MesReturn synMatInfo(@RequestBody MesMatInfo param){ MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess(mesService.synMatInfo(param) == 1 ? "1" : "2"); return mesReturn; } // 出库申请 @PostMapping("/api/mes/outBoundOrder") public MesReturn outBoundOrder(@RequestBody MesInApply param){ MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess(mesService.outBoundOrder(param) == 1 ? "1" : "2"); return mesReturn; } // // 出库申请(叫料),装配库、滑块库 // @PostMapping("/api/mes/callOutBoundOrder") // public MesReturn callOutBoundOrder(@RequestBody MesCallOutApply param){ // // MesReturn mesReturn = new MesReturn(); // mesReturn.setSuccess(mesService.callOutBoundOrder(param) == 1 ? "1" : "2"); // return mesReturn; // } // 入库申请 @PostMapping("/api/mes/inBoundOrder") public MesReturn inBoundOrder(@RequestBody MesInApply param){ MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess(mesService.inBoundOrder(param, 0) == 1 ? "1" : "2"); return mesReturn; } // 入站允许 @PostMapping("/api/mes/allowInStation") public MesReturn allowInStation(@RequestBody TransInOutStationAllow param){ return mesService.allowInStation(param); } // 离站允许,装配库、滑块库 @PostMapping("/api/mes/allowOutStation") public MesReturn allowOutStation(@RequestBody TransInOutStationAllow param){ return mesService.allowOutStation(param); } // 下发运输任务 @PostMapping("/api/mes/submitTask") public JSONObject submitTask(@RequestBody TransTask param){ return mesService.submitTask(param); } // 接受成品刀可以入库二维码 @PostMapping("/api/mes/inBoundItemBarcode") public MesReturn inBoundItemBarcode(@RequestBody MesItemBarCode param){ MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); // TODO:待缓存成品刀二维码; return mesReturn; } // region 测试 @GetMapping("/api/mes/transDj") public int transDj(@RequestParam String taskNo,@RequestParam String djNo){ return mesService.transDj(taskNo,djNo); } // 退空托盘返回产线 pda上操作空托返回产线 @GetMapping("/tkt") public R tkt(@RequestParam String taskNo){ return mesService.tkt(taskNo); } // endregion } src/main/java/com/zy/asrs/controller/NodeController.java
@@ -35,7 +35,7 @@ import java.net.URLEncoder; import java.util.*; import static jdk.nashorn.api.scripting.ScriptUtils.convert; //import static jdk.nashorn.api.scripting.ScriptUtils.convert; @RestController public class NodeController extends BaseController { src/main/java/com/zy/asrs/controller/RcsController.java
New file @@ -0,0 +1,44 @@ package com.zy.asrs.controller; import com.alibaba.fastjson.JSONObject; import com.zy.asrs.entity.mes.TransParent; import com.zy.asrs.entity.rcs.RcsReporterEqpt; import com.zy.asrs.entity.rcs.RcsReporterTask; import com.zy.asrs.entity.rcs.RcsReturn; import com.zy.asrs.service.RcsService; import com.zy.common.web.BaseController; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class RcsController extends BaseController { @Resource private RcsService rcsService; // 反馈任务执行结果 @PostMapping("/api/robot/reporter/task") public RcsReturn reporterTask(@RequestBody RcsReporterTask param){ return rcsService.reporterTask(param); } // 反馈封锁区(自动门)申请 @PostMapping("/api/robot/reporter/eqpt") public RcsReturn reporterEqpt(@RequestBody RcsReporterEqpt param){ return rcsService.reporterEqpt(param); } // 华晓AGV申请进入产线(光幕) @PostMapping("/api/robot/apply/inLine") public JSONObject hxApplyInLine(@RequestBody TransParent param){ return rcsService.hxApplyInLine(param); } } src/main/java/com/zy/asrs/entity/AgvInfo.java
New file @@ -0,0 +1,53 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data @TableName("agv_info") public class AgvInfo implements Serializable { private static final long serialVersionUID = 1L; /** * 主键,设备编号 */ @ApiModelProperty(value= "主键") @TableId(value = "agvNo", type = IdType.AUTO) private String agvNo; /** * 设备名称 */ @ApiModelProperty(value= "设备名称") @TableField("agv_name") private String agvName; /** * 设备类型,1 agv;2 ctu; */ @ApiModelProperty(value= "设备类型") @TableField("agv_type") private String agvType; /** * 设备厂家,1 海康;2 华晓; */ @ApiModelProperty(value= "设备类型") @TableField("agv_factory") private Integer agvFactory; /** * 所属库区 */ @ApiModelProperty(value= "所属库区") @TableField("belong_area") private String belongArea; } src/main/java/com/zy/asrs/entity/BlockStation.java
New file @@ -0,0 +1,81 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data @TableName("agv_block_station") public class BlockStation implements Serializable { private static final long serialVersionUID = 1L; /** * 主键 */ @ApiModelProperty(value= "主键") @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 站点编号 */ @ApiModelProperty(value= "站点id") @TableField("dev_no") private String devNo; /** * 站点名称 */ @ApiModelProperty(value= "站点名称") @TableField("dec_name") private String decName; /** * 封锁区id */ @ApiModelProperty(value= "封锁区id") @TableField("block_no") private String blockNo; /** * 封锁区名称 */ @ApiModelProperty(value= "封锁区名称") @TableField("block_name") private String blockName; /** * 所属库区id */ @ApiModelProperty(value= "所属库区id") @TableField("area_id") private String areaId; /** * 所属库区名称 */ @ApiModelProperty(value= "所属库区名称") @TableField("area_name") private String areaName; /** * 状态,0 空闲;1 海康封锁中;2 华晓封锁中;-1 异常; */ @ApiModelProperty(value= "状态") @TableField("status") private Integer status; /** * 封锁区内agv数量 */ @ApiModelProperty(value= "状态") @TableField("agv_num") private Integer agvNum; } src/main/java/com/zy/asrs/entity/BlockTask.java
New file @@ -0,0 +1,74 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; import java.util.Date; @Data @TableName("agv_block_task") public class BlockTask implements Serializable { private static final long serialVersionUID = 1L; /** * 主键,请求号 */ @ApiModelProperty(value= "主键") @TableId(value = "task_code") private String taskCode; /** * 请求时间 */ @ApiModelProperty(value= "请求时间") @TableField("apply_time") private Date applyTime; /** * 封锁区id */ @ApiModelProperty(value= "封锁区id") @TableField("block_no") private String blockNo; /** * 封锁区名称 */ @ApiModelProperty(value= "封锁区名称") @TableField("block_name") private String blockName; /** * 进入方法,APPLY_LOCK 申请封锁区;RELEASE_EQPT 释放封锁区; */ @ApiModelProperty(value= "进入方法") @TableField("method") private String method; /** * 是否完成,1 完成;0 未完成; */ @ApiModelProperty(value= "是否完成") @TableField("completed") private Integer completed; /** * 完成时间 */ @ApiModelProperty(value= "完成时间") @TableField("completed_time") private Date completedTime; /** * agv厂家,1 海康;2 华晓; */ @ApiModelProperty(value= "agv厂家") @TableField("agv_factory") private Integer agvFactory; } src/main/java/com/zy/asrs/entity/LocCount.java
New file @@ -0,0 +1,41 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @TableName("asr_loc_count") public class LocCount { private static final long serialVersionUID = 1L; /** * 日期 */ @ApiModelProperty(value= "日期,格式:20250101") @TableField("date") private Integer date; /** * 库区号 */ @ApiModelProperty(value= "库区号") @TableField("area_id") private String areaId; /** * 库位数量 */ @ApiModelProperty(value= "库位数量") @TableField("loc_num") private Integer locNum; /** * 剩余库位数量 */ @ApiModelProperty(value= "剩余库位数量") @TableField("remain_num") private Integer remainNum; } src/main/java/com/zy/asrs/entity/LocDetl.java
@@ -121,7 +121,8 @@ private Double weight; @ApiModelProperty(value= "长度") private Double man_length; @TableField("man_length") private Double manLength; @ApiModelProperty(value= "体积") private Double volume; src/main/java/com/zy/asrs/entity/Task.java
@@ -334,6 +334,13 @@ @TableField("take_none") private String takeNone; /** * 外部任务编号 */ @ApiModelProperty(value= "外部任务编号") @TableField("task_no") private String taskNo; public Task() {} public String getYmd$(){ src/main/java/com/zy/asrs/entity/WrkMast.java
@@ -325,6 +325,13 @@ @TableField("take_none") private String takeNone; /** * 外部任务编号 */ @ApiModelProperty(value= "外部任务编号") @TableField("task_no") private String taskNo; public WrkMast() {} public String getYmd$(){ src/main/java/com/zy/asrs/entity/digitaltwin/DtDetainMatVo.java
New file @@ -0,0 +1,28 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:呆滞品信息 @Data @Builder public class DtDetainMatVo { // 归属库区ID private String belongAreaId; // 归属库区名称 private String belongAreaName; // 物料ID private String matId; // 物料名称 private String matName; // 所属库位ID private String lokId; // 所属库位名称 private String lokName; // 呆滞时间,计算单位:分钟 private Integer detainTime; // 入库时间,格式:2025-10-11T11:15:16,预留 private String inBoundTime; } src/main/java/com/zy/asrs/entity/digitaltwin/DtEquipmentVo.java
File was renamed from src/main/java/com/zy/asrs/entity/result/DtEquipmentVo.java @@ -1,4 +1,4 @@ package com.zy.asrs.entity.result; package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; src/main/java/com/zy/asrs/entity/digitaltwin/DtInAndOutBoundVo.java
New file @@ -0,0 +1,17 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天出入库数量 @Data @Builder public class DtInAndOutBoundVo { // 日期 private String boundDate; // 入库数量 private Integer inBoundNum; // 出库数量 private Integer outBoundNum; } src/main/java/com/zy/asrs/entity/digitaltwin/DtLocDetailVo.java
New file @@ -0,0 +1,30 @@ package com.zy.asrs.entity.digitaltwin; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import lombok.Data; @Data public class DtLocDetailVo { // 库位号 private String locNo; // 库位状态,O空库位(英文不是数字);F 在库;D 空板;P 出库中;R 出库预约;S 入库预约;其他 其他; private String locSts; // 库区id private Long areaId; // 库区名称 private String areaName; // 排 private Integer row1; // 列 private Integer bay1; // 层 private Integer lev1; // 库位信息 private LocMast locMast; // 库存信息 private LocDetl locDetl; } src/main/java/com/zy/asrs/entity/digitaltwin/DtLocVo.java
File was renamed from src/main/java/com/zy/asrs/entity/result/DtLocVo.java @@ -1,4 +1,4 @@ package com.zy.asrs.entity.result; package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; src/main/java/com/zy/asrs/entity/digitaltwin/DtOrderVo.java
New file @@ -0,0 +1,15 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天订单数量 @Data @Builder public class DtOrderVo { // 日期 private String orderDate; // 订单数量 private Integer orderNum; } src/main/java/com/zy/asrs/entity/digitaltwin/DtOverviewVo.java
New file @@ -0,0 +1,24 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天出库、入库数量 @Data @Builder public class DtOverviewVo { // 总库位 private Integer totalLoc; // 已用库位 private Integer useLoc; // 剩余库位 private Integer idleLoc; // 今日出库 private Integer todayOutbound; // 今日入库 private Integer todayWarehousing; // 剩余库存 private Integer remainingStock; } src/main/java/com/zy/asrs/entity/mes/MesCallOutApply.java
New file @@ -0,0 +1,61 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; // 出库申请(叫料) @EqualsAndHashCode(callSuper = true) @Data public class MesCallOutApply extends MesParent { // // 任务编号 // private String taskno; // // 任务名称 // private String taskname; // // 生产订单号 // @JsonProperty("OrderNo") // private String OrderNo; // 运输类型,字典值(wms_tranfs_type) 06 装配领料;01:空托 @JsonProperty("TransType") @JSONField(name = "TransType") private String TransType; // // 生产线编码 // @JsonProperty("ProductLineId") // private String ProductLineId; // // 工位编码 // @JsonProperty("StationId") // private String StationId; // 当前工序 @JsonProperty("CurProcess") @JSONField(name = "CurProcess") private String CurProcess; // 配盘信息 @JsonProperty("Itemdata") @JSONField(name = "Itemdata") private List<MesOutApplyItem> Itemdata; // (sfc_shop_route_consume)mes中配盘表名 @Data public static class MesOutApplyItem { // 配盘号 private String trayid; // 零件编码 @JsonProperty("Itemno") @JSONField(name = "Itemno") private String Itemno; // 数量 @JsonProperty("Qty") @JSONField(name = "Qty") private Integer Qty; // 物料二维码 @JsonProperty("ItemBarcode") @JSONField(name = "ItemBarcode") private String ItemBarcode; } } src/main/java/com/zy/asrs/entity/mes/MesInApply.java
New file @@ -0,0 +1,124 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; // MES入库申请\入库完成 //@EqualsAndHashCode(callSuper = true) @Data public class MesInApply { //extends MesParent // public MesInApply() { // Details = new ArrayList<>(); // } // 单据类型,0 采购入库;1 生产入库;2 退货入库; @JsonProperty("billType") @JSONField(name = "billType") private String billType; // // 生产线编码 @JsonProperty("productLineId") private String productLineId; // // 工位编码 @JsonProperty("stationId") private String stationId; // 生产订单号 @JsonProperty("orderNo") @JSONField(name = "orderNo") private String orderNo; // agv任务号 @JsonProperty("taskNo") @JSONField(name = "taskNo") private String taskNo; // agv运输类型 @JsonProperty("transType") @JSONField(name = "transType") private String transType; // 时间,格式:2025-11-19 10:11:12 @JsonProperty("createTime") @JSONField(name = "createTime") private String createTime; // 入库详情 @JsonProperty("details") @JSONField(name = "details") private List<MesItemDetails> details; // @Data // @NoArgsConstructor // public static class ItemDetails { // // // 物料编码 // @JsonProperty("itemNo") // @JSONField(name = "itemNo") // private String itemNo; // // // 数量 // @JsonProperty("anfme") // @JSONField(name = "anfme") // private String anfme; // } // //// // 任务编号 //// private String taskno; //// // 任务名称 //// private String taskname; //// // 生产线编码 //// @JsonProperty("ProductLineId") //// private String ProductLineId; //// // 工位编码 //// @JsonProperty("StationId") //// private String StationId; // // 零件编码 // @JsonProperty("Itemno") // @JSONField(name = "Itemno") // private String Itemno; //// // 托盘条码 //// @JsonProperty("TuoPanId") //// @JSONField(name = "TuoPanId") //// private String TuoPanId; // // 数量,托盘零件数量 // @JsonProperty("Qty") // @JSONField(name = "Qty") // private Float Qty; // // 版本号 // @JsonProperty("VersionNo") // @JSONField(name = "VersionNo") // private String VersionNo; //// // 生产订单号 //// @JsonProperty("OrderNo") //// private String OrderNo; // // 配盘信息 // @JsonProperty("ProductInfo") // @JSONField(name = "ProductInfo") // private List<ProductInfo> ProductInfo; // // @Data // @NoArgsConstructor // public static class ProductInfo { // // // 物料二维码 // @JsonProperty("ItemBarcode") // @JSONField(name = "ItemBarcode") // private String ItemBarcode; // // 质量状态 // @JsonProperty("QualityStatus") // @JSONField(name = "QualityStatus") // private Integer QualityStatus; // } } src/main/java/com/zy/asrs/entity/mes/MesItemBarCode.java
New file @@ -0,0 +1,34 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class MesItemBarCode { // 刀具RFID码 @JSONField(name = "ToolRfidCode") @JsonProperty("ToolRfidCode") private String ToolRfidCode; // 刀具名称 @JSONField(name = "ToolName") @JsonProperty("ToolName") private String ToolName; // 刀具种类编码 @JSONField(name = "ToolCode") @JsonProperty("ToolCode") private String ToolCode; // 机床刀号 @JSONField(name = "MachineToolNo") @JsonProperty("MachineToolNo") private String MachineToolNo; // 版本 @JSONField(name = "Version") @JsonProperty("Version") private String Version; } src/main/java/com/zy/asrs/entity/mes/MesItemDetails.java
New file @@ -0,0 +1,19 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class MesItemDetails { // 物料编码 @JsonProperty("itemNo") @JSONField(name = "itemNo") private String itemNo; // 数量 @JsonProperty("anfme") @JSONField(name = "anfme") private Double anfme; } src/main/java/com/zy/asrs/entity/mes/MesMatInfo.java
New file @@ -0,0 +1,67 @@ package com.zy.asrs.entity.mes; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import javax.validation.constraints.NotNull; // MES物料信息 @Data public class MesMatInfo { // 物料编码,唯一标识 @NotNull private String item_no; // 物料名称 @NotNull private String description; // 单位 private String unit_of_measure; // 物料类型 @NotNull private String item_type; // 材质 private String cz; // 重量 private float weight; // 物料属性 @NotNull private String classification_code; // 图号 private String drawing_no; // 设计备注 private String item_comments; // 创建时间,timestamp private String create_date; // 最近一次修改时间,timestamp private String modified_date1; // 最近修改人 private String modified_operator1; // 生产单位 private String dept; // 是否关键件 private String gt_code; // 规格型号 private String specification; // 工艺备注 private String proc_comments; // 工艺修改人 private String proc_operator; // 工艺修改时间,timestamp private String proc_modified_date; // ABC码 private String abc_code; // 供应商编码 private String vendor_no; // 版本号 private String drawing_version; // 生产订单号 @NotNull @JsonProperty("OrderNo") // @JSONField(name = "OrderNo") private String OrderNo; // 本单入库数量 @NotNull private Float qty; } src/main/java/com/zy/asrs/entity/mes/MesMatRecvForm.java
New file @@ -0,0 +1,17 @@ package com.zy.asrs.entity.mes; import lombok.Data; // MES发出的领料入库单 @Data public class MesMatRecvForm { // 来源单号 private String source_no; // 来源单名称 private String source_name; // 操作人 private String operuser; // 物料信息 private MesMatInfo itemdata; } src/main/java/com/zy/asrs/entity/mes/MesOutApply.java
New file @@ -0,0 +1,46 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; // 出库申请 @EqualsAndHashCode(callSuper = true) @Data public class MesOutApply extends MesParent { // // 任务编号 // private String taskno; // // 任务名称 // private String taskname; // // 生产订单号 // @JsonProperty("OrderNo") // @JSONField(name = "OrderNo") // private String OrderNo; // 运输类型,字典值(wms_tranfs_type) 06 装配领料;01:空托 @JsonProperty("TransType") @JSONField(name = "TransType") private String TransType; // 零件编码 @JsonProperty("Itemno") @JSONField(name = "Itemno") private String Itemno; // 数量 @JsonProperty("Qty") @JSONField(name = "Qty") private Integer Qty; // // 生产线编码 // @JsonProperty("ProductLineId") // @JSONField(name = "ProductLineId") // private String ProductLineId; // // 工位编码 // @JsonProperty("StationId") // @JSONField(name = "StationId") // private String StationId; // 物料二维码 @JsonProperty("ItemBarcode") @JSONField(name = "ItemBarcode") private String ItemBarcode; } src/main/java/com/zy/asrs/entity/mes/MesOutFeedback.java
New file @@ -0,0 +1,45 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; // 返回MES出库完成 @EqualsAndHashCode(callSuper = true) @Data public class MesOutFeedback extends MesParent { // // 任务编号 // private String taskno; // // 任务名称 // private String taskname; // // 生产线编码 // @JsonProperty("ProductLineId") // @JSONField(name = "ProductLineId") // private String ProductLineId; // // 工位编码 // @JsonProperty("StationId") // @JSONField(name = "StationId") // private String StationId; // 零件编码 @JsonProperty("Itemno") @JSONField(name = "Itemno") private String Itemno; // 托盘条码 @JsonProperty("TuoPanId") @JSONField(name = "TuoPanId") private String TuoPanId; // 数量,托盘零件数量 @JsonProperty("Qty") @JSONField(name = "Qty") private Integer Qty; // 物料二维码 @JsonProperty("ItemBarcode") @JSONField(name = "ItemBarcode") private String ItemBarcode; // // 生产订单号 // @JsonProperty("OrderNo") // @JSONField(name = "OrderNo") // private String OrderNo; } src/main/java/com/zy/asrs/entity/mes/MesParent.java
New file @@ -0,0 +1,39 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class MesParent { // 任务编号 @JsonProperty("taskno") @JSONField(name = "taskno") private String taskno; // 任务名称 @JsonProperty("taskname") @JSONField(name = "taskname") private String taskname; // 生产订单号 @JsonProperty("OrderNo") @JSONField(name = "OrderNo") private String OrderNo; // 生产线编码 @JsonProperty("ProductLineId") @JSONField(name = "ProductLineId") private String ProductLineId; // 工位编码 @JsonProperty("StationId") @JSONField(name = "StationId") private String StationId; // // 零件编码 // @JsonProperty("Itemno") // @JSONField(name = "Itemno") // private String Itemno; // // 数量,托盘零件数量 // @JsonProperty("Qty") // @JSONField(name = "Qty") // private Float Qty; } src/main/java/com/zy/asrs/entity/mes/MesRecvFeedback.java
New file @@ -0,0 +1,32 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; import java.util.List; // 入库反馈 @Data public class MesRecvFeedback { // 来源单号 private String source_no; // 操作人 private String operuser; // 反馈信息 private List<MesRecvFeedbackItem> itemdata; @Data public static class MesRecvFeedbackItem { // 物料编码 private String item_no; // 生产订单号 @JSONField(name = "OrderNo") private String OrderNo; // 本单入库数量 private Integer qty; // 本单实际数量 private Integer real_qty; } } src/main/java/com/zy/asrs/entity/mes/MesReturn.java
New file @@ -0,0 +1,38 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; // MES接口返回结果 public class MesReturn { // 1:成功;2:失败 @JsonProperty("Success") private String Success; // 失败消息 @JsonProperty("Message") private String Message; @JsonProperty("Success") public String getSuccess() { return Success; } @JsonProperty("Success") public void setSuccess(String success) { this.Success = success; } @JsonProperty("Message") public String getMessage() { return Message; } @JsonProperty("Message") public void setMessage(String message) { this.Message = message; } } src/main/java/com/zy/asrs/entity/mes/TransArrivalStation.java
New file @@ -0,0 +1,61 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; // 到站完成 //@EqualsAndHashCode(callSuper = true) @Data public class TransArrivalStation { // 任务编号 @JsonProperty("taskno") @JSONField(name = "taskno") private String taskno; // 任务名称 @JsonProperty("taskname") @JSONField(name = "taskname") private String taskname; // 生产订单号 @JsonProperty("OrderNo") @JSONField(name = "OrderNo") private String OrderNo; // 生产线编码 @JsonProperty("ProductLineId") @JSONField(name = "ProductLineId") private String ProductLineId; // 工位编码 @JsonProperty("StationID") @JSONField(name = "StationID") private String StationID; // 到站类型,06:装配领料,07:装配入库,08:装配转序 @JsonProperty("Daotype") @JSONField(name = "Daotype") private String Daotype; // 托盘条码 @JsonProperty("TuoPanId") @JSONField(name = "TuoPanId") private String TuoPanId; // AGV编码 @JsonProperty("AgvCode") @JSONField(name = "AgvCode") private String AgvCode; // 物料编码 @JsonProperty("Itemno") @JSONField(name = "Itemno") private String Itemno; // 零件码 @JsonProperty("ItemBarcode") @JSONField(name = "ItemBarcode") private List<String> ItemBarcode; // 刀架编号 @JsonProperty("DJNo") @JSONField(name = "DJNo") private String DJNo; } src/main/java/com/zy/asrs/entity/mes/TransInOutStationAllow.java
New file @@ -0,0 +1,13 @@ package com.zy.asrs.entity.mes; import lombok.Data; import lombok.EqualsAndHashCode; // 入站允许、离站允许 @EqualsAndHashCode(callSuper = true) @Data public class TransInOutStationAllow extends TransParent { // 是否允许,Y 允许;N,不允许 private String status; } src/main/java/com/zy/asrs/entity/mes/TransParent.java
New file @@ -0,0 +1,31 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; // 出入站请求继承父类:入站请求、入站允许、离站请求、离站允许、离站完成 @Data public class TransParent { // 任务编号,wcs_task_header表中的task_no private String taskno; // 任务名称,wcs_task_header表中的task_name private String taskname; // AGV编码 @JsonProperty("AgvCode") @JSONField(name = "AgvCode") private String AgvCode; // 运输类型 @JsonProperty("TransType") @JSONField(name = "TransType") private String TransType; // 生产线编码 @JsonProperty("ProductLineId") @JSONField(name = "ProductLineId") private String ProductLineId; // 工位编码 @JsonProperty("StationId") @JSONField(name = "StationId") private String StationId; } src/main/java/com/zy/asrs/entity/mes/TransTask.java
New file @@ -0,0 +1,68 @@ package com.zy.asrs.entity.mes; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; // MES运输任务 @Data public class TransTask { // 任务编号,wcs_task_header表中的task_no private String taskno; // 任务名称,wcs_task_header表中的task_name private String taskname; // 生产订单号 @JsonProperty("OrderNo") @JSONField(name = "OrderNo") private String OrderNo; // 运输类型,01:空托,02:毛坯,03:成品,04:转序,本接口为转序 @JsonProperty("TransType") @JSONField(name = "TransType") private String TransType; // 当前工序,通过当前任务 @JsonProperty("CurProcess") @JSONField(name = "CurProcess") private String CurProcess; // 起点编码 @JsonProperty("CurStationId") @JSONField(name = "CurStationId") private String CurStationId; // 下一工位,默认计划下一工序,可手工调整 @JsonProperty("NextProcess") @JSONField(name = "NextProcess") private String NextProcess; // 终点编码 @JsonProperty("NextStationId") @JSONField(name = "NextStationId") private String NextStationId; // 零件编码 @JsonProperty("Itemno") @JSONField(name = "Itemno") private String Itemno; // 数量 @JsonProperty("Qty") @JSONField(name = "Qty") private Integer Qty; // 生产线编码 @JsonProperty("ProductLineId") @JSONField(name = "ProductLineId") private String ProductLineId; // 物料二维码 @JsonProperty("ItemBarcode") @JSONField(name = "ItemBarcode") private String ItemBarcode; // 操作类型,1 新增任务;2 修改任务;3 取消任务;(RCS执行后无法取消) @JsonProperty("OperateType") @JSONField(name = "OperateType") private Integer OperateType; // 指定AGV厂家,1 海康;2 华晓;华晓与海康AGV运载能力不同,MES可按需求指定 @JsonProperty("AgvFactory") @JSONField(name = "AgvFactory") private Integer AgvFactory; // 刀架编号 @JsonProperty("DJNo") private String djNo; } src/main/java/com/zy/asrs/entity/mes/TransTaskFeedback.java
New file @@ -0,0 +1,17 @@ package com.zy.asrs.entity.mes; import lombok.Data; // MES运输任务反馈 @Data public class TransTaskFeedback { // 任务编号,wcs_task_header表中的task_no private String taskno; // 任务名称,wcs_task_header表中的task_name private String taskname; // 任务执行结果,1 完成;2 失败; private Integer result; // 失败原因 private String failMsg; } src/main/java/com/zy/asrs/entity/rcs/RcsEqptNotify.java
New file @@ -0,0 +1,16 @@ package com.zy.asrs.entity.rcs; import lombok.Data; // 通知进入 @Data public class RcsEqptNotify { // 封锁区编号 private String eqptCode; // 申请编号,可使用 UUID private String taskCode; // 任务执行状态:可扩展枚举值。预制枚举值:1 可以进入封锁区; private String actionStatus; } src/main/java/com/zy/asrs/entity/rcs/RcsReporterEqpt.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.entity.rcs; import lombok.Data; // 请求进入封锁区、入站、离站等 @Data public class RcsReporterEqpt { // 封锁区编号 private String eqptCode; // 封锁区名称 private String eqptName; // 申请编号,可使用 UUID private String taskCode; // 任务执行方法,与设备相关,可扩展枚举值。 预制枚举值:APPLY_LOCK 申请封锁区;RELEASE_EQPT 释放封锁区; private String method; // agv厂家,1 海康;2 华晓 private Integer agvFactory; } src/main/java/com/zy/asrs/entity/rcs/RcsReporterTask.java
New file @@ -0,0 +1,18 @@ package com.zy.asrs.entity.rcs; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 任务执行反馈 @Data public class RcsReporterTask { // 任务号 private String robotTaskCode; // 当前执行任务的机器人唯一标识。 private String singleRobotCode; // 目标路径序列,0 起点序号,1 终点序号。 private Integer currentSeq; // 详细信息 private JSONObject extra; } src/main/java/com/zy/asrs/entity/rcs/RcsReturn.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.entity.rcs; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 海康返回 @Data public class RcsReturn { // SUCCESS 成功 // Err_TaskTypeNotSupport 任务类型不支持 // Err_RobotGroupsNotMatch 机器人资源组编号与任务不匹配,无法调度 // Err_RobotCodeNotMatch 机器人编号与任务不匹配,无法调度 // Err_TargetRouteError 任务路径参数有误 private String code; private String message; private JSONObject data; } src/main/java/com/zy/asrs/entity/rcs/RcsTaskCancel.java
New file @@ -0,0 +1,17 @@ package com.zy.asrs.entity.rcs; import lombok.Data; // 取消任务 @Data public class RcsTaskCancel { // 任务号,全局唯一 private String robotTaskCode; // 任务取消类型 //取消(原软取消) //CANCEL //人工介入(原硬取消) //DROP private String cancelType; } src/main/java/com/zy/asrs/entity/rcs/RcsTaskContinue.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.entity.rcs; import lombok.Data; // 继续执行任务 @Data public class RcsTaskContinue { // 任务链编号 private String robotTaskCode; // 触发类型: //SITE 站点编号触发 //CARRIER 载具编号触发 //ROBOT 车号触发 //TASK 任务链编号触发 private String triggerType; // 与 triggerType 对应的触发编号 private String triggerCode; } src/main/java/com/zy/asrs/entity/rcs/RcsTaskSubmit.java
New file @@ -0,0 +1,29 @@ package com.zy.asrs.entity.rcs; import lombok.Data; import java.util.List; // RCS任务下发 @Data public class RcsTaskSubmit { // 任务类型,枚举值:TRANSPORT搬运。 private String taskType = "TRANSPORT"; // 执行步骤集合。本次任务机器人需要执行的关键路径,序号0代表起点,序号1代表终点。 private List<RcsTaskTargetRoute> targetRoute; // 任务唯一编号,如果为空,系统生成任务号并返回。 private String robotTaskCode; // 任务执行的初始优先顺序,数值越大,优先级越高。 private Integer initPriority; // 要求调度系统仅在当前指定的范围内选择机器人执行该任务。可能出现任务与机器人类型不匹配的异常,需要业务系统确保任务与机器人类型的匹配。如果不指定,则调度系统会在所有可用机器人的范围内寻找最优方案。 // 固定枚举值: GROUPS 机器人资源组编号;ROBOTS 机器人编号; private String robotType; // 与 robotType 匹配的资源类型唯一标识。支持单个和多个编号。若写入多个编号时,之间用逗号隔开。 private String robotCode; // 能否打断,1:可打断,该货架中途有其他任务时,打断当前任务。0:不可打断,该货架中途有其他任务时,不能打断当前任务。默认不可打断。 private String interrupt; // 任务组编号,全局唯一。 private String groupCode; } src/main/java/com/zy/asrs/entity/rcs/RcsTaskTargetRoute.java
New file @@ -0,0 +1,22 @@ package com.zy.asrs.entity.rcs; import lombok.Data; // 任务路线 @Data public class RcsTaskTargetRoute { // 目标路径序列。0 起点序号; 1 终点序号。 private Integer seq; // 目标类型。可扩展枚举值。预制枚举值:SITE 站点别名; private String type = "SITE"; // 站点编号 private String code; // 机器人到达目标位置后的操作。预制枚举值:COLLECT取货;DELIVERY送货; private String operation; // 要求调度系统仅在当前指定的范围内选择机器人执行该步骤。固定枚举值:GROUPS机器人资源组编号;ROBOTS机器人编号; private String robotType; // 与 robotType 匹配的资源类型唯一标识。 private String robotCode; } src/main/java/com/zy/asrs/enums/RcsRetMethodEnum.java
New file @@ -0,0 +1,38 @@ package com.zy.asrs.enums; public enum RcsRetMethodEnum { TASK_START("start", "任务开始"), TASK_END("end", "任务完成"), TASK_OUT_BIN("outbin", "走出储位"), APPLY_IN_STATION("applyInStation", "入站请求"), APPLY_OFF_STATION("applyOutStation", "离站请求"), ARRIVE_ON_STATION("arriveOnStation", "到站完成"), ARRIVE_OFF_STATION("arriveOffStation", "离站完成"); private String code; private String message; RcsRetMethodEnum(String code, String message) { this.code = code; this.message = message; } public static RcsRetMethodEnum getEnum(String code) { for (RcsRetMethodEnum method : RcsRetMethodEnum.values()) { if (method.getCode().equals(code)) { return method; } } return null; } public String getCode() { return code; } public String getMessage() { return message; } } src/main/java/com/zy/asrs/mapper/AgvInfoMapper.java
New file @@ -0,0 +1,11 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.AgvInfo; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface AgvInfoMapper extends BaseMapper<AgvInfo> { } src/main/java/com/zy/asrs/mapper/BlockStationMapper.java
New file @@ -0,0 +1,14 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.BlockStation; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; @Mapper @Repository public interface BlockStationMapper extends BaseMapper<BlockStation> { Integer addByBlockNo(@Param("blockNo")String blockNo, @Param("status")int status); } src/main/java/com/zy/asrs/mapper/BlockTaskMapper.java
New file @@ -0,0 +1,16 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.BlockTask; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; @Mapper @Repository public interface BlockTaskMapper extends BaseMapper<BlockTask> { BlockTask findTop(); BlockTask findByTaskCode(@Param("taskCode")String taskCode); } src/main/java/com/zy/asrs/mapper/DigitalTwinMapper.java
New file @@ -0,0 +1,26 @@ package com.zy.asrs.mapper; import com.zy.asrs.entity.digitaltwin.DtDetainMatVo; import com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo; import com.zy.asrs.entity.digitaltwin.DtOrderVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface DigitalTwinMapper { List<Double> overview(@Param("areaId")String areaId); List<DtOrderVo> recentOrder(@Param("startTime")String startTime, @Param("endTime")String endTime); List<DtInAndOutBoundVo> recentInBound(@Param("areaId")String areaId, @Param("startTime")String startTime, @Param("endTime")String endTime); List<DtInAndOutBoundVo> recentOutBound(@Param("areaId")String areaId, @Param("startTime")String startTime, @Param("endTime")String endTime); List<DtDetainMatVo> recentDetainMat(@Param("areaId")String areaId, @Param("startTime")String startTime, @Param("pageIndex")Integer pageIndex, @Param("pageSize")Integer pageSize); } src/main/java/com/zy/asrs/mapper/LocCountMapper.java
New file @@ -0,0 +1,24 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.LocCount; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface LocCountMapper extends BaseMapper<LocCount> { List<LocCount> getByAreaAndDate(@Param("areaId")String areaId, @Param("startDate")int startDate, @Param("endDate")int endDate); List<LocCount> getByDate(@Param("startDate")int startDate, @Param("endDate")int endDate); Integer insertOrUpdate(@Param("model")LocCount model); List<LocCount> totalLoc(); List<LocCount> useLoc(); } src/main/java/com/zy/asrs/service/DigitalTwinService.java
New file @@ -0,0 +1,70 @@ package com.zy.asrs.service; import com.zy.asrs.entity.digitaltwin.*; import java.util.List; public interface DigitalTwinService { /** * 总览:总库位、已用库位、剩余库位、今日出库、今日入库、剩余库位 * * @param areaId * @return */ DtOverviewVo overview(String areaId); /** * 近期订单,默认7天 * * @param startDate * @param endDate * @return */ List<DtOrderVo> order(String startDate, String endDate); /** * 近期出库、入库数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ List<DtInAndOutBoundVo> inAndOutBound(String areaId, String startDate, String endDate); /** * 近期近期呆滞品信息,默认超过30天为呆滞品 * * @param areaId * @param overDayNum * @param pageIndex * @param pageSize * @return */ List<DtDetainMatVo> recentDetainMat(String areaId, Integer overDayNum, Integer pageIndex, Integer pageSize); /** * 查询库存和库位详细信息 * * @param areaId * @return */ List<DtLocDetailVo> warehouseDetail(String areaId); /** * 近期剩余库位数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ List<DtLocVo> recentLoc(String areaId, String startDate, String endDate); /** * 定期统计剩余库存 * */ void locNumCount(); } src/main/java/com/zy/asrs/service/MesService.java
New file @@ -0,0 +1,154 @@ package com.zy.asrs.service; import com.alibaba.fastjson.JSONObject; import com.core.common.R; import com.zy.asrs.entity.mes.*; import com.zy.asrs.entity.rcs.RcsReporterTask; import java.text.ParseException; public interface MesService { // /** // * 物料信息同步 // * // * @param matRecvForm // * @return // */ // MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm); /** * 新增、修改物料信息 * * @param mesMatInfo * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败; * @throws ParseException */ int synMatInfo(MesMatInfo mesMatInfo); /** * 实际入库反馈 * 触发条件:针对原料出库检查再入库的情况 * 推送时机:当所有货物都入库时推送 * * @param orderNo * @return */ int recvFeedback(String orderNo); /** * 出库申请 * * @param mesOutApply * @return */ int outBoundOrder(MesInApply mesOutApply); /** * 出库申请(叫料),齐套性配盘 * * @param mesCallOutApply * @return */ int callOutBoundOrder(MesCallOutApply mesCallOutApply); /** * 出库完成 * * @param orderNo * @return */ int outFeedback(String orderNo); /** * 入库完成 * * @param orderNo * @return */ int inFeedback(String orderNo); /** * 入库申请 * * @param mesInApply * @return */ int inBoundOrder(MesInApply mesInApply, int check); int transDj(String taskNo,String djNo); /** * 9.1下发运输任务 * * @param transTask * @return */ JSONObject submitTask(TransTask transTask); /** * 9.2返回任务执行结果 * * @param rcsReporterTask * @return */ int reporterTask(RcsReporterTask rcsReporterTask); /** * 9.8申请华晓AGV进入生产线 * * @param apply * @return */ String applyInLine(TransParent apply); /** * 入站请求:转发AGV->入站请求->给MES * * @param apply * @return */ int applyInStation(TransParent apply); /** * 入站允许:转发MES->允许入站->给AGV * * @param allow * @return */ MesReturn allowInStation(TransInOutStationAllow allow); /** * 到站完成:转发AGV->到站完成->给MES * * @param arrivalStation * @return */ int arriveOnStation(TransArrivalStation arrivalStation,String path); /** * 离站请求:转发AGV->离站请求->给MES * * @param apply * @return */ int applyOutStation(TransParent apply); /** * 离站允许:转发MES->允许离站->给AGV * * @param allow * @return */ MesReturn allowOutStation(TransInOutStationAllow allow); /** * 离站完成:转发AGV->离站完成->给MES * * @param apply * @return */ int outStation(TransParent apply); R tkt(String taskNo); } src/main/java/com/zy/asrs/service/RcsService.java
New file @@ -0,0 +1,66 @@ package com.zy.asrs.service; import com.alibaba.fastjson.JSONObject; import com.zy.asrs.entity.mes.TransInOutStationAllow; import com.zy.asrs.entity.mes.TransParent; import com.zy.asrs.entity.rcs.*; public interface RcsService { /** * 管理封锁区进入 * */ void managerBlock(); /** * 2.1.2任务下发接口 * * @param rcsTaskSubmit * @param rcsFactory 1 海康;2 华晓; * @return */ int submitTask(RcsTaskSubmit rcsTaskSubmit, int rcsFactory); /** * 2.1.3任务继续执行接口 * * @param rcsTaskContinue * @param rcsFactory * @return */ int continueTask(RcsTaskContinue rcsTaskContinue, int rcsFactory); /** * 2.1.4任务取消接口 * * @param rcsTaskCancel * @param rcsFactory * @return */ int cancelTask(RcsTaskCancel rcsTaskCancel, int rcsFactory); /** * 2.2.1任务执行回馈 * * @param rcsReporterTask * @return */ RcsReturn reporterTask(RcsReporterTask rcsReporterTask); /** * 2.2.4请求外设接口,请求封锁区 * * @param rcsReporterEqpt * @return */ RcsReturn reporterEqpt(RcsReporterEqpt rcsReporterEqpt); /** * 9.7申请进入生产线 * * @param apply * @return */ JSONObject hxApplyInLine(TransParent apply); } src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java
New file @@ -0,0 +1,272 @@ package com.zy.asrs.service.impl; import com.zy.asrs.entity.LocCount; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.digitaltwin.*; import com.zy.asrs.mapper.DigitalTwinMapper; import com.zy.asrs.mapper.LocCountMapper; import com.zy.asrs.service.DigitalTwinService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @Service public class DigitalTwinServiceImpl implements DigitalTwinService { @Resource private DigitalTwinMapper digitalTwinMapper; @Resource private LocCountMapper locCountMapper; /** * 总览:总库位、已用库位、剩余库位、今日出库、今日入库、剩余库位 * * @param areaId * @return */ public DtOverviewVo overview(String areaId) { List<Double> dbOverview = digitalTwinMapper.overview(areaId); if (dbOverview != null && !dbOverview.isEmpty()){ DtOverviewVo dtOverviewVo = DtOverviewVo.builder() .totalLoc((int)Math.round(dbOverview.get(0))) .useLoc((int)Math.round(dbOverview.get(1))) .remainingStock((int)Math.round(dbOverview.get(2))) .todayWarehousing((int)Math.round(dbOverview.get(3))) .todayOutbound((int)Math.round(dbOverview.get(4))) .build(); dtOverviewVo.setIdleLoc(dtOverviewVo.getTotalLoc() - dtOverviewVo.getUseLoc()); return dtOverviewVo; } return DtOverviewVo.builder().build(); } /** * 近期订单,默认7天 * * @param startDate * @param endDate * @return */ public List<DtOrderVo> order(String startDate, String endDate) { String startTime; String endTime; if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); Date start = calendar.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); endDate = sdf.format(now); startDate = sdf.format(start); } startTime = startDate.substring(0, 4) + "-" + startDate.substring(4, 6) + "-" + startDate.substring(6, 8) + "00:00:00"; endTime = endDate.substring(0, 4) + "-" + endDate.substring(4, 6) + "-" + endDate.substring(6, 8) + "00:00:00"; List<DtOrderVo> dbOrder = digitalTwinMapper.recentOrder(startTime, endTime); // 空日期补全 return dbOrder; } /** * 近期出库、入库数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ public List<DtInAndOutBoundVo> inAndOutBound(String areaId, String startDate, String endDate) { List<DtInAndOutBoundVo> dtInAndOutBoundVos = new ArrayList<>(); String startTime; String endTime; if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); Date start = calendar.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); endDate = sdf.format(now); startDate = sdf.format(start); } startTime = startDate.substring(0, 4) + "-" + startDate.substring(4, 6) + "-" + startDate.substring(6, 8) + "00:00:00"; endTime = endDate.substring(0, 4) + "-" + endDate.substring(4, 6) + "-" + endDate.substring(6, 8) + "00:00:00"; List<DtInAndOutBoundVo> dtInBoundVos = digitalTwinMapper.recentInBound(areaId, startTime, endTime); List<DtInAndOutBoundVo> dtOutBoundVos = digitalTwinMapper.recentOutBound(areaId, startTime, endTime); // 格式整理 return dtInAndOutBoundVos; } /** * 近期近期呆滞品信息,默认超过30天为呆滞品 * * @param areaId * @param overDayNum * @param pageIndex * @param pageSize * @return */ public List<DtDetainMatVo> recentDetainMat(String areaId, Integer overDayNum, Integer pageIndex, Integer pageSize) { overDayNum = overDayNum == null ? 30 : overDayNum; pageIndex = pageIndex == null ? 1 : pageIndex; pageSize = pageSize == null ? 1000000 : pageSize; Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -overDayNum); Date start = calendar.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String startTime = sdf.format(start); List<DtDetainMatVo> dbDetainMats = digitalTwinMapper.recentDetainMat(areaId, startTime, pageIndex, pageSize); return dbDetainMats; } /** * 查询库存和库位详细信息 * * @param areaId * @return */ public List<DtLocDetailVo> warehouseDetail(String areaId) { List<DtLocDetailVo> locDetailVos = new ArrayList<>(); List<LocMast> locMasts = new ArrayList<>(); List<LocDetl> locDetls = new ArrayList<>(); for (LocMast locMast : locMasts) { DtLocDetailVo dtLocDetailVo = new DtLocDetailVo(); dtLocDetailVo.setLocMast(locMast); dtLocDetailVo.setLocNo(locMast.getLocNo()); dtLocDetailVo.setLocSts(locMast.getLocSts()); dtLocDetailVo.setRow1(locMast.getRow1()); dtLocDetailVo.setBay1(locMast.getBay1()); dtLocDetailVo.setLev1(locMast.getLev1()); for (LocDetl locDetl : locDetls) { List<LocDetl> locDetl1 = locDetls.parallelStream().filter(a -> a.getLocNo().equals(locDetl.getLocNo())).collect(Collectors.toList()); if (locDetl1 != null && locDetl1.size() == 1) { dtLocDetailVo.setLocDetl(locDetl1.get(0)); dtLocDetailVo.setAreaId(locDetl.getAreaId()); dtLocDetailVo.setAreaName(locDetl.getAreaName()); } } locDetailVos.add(dtLocDetailVo); } return locDetailVos; } /** * 近期剩余库位数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ public List<DtLocVo> recentLoc(String areaId, String startDate, String endDate) { List<DtLocVo> locVos = new ArrayList<>(); if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); Date start = calendar.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); endDate = sdf.format(now); startDate = sdf.format(start); } List<LocCount> locCounts; if(areaId.isEmpty()){ locCounts = locCountMapper.getByDate(Integer.parseInt(startDate), Integer.parseInt(endDate)); } else { locCounts = locCountMapper.getByAreaAndDate(areaId, Integer.parseInt(startDate), Integer.parseInt(endDate)); } for (LocCount locCount : locCounts) { String date = locCount.getDate().toString(); String locDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8); DtLocVo dtLocVo = DtLocVo.builder() .locDate(locDate) .idleNum(locCount.getRemainNum()) .build(); locVos.add(dtLocVo); } return locVos; } /** * 定期统计剩余库存 * */ public void locNumCount() { List<LocCount> result = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String date = sdf.format(new Date()); List<LocCount> totalLoc = locCountMapper.totalLoc(); List<LocCount> useLoc = locCountMapper.useLoc(); for (LocCount locCount : totalLoc) { LocCount locCount1 = new LocCount(); locCount1.setDate(Integer.valueOf(date)); locCount1.setAreaId(locCount.getAreaId()); locCount1.setLocNum(locCount1.getLocNum()); for (LocCount locCount2 : useLoc) { if(locCount1.getAreaId().equals(locCount2.getAreaId())){ locCount1.setRemainNum(locCount1.getLocNum() - locCount2.getLocNum()); } } result.add(locCount1); } for (LocCount locCount : result) { locCountMapper.insertOrUpdate(locCount); } } // region 数字孪生 // 数字孪生整合 // 机器状态整合 // endregion // region 立库调度 // 堆垛机存取 // 输送线拍照、称重 // endregion } src/main/java/com/zy/asrs/service/impl/MatServiceImpl.java
@@ -23,7 +23,8 @@ } @Override public Page<Mat> getPage2(Page page, String tagId, Object matnr, Object maktx, Object specs) { return page.setRecords(baseMapper.listByPage2(page, tagId, matnr, maktx, specs)); return page.setRecords(baseMapper.listByPage2(page, "1".equals(tagId) ? "2" : tagId, matnr, maktx, specs)); } src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java
New file @@ -0,0 +1,1090 @@ package com.zy.asrs.service.impl; import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.R; import com.core.common.SnowflakeIdWorker; import com.core.exception.CoolException; import com.zy.asrs.entity.*; import com.zy.asrs.entity.mes.*; import com.zy.asrs.entity.param.CombParam; import com.zy.asrs.entity.rcs.*; import com.zy.asrs.mapper.AgvInfoMapper; import com.zy.asrs.service.*; import com.zy.common.model.enums.WorkNoType; import com.zy.common.service.CommonService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.text.ParseException; import java.time.OffsetDateTime; import java.util.*; import java.util.stream.Collectors; @Slf4j @Service public class MesServiceImpl implements MesService { @Value("${mes.url}") public String MES_URL; @Value("${dj.url}") public String DJ_URL; @Value("${wms.currentName}") public String WMS_CURRENT_NAME; @Value("${mes.defaultUserId}") public long defaultUserId; @Value("${wms.wmsTransStartStation1}") public String WMS_TRANS_START_STATION_1; @Resource private RcsService rcsService; @Resource private MatService matService; @Resource private TagService tagService; @Resource private OrderPakinService orderPakinService; @Resource private OrderDetlPakinService orderDetlPakinService; @Resource private OrderPakoutService orderPakoutService; @Resource private OrderDetlPakoutService orderDetlPakoutService; @Resource private MobileService mobileService; @Resource private WaitPakinService waitPakinService; @Resource private TaskService taskService; @Resource private TaskDetlService taskDetlService; @Resource private SnowflakeIdWorker snowflakeIdWorker; @Resource private CommonService commonService; @Resource private AgvInfoMapper agvInfoMapper; // region MES接口 // /** // * 物料信息同步,MES->WMS // * 同步物料信息->入库单 // * // * @param matRecvForm // * @return // */ // @Transactional(rollbackFor = Exception.class) // public MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm) { // // MesReturn mesReturn = new MesReturn(); // // // 1、物料信息同步 // try { // if (synMatInfo(matRecvForm.getItemdata()) == 1) { // // 2、生成入库单 // try { // MesInApply mesInApply = new MesInApply(); // mesInApply.setItemno(matRecvForm.getItemdata().getItem_no()); // mesInApply.setQty(matRecvForm.getItemdata().getQty()); // mesInApply.setOrderNo(matRecvForm.getItemdata().getOrderNo()); // if (inBoundOrder(mesInApply, 1) == 1) { // mesReturn.setSuccess("1"); // } else { // mesReturn.setSuccess("2"); // mesReturn.setMessage("生成入库订单失败"); // } // } catch (Exception e) { // mesReturn.setSuccess("2"); // mesReturn.setMessage("生成入库订单失败"); // log.error("MES物料信息同步接口,生成入库订单错误", e); // } // } else { // mesReturn.setSuccess("2"); // mesReturn.setMessage("同步物料信息失败"); // } // } catch (Exception e) { // mesReturn.setSuccess("2"); // mesReturn.setMessage("同步物料信息失败"); // log.error("MES物料信息同步接口,同步物料错误", e); // } // // return mesReturn; // } /** * 新增、修改物料信息 * * @param mesMatInfo * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败; * @throws ParseException */ public int synMatInfo(MesMatInfo mesMatInfo) { try { // 规则定义:默认第3层为同步的物料类型 long secondPath = 2; String secondParentName = WMS_CURRENT_NAME; // long locType = 1; long userId = defaultUserId; // if (mesMatInfo.getModified_operator1() != null && !mesMatInfo.getModified_operator1().isEmpty()) { // userId = Long.parseLong(mesMatInfo.getModified_operator1()); // } Date now = new Date(); if (mesMatInfo.getModified_date1() != null && !mesMatInfo.getModified_date1().isEmpty()) { now = Date.from(OffsetDateTime.parse(mesMatInfo.getModified_date1()).toInstant()); } // 物料类型更新 EntityWrapper<Tag> wrapper = new EntityWrapper<>(); wrapper.eq("name", mesMatInfo.getItem_type()); Tag tag = tagService.selectByName(mesMatInfo.getItem_type(), 3); if (tag == null || StringUtils.isEmpty(tag.getName())) { Tag newTag = new Tag(); newTag.setName(mesMatInfo.getItem_type()); newTag.setParentId(secondPath); newTag.setParentName(secondParentName); newTag.setPath("2"); newTag.setPathName(secondParentName); newTag.setLevel(3); newTag.setStatus(1); newTag.setCreateBy(userId); newTag.setCreateTime(now); newTag.setUpdateBy(userId); newTag.setUpdateTime(now); if (!tagService.insert(newTag)) return -1; } // 物料更新 long tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId(); Mat mat = matService.selectByMatnr(mesMatInfo.getItem_no()); Mat newMat = new Mat(); newMat.setMatnr(mesMatInfo.getItem_no()); newMat.setMaktx(mesMatInfo.getDescription()); newMat.setTagId(tagId); newMat.setLocType(tagId); //locType newMat.setSpecs(mesMatInfo.getSpecification()); newMat.setUnit("件"); //统一为件,mesMatInfo.getUnit_of_measure() newMat.setModel(mesMatInfo.getClassification_code()); newMat.setMemo(JSONObject.toJSONString(mesMatInfo)); newMat.setCreateBy(userId); newMat.setCreateTime(now); newMat.setUpdateBy(userId); newMat.setUpdateTime(now); newMat.setStatus(1); if (mat == null) { if (!matService.insert(newMat)) return -2; } else { JSONObject dbMemo = JSONObject.parseObject(mat.getMemo()); // dbMemo.remove("OrderNo"); // dbMemo.remove("qty"); JSONObject newMemo = JSONObject.parseObject(newMat.getMemo()); // newMemo.remove("OrderNo"); // newMemo.remove("qty"); if (!dbMemo.equals(newMemo)) { newMat.setId(mat.getId()); if (!matService.updateById(newMat)) return -2; } } return 1; } catch (Exception e) { log.error("同步物料失败", e); return -1; } } /** * 实际入库反馈 * 触发条件:针对原料出库检查再入库的情况 * 推送时机:当订单完成时推送 * * @param orderNo * @return */ public int recvFeedback(String orderNo) { // 按单号查询 OrderPakin order = orderPakinService.selectByNo(orderNo); if (order != null && order.getSettle() == 4) { // 校验是否完成 // List<MesRecvFeedback.MesRecvFeedbackItem> list = new ArrayList<>(); JSONObject dbMemo = JSONObject.parseObject(order.getMemo()); List<MesItemDetails> details = new ArrayList<>(); EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper); if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) { for (OrderDetlPakin orderDetl : orderDetlPakins) { int qty = Integer.parseInt(dbMemo.getString("qty")); double real_qty = Double.parseDouble(orderDetl.getQty().toString()); MesItemDetails detail = new MesItemDetails(); detail.setItemNo(orderDetl.getMatnr()); detail.setAnfme(real_qty); details.add(detail); // MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem(); // item.setItem_no(orderDetl.getMatnr()); // item.setOrderNo(orderNo); // item.setQty(qty); // item.setReal_qty(real_qty); // list.add(item); } } // MesRecvFeedback mesRecvFeedback = new MesRecvFeedback(); // mesRecvFeedback.setSource_no(dbMemo.getString("source_no")); // mesRecvFeedback.setOperuser(dbMemo.getString("operuser")); // mesRecvFeedback.setItemdata(list); MesInApply mesRecvFeedback = new MesInApply(); mesRecvFeedback.setBillType(dbMemo.getString("billType")); mesRecvFeedback.setOrderNo(dbMemo.getString("orderNo")); mesRecvFeedback.setCreateTime(dbMemo.getString("createTime")); mesRecvFeedback.setDetails(details); String url = DJ_URL + "api/InboundOrder/WmsInFinish"; String response = RcsServiceImpl.sendPost(url, mesRecvFeedback.toString()); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } } return 0; } /** * 出库申请 * 加工库、刀具库 * * @param mesOutApply * @return 1 成功;-1 订单重复; */ public int outBoundOrder(MesInApply mesOutApply){ // docType根据库类型确定 long docType = 7; long settle = 1; // 校验订单是否重复 OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { return -1; } // 生成订单 Date now = new Date(); OrderPakout orderPakout = new OrderPakout(); orderPakout.setUuid( String.valueOf(snowflakeIdWorker.nextId())); orderPakout.setOrderNo(mesOutApply.getOrderNo()); orderPakout.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakout.setDocType(docType); orderPakout.setSettle(settle); orderPakout.setStatus(1); orderPakout.setCreateBy(defaultUserId); orderPakout.setCreateTime(now); orderPakout.setUpdateBy(defaultUserId); orderPakout.setUpdateTime(now); orderPakout.setMemo(JSONObject.toJSONString(mesOutApply)); orderPakout.setPakinPakoutStatus(2); if (!orderPakoutService.insert(orderPakout)) { log.error("MES保存出库订单主档失败"); throw new CoolException("保存出库订单主档失败"); } // 生成明细 for (MesItemDetails item : mesOutApply.getDetails()) { Mat mat = matService.selectByMatnr(item.getItemNo()); OrderDetlPakout orderDetlPakout = new OrderDetlPakout(); orderDetlPakout.setOrderId(orderPakout.getId()); orderDetlPakout.setOrderNo(orderPakout.getOrderNo()); orderDetlPakout.setAnfme(Double.valueOf(item.getAnfme())); orderDetlPakout.setQty(0.0); orderDetlPakout.setMatnr(mat.getMatnr()); orderDetlPakout.setMaktx(mat.getMaktx()); orderDetlPakout.setSpecs(mat.getSpecs()); orderDetlPakout.setModel(mat.getModel()); orderDetlPakout.setCreateBy(defaultUserId); orderDetlPakout.setCreateTime(now); orderDetlPakout.setUpdateBy(defaultUserId); orderDetlPakout.setUpdateTime(now); orderDetlPakout.setStatus(1); orderDetlPakout.setPakinPakoutStatus(2); if (!orderDetlPakoutService.insert(orderDetlPakout)) { log.error("MES保存出库订单明细档失败"); throw new CoolException("保存出库订单明细档失败"); } } // TODO:CTU出库动作 // todo 呼叫agv产线取空料架 // TODO:若AGV和输送线没有安全交互,则要保证立库出货完成后再呼叫AGV。 // 立库生成订单后,自动调度AGV从产线运输空刀架至立库缓存区。 try { if (!StringUtils.isEmpty(mesOutApply.getTaskNo()) && !StringUtils.isEmpty(mesOutApply.getStationId())) { TransTask transTask = new TransTask(); transTask.setTaskno(mesOutApply.getTaskNo()); // transTask.setTaskname(mesOutApply.getTaskname()); transTask.setOrderNo(mesOutApply.getOrderNo()); transTask.setTransType("02"); //运回刀架时默认02(下空托) mesOutApply.getTransType() transTask.setCurProcess(mesOutApply.getProductLineId()); transTask.setCurStationId(mesOutApply.getStationId()); // transTask.setNextProcess(); transTask.setNextStationId(WMS_TRANS_START_STATION_1); // transTask.setItemno(mesOutApply.getItemNo()); transTask.setQty(0); transTask.setProductLineId(mesOutApply.getProductLineId()); // transTask.setItemBarcode(codes); // transTask.setTuoPanId(entry.getKey()); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask)); } // // 按零件二维码查询有几个托,多托生成多个任务,每托对应零件二维码 //// String barCode = barCodeListToStr(mesOutApply.getItemBarcode()); // EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>(); // matItemBarcodeEntityWrapper.in("item_barcode", barCode); // List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper); // if (barcodes != null) { // Map<String, List<MatItemBarcode>> map = barcodes.stream().collect(Collectors.groupingBy(MatItemBarcode::getZapplet)); // for (Map.Entry<String, List<MatItemBarcode>> entry : map.entrySet()) { // List<MatItemBarcode> list = entry.getValue(); // List<String> codes = new ArrayList<>(); // for (MatItemBarcode zapllet : list) { // codes.add(zapllet.getItemBarcode()); // } // // // } // } } } catch (Exception e) { log.error("下发AGV运输任务失败", e); } return 1; } public int transDj(String taskNo,String djNo) { try { EntityWrapper<Task> wapper = new EntityWrapper<>(); wapper.eq("task_no", taskNo).orderBy("wrk_date"); Task task = taskService.selectOne(wapper); if (task != null) { JSONObject memo = JSONObject.parseObject(task.getMemo()); TransTask transTask = new TransTask(); transTask.setTaskno(taskNo + "_1"); // transTask.setTaskname(mesOutApply.getTaskname()); transTask.setOrderNo(memo.getString("OrderNo")); transTask.setTransType("05"); //送刀时默认05(上刀) transTask.setCurStationId(WMS_TRANS_START_STATION_1); transTask.setNextProcess(memo.getString("ProductLineId")); transTask.setNextStationId(memo.getString("CurStationId")); // transTask.setItemno(mesOutApply.getItemNo()); // transTask.setQty(0); transTask.setProductLineId(memo.getString("ProductLineId")); // transTask.setItemBarcode(codes); // transTask.setTuoPanId(entry.getKey()); transTask.setOperateType(1); transTask.setAgvFactory(1); transTask.setDjNo(djNo); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("上刀下发agv运输任务失败", JSONObject.toJSONString(transTask)); } } } catch (Exception e) { log.error("上刀下发AGV运输任务失败", e); } return 1; } /** * 入库申请 * * @param mesInApply * @return 1 成功;-1 入库订单重复;0 部分失败; */ public int inBoundOrder(MesInApply mesInApply, int check){ // docType根据库类型确定 long docType = 4; long settle = 1; // 校验订单是否重复 OrderPakin order = orderPakinService.selectByNo(mesInApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { return -1; } // 生成订单 Date now = new Date(); OrderPakin orderPakin = new OrderPakin(); orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId())); orderPakin.setOrderNo(mesInApply.getOrderNo()); orderPakin.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakin.setDocType(docType); orderPakin.setSettle(settle); orderPakin.setStatus(1); orderPakin.setCreateBy(defaultUserId); orderPakin.setCreateTime(now); orderPakin.setUpdateBy(defaultUserId); orderPakin.setUpdateTime(now); orderPakin.setMemo(JSONObject.toJSONString(mesInApply)); //为出库完成反馈保存 orderPakin.setPakinPakoutStatus(1); if (!orderPakinService.insert(orderPakin)) { log.error("MES保存入库订单主档失败"); throw new CoolException("保存入库订单主档失败"); } // 生成明细 for (MesItemDetails item : mesInApply.getDetails()) { Mat mat = matService.selectByMatnr(item.getItemNo()); OrderDetlPakin orderDetlPakin = new OrderDetlPakin(); orderDetlPakin.setOrderId(orderPakin.getId()); orderDetlPakin.setOrderNo(orderPakin.getOrderNo()); orderDetlPakin.setAnfme(Double.valueOf(item.getAnfme())); orderDetlPakin.setQty(0.0); orderDetlPakin.setMatnr(mat.getMatnr()); orderDetlPakin.setMaktx(mat.getMaktx()); orderDetlPakin.setSpecs(mat.getSpecs()); orderDetlPakin.setModel(mat.getModel()); // if (mesInApply.getDetails() != null) { // orderDetlPakin.setStandby1(JSONObject.toJSONString(mesInApply.getProductInfo())); //零件详情存在备选1 // } orderDetlPakin.setStandby2(String.valueOf(check)); //保存齐套性检查标识,1 检查;0 不检查; orderDetlPakin.setCreateBy(defaultUserId); orderDetlPakin.setCreateTime(now); orderDetlPakin.setUpdateBy(defaultUserId); orderDetlPakin.setUpdateTime(now); orderDetlPakin.setStatus(1); orderDetlPakin.setPakinPakoutStatus(1); if (!orderDetlPakinService.insert(orderDetlPakin)) { log.error("MES保存入库订单明细档失败1"); throw new CoolException("保存入库订单明细档失败1"); } } // // TODO:是否绑定货物和托盘? // if (!StringUtils.isEmpty(mesInApply.getTuoPanId())) { // CombParam combParam = new CombParam(); // combParam.setOrderNo(mesInApply.getOrderNo()); // combParam.setBarcode(mesInApply.getTuoPanId()); // List<CombParam.CombMat> combMats = new ArrayList<>(); // CombParam.CombMat combMat = new CombParam.CombMat(); // combMat.setOrderNo(mesInApply.getOrderNo()); // combMat.setMatnr(mat.getMatnr()); // combMat.setMaktx(mat.getMaktx()); // combMat.setSpecs(mat.getSpecs()); // combMat.setAnfme(Double.valueOf(mesInApply.getQty())); //// combMat.setBatch("1"); // combMats.add(combMat); // combParam.setCombMats(combMats); // // 组托 // mobileService.comb(combParam, defaultUserId); // } return 1; } /** * 出库申请(叫料) * 装配库、滑块库 * * @param mesCallOutApply * @return */ public int callOutBoundOrder(MesCallOutApply mesCallOutApply){ // docType根据库类型确定 long docType = 7; long settle = 1; // 校验订单是否重复 OrderPakout order = orderPakoutService.selectByNo(mesCallOutApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { return -1; } // 生成订单 Date now = new Date(); OrderPakout orderPakout = new OrderPakout(); orderPakout.setUuid(String.valueOf(snowflakeIdWorker.nextId())); orderPakout.setOrderNo(mesCallOutApply.getOrderNo()); orderPakout.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakout.setDocType(docType); orderPakout.setSettle(settle); orderPakout.setStatus(1); orderPakout.setCreateBy(defaultUserId); orderPakout.setCreateTime(now); orderPakout.setUpdateBy(defaultUserId); orderPakout.setUpdateTime(now); orderPakout.setMemo(JSONObject.toJSONString(mesCallOutApply)); orderPakout.setPakinPakoutStatus(2); if (!orderPakoutService.insert(orderPakout)) { log.error("MES保存出库订单(叫料)主档失败"); throw new CoolException("保存出库订单(叫料)主档失败"); } // 生成明细 if (mesCallOutApply.getItemdata() != null && !mesCallOutApply.getItemdata().isEmpty()) { for (MesCallOutApply.MesOutApplyItem mesOutApplyItem : mesCallOutApply.getItemdata()) { Mat mat = matService.selectByMatnr(mesOutApplyItem.getItemno()); OrderDetlPakout orderDetlPakout = new OrderDetlPakout(); orderDetlPakout.setOrderId(orderPakout.getId()); orderDetlPakout.setOrderNo(orderPakout.getOrderNo()); orderDetlPakout.setAnfme(Double.valueOf(mesOutApplyItem.getQty())); orderDetlPakout.setQty(0.0); orderDetlPakout.setMatnr(mat.getMatnr()); orderDetlPakout.setMaktx(mat.getMaktx()); orderDetlPakout.setSpecs(mat.getSpecs()); orderDetlPakout.setModel(mat.getModel()); orderDetlPakout.setThreeCode(mesOutApplyItem.getItemBarcode()); orderDetlPakout.setStandby1(mesOutApplyItem.getTrayid()); //保存配盘号,非托盘号 orderDetlPakout.setCreateBy(defaultUserId); orderDetlPakout.setCreateTime(now); orderDetlPakout.setUpdateBy(defaultUserId); orderDetlPakout.setUpdateTime(now); orderDetlPakout.setStatus(1); orderDetlPakout.setPakinPakoutStatus(2); if (!orderDetlPakoutService.insert(orderDetlPakout)) { log.error("MES保存出库订单(叫料)明细档失败"); throw new CoolException("保存出库订单(叫料)明细档失败"); } } } return 1; } /** * 出库完成 * * @param orderNo * @return */ public int outFeedback(String orderNo) { int success = 0; OrderPakout order = orderPakoutService.selectByNo(orderNo); if (order != null && order.getSettle() == 4) { // 校验是否完成 List<MesItemDetails> details = new ArrayList<>(); JSONObject dbMemo = JSONObject.parseObject(order.getMemo()); EntityWrapper<OrderDetlPakout> wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List<OrderDetlPakout> orderDetlPakouts = orderDetlPakoutService.selectList(wrapper); if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) { for (OrderDetlPakout orderDetl : orderDetlPakouts) { double real_qty = Double.parseDouble(orderDetl.getQty().toString()); MesItemDetails detail = new MesItemDetails(); detail.setItemNo(orderDetl.getMatnr()); detail.setAnfme(real_qty); details.add(detail); // StringBuilder palletId = new StringBuilder(); // EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>(); // wrapper2.eq("order_no", orderDetl.getOrderNo()); // List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2); // for (WaitPakin waitPakin : waitPakins) { // palletId.append(waitPakin.getZpallet()).append(","); // } // // MesOutFeedback mesOutFeedback = new MesOutFeedback(); // mesOutFeedback.setTaskno(dbMemo.getString("taskno")); // mesOutFeedback.setTaskname(dbMemo.getString("taskname")); // mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId")); // mesOutFeedback.setStationId(dbMemo.getString("StationID")); // mesOutFeedback.setItemno(orderDetl.getMatnr()); // if (!StringUtils.isEmpty(palletId.toString())) { // mesOutFeedback.setTuoPanId(palletId.substring(0, palletId.length() - 1)); // } // mesOutFeedback.setQty(Integer.parseInt(orderDetl.getQty().toString())); // mesOutFeedback.setItemBarcode(dbMemo.getString("ItemBarcode")); // mesOutFeedback.setOrderNo(orderNo); } MesInApply mesOutFeedback = new MesInApply(); mesOutFeedback.setBillType(dbMemo.getString("billType")); mesOutFeedback.setOrderNo(dbMemo.getString("orderNo")); mesOutFeedback.setCreateTime(dbMemo.getString("createTime")); mesOutFeedback.setDetails(details); String url = DJ_URL + "api/OutboundOrder/WmsOutFinish"; String response = RcsServiceImpl.sendPost(url, mesOutFeedback.toString()); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success++; } } if (success == orderDetlPakouts.size()) { success = 1; } else { success = 0; } } } return success; } /** * 入库完成 * * @param orderNo * @return */ public int inFeedback(String orderNo) { int success = 0; int recvFeedback = 0; OrderPakin order = orderPakinService.selectByNo(orderNo); if (order != null && order.getSettle() == 4) { // 校验是否完成 EntityWrapper<OrderDetlPakin> wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(wrapper); if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) { for (OrderDetlPakin orderDetl : orderDetlPakins) { MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class); // result.setAnfme(Float.parseFloat(orderDetl.getAnfme().toString())); String url = MES_URL + "api/order/inComplete"; String response = RcsServiceImpl.sendPost(url, result.toString()); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success++; } } if ("1".equals(orderDetl.getStandby2())) { recvFeedback++; } } // 入库回馈 if (recvFeedback > 0) { recvFeedback(orderNo); } if (success == orderDetlPakins.size()) { success = 1; } else { success = 0; } } } return success; } // endregion // region 搬运任务调度 // route转发3个WCS任务 /** * 9.1下发运输任务 * TODO:其他库的任务全部转到滑块库统一调度 * * @param transTask * @return */ @Transactional public JSONObject submitTask(TransTask transTask) { JSONObject result = new JSONObject(); result.put("taskno", transTask.getTaskno()); // 重复性校验 EntityWrapper<Task> wrapper = new EntityWrapper<>(); wrapper.eq("task_no", transTask.getTaskno()); List<Task> tasks = taskService.selectList(wrapper); if (tasks != null && !tasks.isEmpty()) { result.put("Success", "2"); result.put("Message", "任务重复发送"); return result; } try { int workNo = commonService.getWorkNo(WorkNoType.OTHER.type); Date now = new Date(); Task task = new Task(); task.setWrkNo(workNo); task.setTaskType("AGV"); task.setWrkSts(301L); task.setIoType(3); task.setIoPri(10.00); task.setWrkDate(now); task.setStaNo(transTask.getNextStationId()); task.setSourceStaNo(transTask.getCurStationId()); task.setModiUser(defaultUserId); task.setModiTime(now); task.setAppeUser(defaultUserId); task.setAppeTime(now); task.setTaskNo(transTask.getTaskno()); task.setMemo(JSONObject.toJSONString(transTask)); if (taskService.insert(task)) { Mat mat = matService.selectByMatnr("emptyDj"); TaskDetl taskDetl = new TaskDetl(); taskDetl.setWrkNo(task.getWrkNo()); taskDetl.setIoTime(task.getIoTime()); taskDetl.setMatnr(mat.getMatnr()); taskDetl.setAnfme(0.0); taskDetl.setStandby1(String.valueOf(transTask.getQty())); taskDetl.setMaktx(mat.getMaktx()); taskDetl.setSpecs(mat.getSpecs()); taskDetl.setOrderNo(transTask.getOrderNo()); taskDetl.setModiUser(defaultUserId); taskDetl.setModiTime(now); taskDetl.setAppeUser(defaultUserId); taskDetl.setAppeTime(now); taskDetlService.insert(taskDetl); // EntityWrapper<WaitPakin> wrapper1 = new EntityWrapper<>(); // wrapper1.eq("order_no", transTask.getTaskno()) // .eq("matnr", mat.getMatnr()) // .eq("anfme", transTask.getQty()); // WaitPakin waitPakin = waitPakinService.selectOne(wrapper1); // if (waitPakin != null) // { // TaskDetl taskDetl = new TaskDetl(); // taskDetl.setWrkNo(task.getWrkNo()); // taskDetl.setIoTime(task.getIoTime()); // taskDetl.setMatnr(transTask.getItemno()); // taskDetl.setAnfme(Double.valueOf(transTask.getQty())); // taskDetl.setAnfme(0.0); // taskDetl.setStandby1(String.valueOf(transTask.getQty())); // taskDetl.setZpallet(waitPakin.getZpallet()); // taskDetl.setMaktx(mat.getMaktx()); // taskDetl.setSpecs(mat.getSpecs()); // taskDetl.setOrderNo(transTask.getOrderNo()); // taskDetl.setModiUser(defaultUserId); // taskDetl.setModiTime(now); // taskDetl.setAppeUser(defaultUserId); // taskDetl.setAppeTime(now); // taskDetlService.insert(taskDetl); // } // else { // result.put("Success", "2"); // result.put("Message", "接收任务失败"); // // Throw // } // 下发给RCS RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit(); rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno()); rcsTaskSubmit.setInitPriority(10); //默认10 List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>(); RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute(); startRoute.setSeq(0); startRoute.setCode(transTask.getCurStationId()); startRoute.setOperation("COLLECT"); targetRouteList.add(startRoute); RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute(); endRoute.setSeq(1); endRoute.setCode(transTask.getNextStationId()); endRoute.setOperation("DELIVERY"); targetRouteList.add(endRoute); rcsTaskSubmit.setTargetRoute(targetRouteList); // 转发给海康或华晓RCS int success = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory()); if (success == 1) { result.put("Success", "1"); result.put("Message", "任务接收成功"); } else { result.put("Success", "2"); result.put("Message", "任务下发给RCS失败"); } } else { result.put("Success", "2"); result.put("Message", "接收任务失败"); } } catch (Exception e) { log.error("下发运输任务错位 - {}", transTask, e); } return result; } /** * 9.2返回任务执行结果 * * @param rcsReporterTask * @return */ public int reporterTask(RcsReporterTask rcsReporterTask) { // 结果汇总 boolean completed = true; EntityWrapper<Task> wrapper = new EntityWrapper<>(); wrapper.eq("task_no", rcsReporterTask.getRobotTaskCode()); List<Task> tasks = taskService.selectList(wrapper); if (tasks != null && !tasks.isEmpty()) { for (Task task : tasks) { if (task.getWrkSts() != 304) { // TODO:确认完成,可能存在多盘任务 completed = false; } } } if (completed) { TransTaskFeedback transTaskFeedback = new TransTaskFeedback(); transTaskFeedback.setTaskno(rcsReporterTask.getRobotTaskCode()); // transTaskFeedback.setTaskname(); transTaskFeedback.setResult(1); String url = MES_URL + "api/task/reporter"; String response = RcsServiceImpl.sendPost(url, transTaskFeedback.toString()); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } } return 0; } /** * 9.8申请华晓AGV进入生产线 * * @param apply * @return */ public String applyInLine(TransParent apply) { String url = MES_URL + "api/apply/inLine"; String response = RcsServiceImpl.sendPost(url, apply.toString()); if (!StringUtils.isEmpty(response) && response.contains("Success")){ JSONObject jsonObject = JSONObject.parseObject(response); if("1".equals(jsonObject.getString("Success"))) { return jsonObject.getJSONObject("Data").getString("status"); } } return "N"; } /** * 入站请求:转发AGV->入站请求->给MES * * @param apply * @return */ public int applyInStation(TransParent apply) { String url = MES_URL + (apply.getProductLineId().equals("LL") ? "AGVTransportPalletNotice" : "Aprs/AGVTransportPalletNotice"); String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 入站允许:转发MES->允许入站->给AGV * * @param allow * @return */ public MesReturn allowInStation(TransInOutStationAllow allow) { MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); if ("Y".equals(allow.getStatus())) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(allow.getTaskno()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(allow.getTaskno()); // rcsTaskContinue.setTriggerType("ROBOT"); // rcsTaskContinue.setTriggerCode(allow.getAgvCode()); int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode())); mesReturn.setSuccess(success == 1 ? "1" : "2"); mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败"); } return mesReturn; } /** * 到站完成:转发AGV->到站完成->给MES * * @param arrivalStation * @return */ public int arriveOnStation(TransArrivalStation arrivalStation,String path) { String url = MES_URL + path; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(arrivalStation)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 离站请求:转发AGV->离站请求->给MES * * @param apply * @return */ public int applyOutStation(TransParent apply) { String url = MES_URL + "api/apply/outStation"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 离站允许:转发MES->允许离站->给AGV * * @param allow * @return */ public MesReturn allowOutStation(TransInOutStationAllow allow) { MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); if ("Y".equals(allow.getStatus())) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(allow.getTaskno()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(allow.getTaskno()); int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode())); mesReturn.setSuccess(success == 1 ? "1" : "2"); mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败"); } return mesReturn; } /** * 离站完成:转发AGV->离站完成->给MES * * @param apply * @return */ public int outStation(TransParent apply) { String url = MES_URL + (apply.getProductLineId().equals("LL") ? "AGVDepartureCompleted" : "Aprs/AGVDepartureCompleted"); String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } @Override public R tkt(String taskNo) { boolean flag = false; try { EntityWrapper<Task> wapper = new EntityWrapper<>(); wapper.eq("task_no", taskNo).orderBy("wrk_date",false); Task task = taskService.selectOne(wapper); // 下发给RCS RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit(); rcsTaskSubmit.setRobotTaskCode(taskNo + "-1"); rcsTaskSubmit.setInitPriority(10); //默认10 List<RcsTaskTargetRoute> targetRouteList = new ArrayList<>(); RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute(); startRoute.setSeq(0); startRoute.setCode(task.getStaNo()); startRoute.setOperation("COLLECT"); targetRouteList.add(startRoute); RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute(); endRoute.setSeq(1); endRoute.setCode(task.getSourceStaNo()); endRoute.setOperation("DELIVERY"); targetRouteList.add(endRoute); rcsTaskSubmit.setTargetRoute(targetRouteList); // 更新起点和终点 String memo = task.getMemo(); TransTask transTask = JSONObject.parseObject(memo, TransTask.class); transTask.setCurStationId(task.getSourceStaNo()); transTask.setNextStationId(task.getStaNo()); transTask.setTransType("01"); // 下空托 // 更新agv任务起点和终点 task.setTaskNo(taskNo + "-1"); task.setSourceStaNo(transTask.getCurStationId()); task.setStaNo(transTask.getNextStationId()); task.setMemo(JSONObject.toJSONString(transTask)); taskService.updateById(task); // 转发给海康或华晓RCS int success = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory()); if (success == 1) { flag = true; } } catch (Exception e) { log.error("空托回产线发AGV运输任务失败", e); } return flag ?R.ok() : R.parse("空托回产线呼叫agv失败"); } // endregion /** * 查询Rcs地址 * * @param agvNo * @return 1 海康;2 华晓 */ private int checkRcsFactory(String agvNo) { AgvInfo agvInfo = agvInfoMapper.selectById(agvNo); return agvInfo.getAgvFactory(); } } src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java
New file @@ -0,0 +1,614 @@ package com.zy.asrs.service.impl; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.zy.asrs.entity.*; import com.zy.asrs.entity.mes.TransArrivalStation; import com.zy.asrs.entity.mes.TransParent; import com.zy.asrs.entity.rcs.*; import com.zy.asrs.enums.RcsRetMethodEnum; import com.zy.asrs.mapper.BlockStationMapper; import com.zy.asrs.mapper.BlockTaskMapper; import com.zy.asrs.service.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.*; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; import java.util.Objects; @Slf4j @Service public class RcsServiceImpl implements RcsService { // 海康RCS地址 @Value("${hik.url}") private String HIK_URL; // 华晓RCS地址 @Value("${hx.url}") private String HX_URL; @Value("${mes.defaultUserId}") public long defaultUserId; @Resource private MesService mesService; @Resource private TaskService taskService; @Resource private BlockStationMapper blockStationMapper; @Resource private BlockTaskMapper blockTaskMapper; @Resource private TaskDetlServiceImpl taskDetlService; @Resource private WrkMastService wrkMastService; // region 封锁区逻辑,目前只有一个大封锁区,任务全部转到滑块库处理,或直接写到滑块库 /** * 申请封锁区请求 * * @param apply * @return */ private int applyBlock(RcsReporterEqpt apply) { BlockTask blockTask = new BlockTask(); blockTask.setTaskCode(apply.getTaskCode()); blockTask.setApplyTime(new Date()); blockTask.setBlockNo(apply.getEqptCode()); blockTask.setBlockName(apply.getEqptName()); blockTask.setMethod(apply.getMethod()); blockTask.setCompleted(0); return blockTaskMapper.insert(blockTask); } /** * 管理封锁区进入 * TODO:增加锁防冲突,可能为分布式锁,定期5秒循环调用 * */ public void managerBlock() { try { BlockTask firstTask = blockTaskMapper.findTop(); if (firstTask == null) { return; } EntityWrapper<BlockStation> wrapper = new EntityWrapper<>(); wrapper.eq("block_no", firstTask.getBlockNo()); List<BlockStation> stations = blockStationMapper.selectList(wrapper); if (!stations.isEmpty()) { boolean locked = false; for (BlockStation station : stations) { // 只允许1个厂家设备进入封锁区,status状态:0 空闲;1 海康封锁中;2 华晓封锁中;-1 异常; if (station.getStatus() > 0 && !station.getStatus().equals(firstTask.getAgvFactory())) { locked = true; break; } } if (!locked) { // 封锁状态 int success = blockStationMapper.addByBlockNo(firstTask.getBlockNo(), firstTask.getAgvFactory()); if (success > 0) { // 通知RCS RcsEqptNotify notify = new RcsEqptNotify(); notify.setEqptCode(firstTask.getBlockNo()); notify.setTaskCode(firstTask.getTaskCode()); notify.setActionStatus("1"); notifyEqpt(notify, firstTask.getAgvFactory()); } } } } catch (Exception e) { log.error("管理封锁区异常", e); } } /** * 离开释放封锁区请求 * TODO:增加锁防冲突,可能为分布式锁 * * @param apply * @return */ private int releaseBlock(RcsReporterEqpt apply) { BlockTask task = blockTaskMapper.findByTaskCode(apply.getTaskCode()); EntityWrapper<BlockStation> wrapper = new EntityWrapper<>(); wrapper.eq("block_no", task.getBlockNo()); List<BlockStation> stations = blockStationMapper.selectList(wrapper); if (!stations.isEmpty()) { // 先完成任务 task.setCompleted(1); task.setCompletedTime(new Date()); int updateTask = blockTaskMapper.updateById(task); // 再更新封锁区数量 for (BlockStation station : stations) { if (station.getAgvNum() - 1 == 0) { station.setStatus(0); } station.setAgvNum(station.getAgvNum() - 1); int updateBlock = blockStationMapper.updateById(station); } } return 1; } // endregion // region 海康RCS,AGV /** * 2.1.2任务下发接口 * 厂家:海量、华晓 * * @param rcsTaskSubmit * @param rcsFactory 1 海康;2 华晓; * @return */ public int submitTask(RcsTaskSubmit rcsTaskSubmit, int rcsFactory){ return 1; // String url = rcsFactory == 2 ? HX_URL :HIK_URL + "api/robot/controller/task/submit"; // String response = sendPost(url, rcsTaskSubmit.toString()); // if (!StringUtils.isEmpty(response) && response.contains("code")){ // RcsReturn rcsReturn = JSONObject.parseObject(response, RcsReturn.class); // if("SUCCESS".equals(rcsReturn.getCode())) { // JSONObject data = rcsReturn.getData(); // String robotTaskCode = data.getString("robotTaskCode"); // if (robotTaskCode.equals(rcsTaskSubmit.getRobotTaskCode())){ // return 1; // } // } // } // // return 0; } /** * 2.1.3任务继续执行接口 * * @param rcsTaskContinue * @param rcsFactory * @return */ public int continueTask(RcsTaskContinue rcsTaskContinue, int rcsFactory){ String url = rcsFactory == 2 ? HX_URL :HIK_URL + "api/robot/controller/task/extend/continue"; String response = sendPost(url, rcsTaskContinue.toString()); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn = JSONObject.parseObject(response, RcsReturn.class); if("SUCCESS".equals(rcsReturn.getCode())) { JSONObject data = rcsReturn.getData(); String robotTaskCode = data.getString("robotTaskCode"); if (robotTaskCode.equals(rcsTaskContinue.getRobotTaskCode())) { return 1; } } } return 0; } /** * 2.1.4任务取消接口 * * @param rcsTaskCancel * @param rcsFactory * @return */ public int cancelTask(RcsTaskCancel rcsTaskCancel, int rcsFactory){ String url = rcsFactory == 2 ? HX_URL :HIK_URL + "api/robot/controller/task/cancel"; String response = sendPost(url, rcsTaskCancel.toString()); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn = JSONObject.parseObject(response, RcsReturn.class); if("SUCCESS".equals(rcsReturn.getCode())) { JSONObject data = rcsReturn.getData(); String robotTaskCode = data.getString("robotTaskCode"); if (robotTaskCode.equals(rcsTaskCancel.getRobotTaskCode())) { return 1; } } } return 0; } /** * 2.1.15外设执行通知接口,通知进入封锁区 * * @param rcsEqptNotify * @param rcsFactory * @return */ private int notifyEqpt(RcsEqptNotify rcsEqptNotify, int rcsFactory){ String url = rcsFactory == 2 ? HX_URL :HIK_URL + "api/wcs/robot/eqpt/notify"; String response = sendPost(url, rcsEqptNotify.toString()); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn = JSONObject.parseObject(response, RcsReturn.class); if("SUCCESS".equals(rcsReturn.getCode())) { JSONObject data = rcsReturn.getData(); String applyCode = data.getString("taskCode"); //申请请求编号,非任务编号 if (applyCode.equals(rcsEqptNotify.getTaskCode())) { return 1; } } } return 0; } /** * 2.2.1任务执行回馈 * 厂家:海量、华晓 * * @param rcsReporterTask * @return */ public RcsReturn reporterTask(RcsReporterTask rcsReporterTask) { RcsReturn rcsReturn = new RcsReturn(); String robotTaskCode = rcsReporterTask.getRobotTaskCode(); String singleRobotCode = rcsReporterTask.getSingleRobotCode(); JSONObject values = rcsReporterTask.getExtra().getJSONObject("values"); // start : 任务开始;outbin : 走出储位;end : 任务完成 String method = values.getString("method"); String carrierType = values.getString("carrierType"); try { if ("Q3".equals(carrierType) || "Q8".equals(carrierType)) { //AGV EntityWrapper<Task> wrapper = new EntityWrapper<>(); wrapper.eq("task_no", robotTaskCode); Task task = taskService.selectOne(wrapper); if (task == null || !task.getTaskNo().equals(robotTaskCode)) { rcsReturn.setCode("Err_RobotCodeNotMatch"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); return rcsReturn; } JSONObject memo = JSONObject.parseObject(task.getMemo()); switch (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method))) { case TASK_START: { task.setWrkSts(302L); // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 task.setModiTime(new Date()); task.setModiUser(defaultUserId); taskService.updateById(task); } break; // case TASK_OUT_BIN: {} break; case TASK_END: { // 更新任务状态等内部逻辑 task.setWrkSts(304L); // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 task.setModiTime(new Date()); task.setModiUser(defaultUserId); taskService.updateById(task); // 任务完成 mesService.reporterTask(rcsReporterTask); // EntityWrapper<TaskDetl> wapper2 = new EntityWrapper<>(); // wapper2.eq("wrk_no", task.getWrkNo()) // .eq("matnr", memo.getString("ItemNo")) // .eq("order_no", memo.getString("OrderNo")); // TaskDetl taskDetl = taskDetlService.selectOne(wapper2); // taskDetl.setAnfme() // taskDetlService.updateById(); // // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 // taskService.completeWrkMast(); // taskDetlService. } break; case APPLY_IN_STATION: case APPLY_OFF_STATION: case ARRIVE_OFF_STATION: { TransParent apply = new TransParent(); apply.setTaskno(robotTaskCode); apply.setTaskname(memo.getString("taskName")); apply.setAgvCode(singleRobotCode); apply.setTransType(memo.getString("TransType")); apply.setProductLineId(memo.getString("ProductLineId")); // apply.setStationId(task.getStaNo()); String transType = memo.getString("TransType"); if(transType.equals("02") || transType.equals("04") || transType.equals("06")) { apply.setStationId(task.getSourceStaNo()); } else { apply.setStationId(task.getStaNo()); } if (RcsRetMethodEnum.APPLY_IN_STATION.getCode().equals(method)) { mesService.applyInStation(apply); } else if (RcsRetMethodEnum.APPLY_OFF_STATION.getCode().equals(method)) { mesService.applyOutStation(apply); } else if (RcsRetMethodEnum.ARRIVE_OFF_STATION.getCode().equals(method)) { mesService.outStation(apply); } } break; case ARRIVE_ON_STATION: { EntityWrapper<TaskDetl> wapper2 = new EntityWrapper<>(); wapper2.eq("wrk_no", task.getWrkNo()) // .eq("matnr", memo.getString("Itemno")) .eq("order_no", memo.getString("OrderNo")); TaskDetl taskDetl = taskDetlService.selectOne(wapper2); TransArrivalStation arrivalStation = new TransArrivalStation(); arrivalStation.setTaskno(robotTaskCode); arrivalStation.setTaskname(memo.getString("taskName")); arrivalStation.setTuoPanId(taskDetl == null || taskDetl.getZpallet() == null ? "" : taskDetl.getZpallet()); arrivalStation.setDaotype(memo.getString("TransType")); arrivalStation.setProductLineId(memo.getString("ProductLineId")); // arrivalStation.setStationId(task.getStaNo()); arrivalStation.setOrderNo(memo.getString("OrderNo")); String transType = memo.getString("TransType"); String dJNo = memo.getString("djNo"); arrivalStation.setDJNo(dJNo); if(transType.equals("02") || transType.equals("04") || transType.equals("06")) { arrivalStation.setStationID(task.getSourceStaNo()); } else { arrivalStation.setStationID(task.getStaNo()); } String path; if(transType.equals("05") || transType.equals("06")) { path = "ToolArrivalNotice"; } else { path = "AGVArrivalCompleted"; } if(transType.equals("01") && arrivalStation.getStationID().contains("XL") || arrivalStation.getStationID().contains("TOOL")) { path = "ToolArrivalNotice"; } mesService.arriveOnStation(arrivalStation,path); } break; default: {} break; } } else if ("CTU".equals(carrierType)) { //CTU EntityWrapper<WrkMast> wrapper = new EntityWrapper<>(); wrapper.eq("task_no", robotTaskCode); WrkMast task = wrkMastService.selectOne(wrapper); if (task == null || !task.getTaskNo().equals(robotTaskCode)) { rcsReturn.setCode("Err_RobotCodeNotMatch"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); return rcsReturn; } // JSONObject memo = JSONObject.parseObject(task.getMemo()); switch (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method))) { case TASK_START: { // task.setWrkSts(302L); // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 // task.setModiTime(new Date()); // task.setModiUser(defaultUserId); // taskService.updateById(task); } break; // case TASK_OUT_BIN: {} break; case TASK_END: { // 更新任务状态等内部逻辑 long wrkSts = task.getWrkSts(); // 1.入库;101.出库; if (task.getIoType() == 1) { wrkSts = 4L; } else if (task.getIoType() == 101) { wrkSts = 14L; } task.setWrkSts(wrkSts); // 4.入库完成;14.已出库未确认; task.setModiTime(new Date()); task.setModiUser(defaultUserId); wrkMastService.updateById(task); // TODO:任务完成触发出入库变更操作 // // 入库完成 // mesService.inFeedback(memo.getString("OrderNo")); // // 出库完成 // mesService.outFeedback(memo.getString("OrderNo")); } break; default: {} break; } } // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } catch (Exception e) { log.error("RCS反馈任务进度处理异常 - {}", rcsReporterTask, e); rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage("内部处理异常"); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } return rcsReturn; } /** * 2.2.4请求外设接口(请求封锁区) * 厂家:海量、华晓 * * @param rcsReporterEqpt * @return */ public RcsReturn reporterEqpt(RcsReporterEqpt rcsReporterEqpt){ int success = 0; if ("APPLY_LOCK".equals(rcsReporterEqpt.getMethod())) { //申请 success = applyBlock(rcsReporterEqpt); } else if ("RELEASE_EQPT".equals(rcsReporterEqpt.getMethod())) { //释放 success = releaseBlock(rcsReporterEqpt); } // 返回RCS RcsReturn rcsReturn = new RcsReturn(); rcsReturn.setCode(success > 0 ? "SUCCESS" : "Err_Internal"); rcsReturn.setMessage(success > 0 ? "" : "内部错误"); JSONObject data = new JSONObject(); data.put("extra", null); rcsReturn.setData(data); return rcsReturn; } // endregion // region 海康CTU 刀具库 // TODO: CTU上层组参引用, // 2.1.2任务下发接口 // 2.1.3任务继续执行接口 // 2.1.4任务取消接口 // 2.2.1任务执行回馈 //// @Transactional(rollbackFor = Exception.class) // public void receiveTaskStatus(RcsReporterTask callbackParam, String method, String stockType, Long hostId) { // // JSONObject values = callbackParam.getExtra().getJSONObject("values"); // EntityWrapper<Task> wapper = new EntityWrapper<>(); // wapper.eq("task_no", callbackParam.getRobotTaskCode()); // Task task = taskService.selectOne(wapper); // if (task == null && !StringUtils.isEmpty(task.getWrkNo())) { // if (1 == task.getIoType()) { // 入库 // // 更新库存 // // // 更新任务状态 // } else if (101 == task.getIoType()) { // 出库 // // 更新库存 // // // 更新任务状态 // // // 货物和托盘解绑 // } // } // } // endregion // region 华晓RCS /** * 9.7申请进入生产线 * * @param apply * @return */ public JSONObject hxApplyInLine(TransParent apply) { String status = mesService.applyInLine(apply); JSONObject result = new JSONObject(); result.put("Success", 1); result.put("Message", status); JSONObject data = new JSONObject(); data.put("status", status); result.put("Data", data); return result; } // endregion // region httpUtil /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { log.info("sendPost - {} - {}", url, param); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("Content-Type", "application/json;charset=utf-8"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } // endregion } src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -370,6 +370,12 @@ wrkDetl.setAppeUser(userId); wrkDetl.setModiTime(now); wrkDetl.setModiUser(userId); wrkDetl.setMatnr(detlDto.getLocDetl().getMatnr()); wrkDetl.setMaktx(detlDto.getLocDetl().getMaktx()); wrkDetl.setUnit(detlDto.getLocDetl().getUnit()); wrkDetl.setSpecs(detlDto.getLocDetl().getSpecs()); wrkDetl.setUnit(detlDto.getLocDetl().getUnit()); wrkDetl.setModel(detlDto.getLocDetl().getModel()); if (!wrkDetlService.insert(wrkDetl)) { throw new CoolException("保存工作档明细失败"); } @@ -457,6 +463,11 @@ wrkDetl.setAppeUser(userId); wrkDetl.setModiTime(now); wrkDetl.setModiUser(userId); wrkDetl.setMatnr(orderDetl.getMatnr()); wrkDetl.setMaktx(orderDetl.getMaktx()); wrkDetl.setSpecs(orderDetl.getSpecs()); wrkDetl.setModel(orderDetl.getModel()); wrkDetl.setUnit(orderDetl.getUnit()); if (!wrkDetlService.insert(wrkDetl)) { throw new CoolException("保存工作档明细失败"); } src/main/java/com/zy/asrs/service/impl/WrkDetlServiceImpl.java
@@ -45,6 +45,11 @@ wrkDetl.setAppeTime(now); wrkDetl.setModiUser(userId); wrkDetl.setModiTime(now); wrkDetl.setMatnr(mat.getMatnr()); wrkDetl.setMaktx(mat.getMaktx()); wrkDetl.setSpecs(mat.getSpecs()); wrkDetl.setModel(mat.getModel()); wrkDetl.setUnit(mat.getUnit()); if (!this.insert(wrkDetl)) { throw new CoolException("保存工作明细失败"); } src/main/java/com/zy/asrs/task/BlockScheduler.java
New file @@ -0,0 +1,26 @@ package com.zy.asrs.task; import com.zy.asrs.service.RcsService; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Slf4j @Component public class BlockScheduler { @Resource private RcsService rcsService; /** * 管理封锁区请求 * */ @Scheduled(cron = "0/3 * * * * ? ") private void execute(){ // rcsService.managerBlock(); } } src/main/java/com/zy/asrs/task/OrderSyncScheduler.java
@@ -2,8 +2,9 @@ import com.core.common.Cools; import com.zy.asrs.entity.Order; import com.zy.asrs.service.ApiLogService; import com.zy.asrs.service.OrderService; import com.zy.asrs.entity.OrderPakin; import com.zy.asrs.entity.OrderPakout; import com.zy.asrs.service.*; import com.zy.asrs.task.core.ReturnT; import com.zy.asrs.task.handler.OrderSyncHandler; import com.zy.asrs.utils.OrderInAndOutUtil; @@ -15,6 +16,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.List; /** @@ -30,6 +32,12 @@ private OrderService orderService; @Autowired private ApiLogService apiLogService; @Resource private OrderPakinService orderPakinService; @Resource private OrderPakoutService orderPakoutService; @Resource private MesService mesService; @Value("${erp.switch.ErpReportOld}") private boolean ErpReportOld; @@ -104,23 +112,43 @@ // @Scheduled(cron = "0/30 * * * * ? ") @Async("orderThreadPool") public void completeAndReportOrderReport() { if (!ErpReportOld){ return; } String erpReport = Parameter.get().getErpReport(); if (!Cools.isEmpty(erpReport) && erpReport.equals("true")) { List<Order> orders = orderService.selectComplete(); for (Order order : orders) { // 入库完成 List<OrderPakin> pakins = orderPakinService.selectComplete(); for (OrderPakin orderPakin : pakins) { try { ReturnT<String> result = orderSyncHandler.startOrderReport(order); if (!result.isSuccess()) { log.error("单据[orderNo={}]上报erp失败", order.getOrderNo()); } mesService.inFeedback(orderPakin.getOrderNo()); } catch (Exception e) { log.error(e.getMessage()); log.error("单据[orderNo={}]上报erp失败", order.getOrderNo()); log.error("推送入库完成信息错误, order{}", orderPakin, e); } } List<OrderPakout> pakouts = orderPakoutService.selectComplete(); for (OrderPakout orderPakout : pakouts) { try { mesService.outFeedback(orderPakout.getOrderNo()); } catch (Exception e) { log.error("推送出库完成信息错误, order{}", orderPakout, e); } } // if (!ErpReportOld){ // return; // } // String erpReport = Parameter.get().getErpReport(); // if (!Cools.isEmpty(erpReport) && erpReport.equals("true")) { // List<Order> orders = orderService.selectComplete(); // for (Order order : orders) { // try { // ReturnT<String> result = orderSyncHandler.startOrderReport(order); // if (!result.isSuccess()) { // log.error("单据[orderNo={}]上报erp失败", order.getOrderNo()); // } // } catch (Exception e) { // log.error(e.getMessage()); // log.error("单据[orderNo={}]上报erp失败", order.getOrderNo()); // } // } // } } } src/main/java/com/zy/asrs/task/WorkMastScheduler.java
@@ -2,6 +2,7 @@ import com.zy.asrs.entity.Task; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.MesService; import com.zy.asrs.service.TaskService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.task.core.ReturnT; @@ -12,6 +13,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Date; import java.util.List; @@ -29,6 +31,9 @@ private WorkMastHandler workMastHandler; @Autowired private TaskService taskService; @Resource private MesService mesService; // TODO:reporterTask() @Scheduled(cron = "0/3 * * * * ? ") private void execute(){ src/main/java/com/zy/asrs/task/handler/OrderSyncHandler.java
@@ -8,10 +8,7 @@ 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.service.*; import com.zy.asrs.task.AbstractHandler; import com.zy.asrs.task.core.ReturnT; import com.zy.asrs.utils.OrderInAndOutUtil; @@ -26,6 +23,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @@ -46,6 +44,14 @@ private ApiLogService apiLogService; @Autowired private DocTypeService docTypeService; @Resource private MesService mesService; //TODO:完成订单时推送MES recvFeedback(orderNo); // mesService.inFeedback(memo.getString("OrderNo")); // // 出库完成 // mesService.outFeedback(memo.getString("OrderNo")); @Transactional public ReturnT<String> startOrderIssuedOnceMore(Order order) { src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -131,6 +131,11 @@ locDetl.setZpallet(wrkDetl.getZpallet()); // 托盘条码 locDetl.setModiTime(now); locDetl.setAppeTime(now); locDetl.setMatnr(wrkDetl.getMatnr()); locDetl.setMaktx(wrkDetl.getMaktx()); locDetl.setSpecs(wrkDetl.getSpecs()); locDetl.setUnit(wrkDetl.getUnit()); locDetl.setZpallet(wrkDetl.getZpallet()); if (!locDetlService.insert(locDetl)) { // exceptionHandle("全板入库 ===>> 添加库存明细失败;[workNo={0}],[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo()); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); @@ -202,6 +207,11 @@ locDetl.setZpallet(wrkDetl.getZpallet()); // 托盘条码 locDetl.setModiTime(now); locDetl.setAppeTime(now); locDetl.setMatnr(wrkDetl.getMatnr()); locDetl.setMaktx(wrkDetl.getMaktx()); locDetl.setSpecs(wrkDetl.getSpecs()); locDetl.setUnit(wrkDetl.getUnit()); locDetl.setZpallet(wrkDetl.getZpallet()); if (!locDetlService.insert(locDetl)) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("拣料途中并板 ===>> 添加库存明细失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); @@ -308,6 +318,11 @@ locDetl.setZpallet(wrkDetl.getZpallet()); // 托盘条码 locDetl.setModiTime(now); locDetl.setAppeTime(now); locDetl.setMatnr(wrkDetl.getMatnr()); locDetl.setMaktx(wrkDetl.getMaktx()); locDetl.setSpecs(wrkDetl.getSpecs()); locDetl.setUnit(wrkDetl.getUnit()); locDetl.setZpallet(wrkDetl.getZpallet()); if (!locDetlService.insert(locDetl)) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return FAIL.setMsg("并板入库 ===>> 新增库存明细失败; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]"); src/main/java/com/zy/common/config/LogAspect.java
New file @@ -0,0 +1,112 @@ package com.zy.common.config; import com.core.common.R; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.rmi.NoSuchObjectException; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Created by Administrator on 2019-07-09. */ @Component @Aspect @Slf4j @Order(2) public class LogAspect { private final List<String> logApiList = Stream.of("digitalTwin", "api/mes", "api/robot") .collect(Collectors.toList()); public LogAspect() { } /** * 切入点 */ @Pointcut("execution(* com.zy.asrs.controller.*.*(..))") // && !execution(* com.lg.iac.controller.PictureController.*(..)) public void controllerPc() { } /** * 环绕通知 * @param pjp ProceedingJoinPoint * @return 方法结果 */ @Around("controllerPc()") public Object around(ProceedingJoinPoint pjp) { try { ServletRequestAttributes attributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .orElseThrow(() -> new NoSuchObjectException("前置通知中获取的 ServletRequestAttributes 对象为空")); HttpServletRequest request = attributes.getRequest(); if(urlContain(request.getRequestURL().toString())){ // 前置通知 log.info("------【前置通知】------"); // 记录请求内容 log.info("浏览器输入的网址:{}", request.getRequestURL().toString()); log.info("HTTP_METHOD:{}", request.getMethod()); log.info("IP:{}", request.getRemoteAddr()); log.info("执行的业务方法名:{}", pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName()); log.info("业务方法获得的参数:{}", Arrays.toString(pjp.getArgs())); Object result = pjp.proceed(); // 后置通知 log.info("------【后置通知】------"); log.info("{}方法的返回值:{}", pjp.getSignature().getName(), result); return result; } else { return pjp.proceed(); } } catch (Throwable e) { // 异常通知 log.error("------【异常通知】------"); log.error("{}方法异常,参数:{},异常:", pjp.getSignature().getName(), Arrays.toString(pjp.getArgs()), e); return R.error("服务器处理数据异常"); } finally { try{ ServletRequestAttributes attributes = Optional.ofNullable((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .orElseThrow(() -> new NoSuchObjectException("前置通知中获取的 ServletRequestAttributes 对象为空")); HttpServletRequest request = attributes.getRequest(); if(urlContain(request.getRequestURL().toString())){ // 最终通知 log.info("------【最终通知】------"); log.info("{}方法执行结束", pjp.getSignature().getName()); } } catch (Exception ignored){ } } } /** * 是否不包含过滤日志接口 * * @param url * @return */ private boolean urlContain(String url){ boolean have = false; for(String str : logApiList){ if(url.contains(str)){ have = true; return have; } } return have; } } src/main/java/com/zy/common/config/WebConfig.java
@@ -1,7 +1,8 @@ package com.zy.common.config; import com.zy.common.constant.MesConstant; import com.zy.common.utils.Http; //import com.zy.common.constant.MesConstant; //import com.zy.common.route.RouteFilter; //import com.zy.common.utils.Http; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -15,6 +16,7 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -30,11 +32,22 @@ @Override public void addInterceptors(InterceptorRegistry registry) { // registry.addInterceptor(new RouteFilter()) // .addPathPatterns("/api/robot") // 拦截路径 // .excludePathPatterns("/static/**"); // 排除静态资源 registry.addInterceptor(adminInterceptor) .addPathPatterns("/**") ; } // @Bean // public RequestMappingHandlerMapping requestMappingHandlerMapping() { // RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping(); // handlerMapping.setOrder(0); // handlerMapping.setInterceptors(new RouteFilter()); // return handlerMapping; // } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") src/main/java/com/zy/common/route/RouteFilter.java
New file @@ -0,0 +1,159 @@ package com.zy.common.route; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.zy.asrs.entity.AgvInfo; import com.zy.asrs.entity.rcs.RcsReporterEqpt; import com.zy.asrs.entity.rcs.RcsReporterTask; import com.zy.asrs.entity.rcs.RcsReturn; import com.zy.asrs.mapper.AgvInfoMapper; import com.zy.asrs.service.RcsService; import com.zy.asrs.service.impl.RcsServiceImpl; import lombok.Value; import lombok.extern.slf4j.Slf4j; import org.apache.tika.utils.StringUtils; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; @Slf4j @Component public class RouteFilter implements HandlerInterceptor { private static final String[] WAREHOUSE_CODE = {"dj", "jg", "ljq", "hk"}; // private static final String[] WAREHOUSE = {"刀具库", "加工库", "联结器装配库", "滑块库"}; // @Value("${mes}") private static Integer CURRENT_WMS_ID = 4; //滑块 @Resource private RcsService rcsService; @Resource private AgvInfoMapper agvInfoMapper; // 请求前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // if (findIndex(request) != CURRENT_WMS_ID) { // // 转发 // // 获取RequestDispatcher对象 // RequestDispatcher dispatcher = request.getRequestDispatcher("/SecondServlet"); // // // 转发请求到SecondServlet // dispatcher.forward(request, response); // //// forward(request); // } forward(request, response); // long startTime = System.currentTimeMillis(); // System.out.println("preHandle,In:" + startTime); // request.setAttribute("startTime", startTime); return true; } // TODO:请求转发与响应重定向 //TODO:HttpServletRequest读取一次后不能再使用,需重构下逻辑顺序 private void forward(HttpServletRequest request, HttpServletResponse response) throws IOException { String url = request.getRequestURI(); StringBuilder body = new StringBuilder(); BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { body.append(line); } JSONObject bodyJson = JSONObject.parseObject(body.toString()); String singleRobotCode = bodyJson.getString("singleRobotCode"); if (!StringUtils.isBlank(singleRobotCode)) { //任务回馈接口 int index = findIndex(singleRobotCode); if (index != CURRENT_WMS_ID) { String wmsId = WAREHOUSE_CODE[index - 1]; //存储所有AGV所属库区 url = url.replace(WAREHOUSE_CODE[CURRENT_WMS_ID - 1], wmsId); // 转发 String returns = RcsServiceImpl.sendPost(url, body.toString()); log.info("转发请求url:{},body:{},返回:{}", url, body, returns); response(response, returns); } else { // 内部逻辑处理 RcsReporterTask param = JSONObject.toJavaObject(bodyJson, RcsReporterTask.class); RcsReturn rcsReturn = rcsService.reporterTask(param); response(response, rcsReturn.toString()); } } else { //请求外设(封锁区),封锁区由当前程序管理不转发 RcsReporterEqpt param = JSONObject.toJavaObject(bodyJson, RcsReporterEqpt.class); RcsReturn rcsReturn = rcsService.reporterEqpt(param); response(response, rcsReturn.toString()); } } private int findIndex(String agvNo) { AgvInfo agvInfo = agvInfoMapper.selectById(agvNo); if (agvInfo != null) { return Integer.parseInt(agvInfo.getBelongArea()); } return -1; } public static void response(HttpServletResponse response, String baseRes){ response.setCharacterEncoding("utf-8"); response.setContentType("application/json; charset=utf-8"); try (PrintWriter out = response.getWriter()) { out.print(JSON.toJSONString(baseRes)); out.flush(); } catch (Exception e) { log.error(e.getMessage(), e); // e.printStackTrace(); } } // public static void response(HttpServletResponse response, String baseRes){ // response.setCharacterEncoding("utf-8"); // response.setContentType("application/json; charset=utf-8"); // try (PrintWriter out = response.getWriter()) { // R r = R.parse(baseRes); // JSONObject jsonObject = new JSONObject(); // jsonObject.put("total", "0"); // jsonObject.put("record", ""); // r.add(jsonObject); // out.print(JSON.toJSONString(r)); // out.flush(); // } catch (Exception e) { // e.printStackTrace(); // } // } // /** // * 设置webflux模型响应 // * // * @param response ServerHttpResponse // * @param contentType content-type // * @param status http状态码 // * @param code 响应状态码 // * @param value 响应内容 // * @return Mono<Void> // */ // public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) // { // response.setStatusCode(status); // response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); // RcsReturn<?> result = RcsReturn.fail(code, value.toString()); // DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes()); // return response.writeWith(Mono.just(dataBuffer)); // } } src/main/java/com/zy/common/web/WcsController.java
@@ -51,6 +51,8 @@ @Autowired private WorkService workService; // TODO:称重、拍照上报存储,CTU料箱运转 @PostMapping("/pakin/loc/v1") @ResponseBody public synchronized R getLocNo(@RequestBody SearchLocParam param) { src/main/java/com/zy/system/timer/LicenseTimer.java
@@ -26,7 +26,7 @@ } public void setSystemSupport(boolean systemSupport) { SYSTEM_SUPPORT = systemSupport; SYSTEM_SUPPORT = true; // systemSupport; } public int getLicenseDays() { src/main/resources/application-dev.yml
@@ -1,5 +1,5 @@ server: port: 8080 port: 8088 servlet: context-path: /@pom.build.finalName@ @@ -11,8 +11,11 @@ datasource: driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver username: sa password: Skyouc#23 url: jdbc:sqlserver://127.0.0.1:1433;databasename=jsxswms password: sa@123 url: jdbc:sqlserver://127.0.0.1:1433;databasename=djwms # username: sa # password: Skyouc#23 # url: jdbc:sqlserver://192.168.4.24:1433;databasename=jsxswms mvc: static-path-pattern: /** redis: @@ -110,3 +113,31 @@ username: "llw" password: "666666" lcid: 2052 #分库配置 wms: #当前是第几库 currentId: 4 #当前库名称 currentName: 滑块装配库 #立库AGV自动运货出库口编码 wmsTransStartStation1: 1013 #mes对接 mes: url: http://172.26.11.250/dev-api/basicmodel/Api/WMS/ #默认接口操作人员id defaultUserId: 30 #海康对接 hik: url: http://127.0.0.1:8089/hik/ #华晓对接 hx: url: http://127.0.0.1:8089/hx/ #刀具管理系统对接 dj: url: http://172.26.11.2/ src/main/resources/libs/framework-3.2.0.jarBinary files differ
src/main/resources/logback-spring.xml
@@ -19,6 +19,9 @@ </encoder> </appender> <!-- 日志保存路径 --> <property name="LOG_PATH" value="D:/wmslogs/dj" /> <!--info级别--> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/info.log</file> src/main/resources/mapper/BlockStationMapper.xml
New file @@ -0,0 +1,24 @@ <?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.BlockStationMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BlockStation"> <result column="task_code" property="taskCode" /> <result column="apply_time" property="applyTime" /> <result column="block_no" property="blockNo" /> <result column="block_name" property="blockName" /> <result column="method" property="method" /> <result column="completed" property="completed" /> <result column="agv_factory" property="agvFactory" /> </resultMap> <update id="addByBlockNo"> UPDATE agv_block_station SET status = #{status}, agv_num = ISNULL(agv_num, 0) + 1 WHERE block_no = #{blockNo} </update> <update id="delByBlockNo"> UPDATE agv_block_station SET status = #{status}, agv_num = ISNULL(agv_num, 0) - 1 WHERE block_no = #{blockNo} </update> </mapper> src/main/resources/mapper/BlockTaskMapper.xml
New file @@ -0,0 +1,24 @@ <?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.BlockTaskMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BlockTask"> <result column="task_code" property="taskCode" /> <result column="apply_time" property="applyTime" /> <result column="block_no" property="blockNo" /> <result column="block_name" property="blockName" /> <result column="method" property="method" /> <result column="completed" property="completed" /> <result column="agv_factory" property="agvFactory" /> </resultMap> <select id="findTop" resultType="com.zy.asrs.entity.BlockTask"> SELECT TOP 1 * FROM agv_block_task WHERE completed = 0 AND method = 'APPLY_LOCK' ORDER BY apply_time ASC </select> <select id="findByTaskCode" resultType="com.zy.asrs.entity.BlockTask"> SELECT * FROM agv_block_task WHERE method = 'APPLY_LOCK' AND completed = 0 AND task_code = #{taskCode} </select> </mapper> src/main/resources/mapper/LocCountMapper.xml
New file @@ -0,0 +1,42 @@ <?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.LocCountMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.LocCount"> <result column="date" property="date" /> <result column="area_id" property="areaId" /> <result column="loc_num" property="locNum" /> <result column="remain_num" property="remainNum" /> </resultMap> <select id="getByAreaAndDate" resultType="com.zy.asrs.entity.LocCount"> SELECT * FROM asr_loc_count WHERE area_id = #{areaId} AND date > #{startDate} AND date < #{endDate} </select> <select id="getByDate" resultType="com.zy.asrs.entity.LocCount"> SELECT date, SUM(ISNULL(loc_num, 0)) AS loc_num, SUM(ISNULL(remain_num, 0)) AS remain_num FROM asr_loc_count GROUP BY date </select> <insert id="insertOrUpdate" parameterType="com.zy.asrs.entity.LocCount"> IF EXISTS (SELECT date FROM asr_loc_count WHERE date = #{model.date} AND area_id = #{model.areaId}) INSERT INTO asr_loc_count(date, area_id, loc_num, remain_num) VALUES (#{model.date}, #{model.areaId}, #{model.locNum}, #{model.remainNum}) ELSE UPDATE asr_loc_count SET loc_num = #{model.locNum}, remain_num = #{model.remainNum} </insert> <select id="totalLoc" resultType="com.zy.asrs.entity.LocCount"> SELECT area_id, COUNT(*) AS loc_num FROM asr_loc_mast WHERE loc_sts != 'Z' GROUP BY area_id </select> <select id="useLoc" resultType="com.zy.asrs.entity.LocCount"> SELECT area_id, COUNT(*) AS loc_num FROM asr_loc_mast WHERE loc_sts = 'F' or loc_sts = 'P' or loc_sts = 'Q' or loc_sts = 'R' or loc_sts = 'S' or loc_sts = 'X' GROUP BY area_id </select> </mapper> src/main/resources/mapper/ViewDigitalTwinMapper.xml
New file @@ -0,0 +1,79 @@ <?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.DigitalTwinMapper"> <!--总览:总库位、已用库位、今日库存、今日出库、今日入库--> <select id="overview" resultType="Double"> SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts != 'Z' <if test="areaId != null"> and area_id = #{areaId} </if> UNION ALL SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts = 'F' or loc_sts = 'P' or loc_sts = 'Q' or loc_sts = 'R' or loc_sts = 'S' or loc_sts = 'X' <if test="areaId != null"> and area_id = #{areaId} </if> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_loc_detl <if test="areaId != null"> WHERE area_id = #{areaId} </if> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkin_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23) <if test="areaId != null"> and area_id = #{areaId} </if> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkout_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23) <if test="areaId != null"> and area_id = #{areaId} </if> </select> <select id="recentOrder" resultType="com.zy.asrs.entity.digitaltwin.DtOrderVo"> SELECT CONVERT(VARCHAR, order_time, 23) as orderDate, COUNT(*) AS orderNum FROM man_order WHERE order_time BETWEEN #{startTime} AND #{endTime} GROUP BY CONVERT(VARCHAR, order_time, 23) </select> <select id="recentInBound" resultType="com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo"> SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS inBoundNum FROM asr_wrkin_view WHERE io_time BETWEEN #{startTime} AND #{endTime} <if test="areaId != null"> and area_id = #{areaId} </if> GROUP BY CONVERT(VARCHAR, io_time, 23) </select> <select id="recentOutBound" resultType="com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo"> SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS outBoundNum FROM asr_wrkout_view WHERE io_time BETWEEN #{startTime} AND #{endTime} <if test="areaId != null"> and area_id = #{areaId} </if> GROUP BY CONVERT(VARCHAR, io_time, 23) </select> <select id="recentDetainMat" resultType="com.zy.asrs.entity.digitaltwin.DtDetainMatVo"> select * from ( select ROW_NUMBER() OVER(Order by t.io_time desc) as row , * from ( SELECT area_id AS belongAreaId, area_name AS belongAreaName, matnr AS matId, maktx AS matName, loc_no AS lokId, '' AS lokName, DATEDIFF(MINUTE, appe_time, GETDATE()) AS detainTime, appe_time AS inBoundTime FROM asr_loc_detl WHERE appe_time < #{startTime} <if test="areaId != null"> and area_id = #{areaId} </if> ) t ) a where 1=1 and a.row between ((#{pageIndex}-1)*#{pageSize}+1) and (#{pageIndex}*#{pageSize}) </select> </mapper> src/main/webapp/static/js/common.js
@@ -1,4 +1,4 @@ var baseUrl = "/wms"; var baseUrl = "/djwms"; // 详情窗口-高度 var detailHeight = '80%'; src/main/webapp/static/js/mat/mat.js
@@ -211,52 +211,52 @@ }); } break; case "batchModifties": var selected = checkStatus.data; if (selected.length === 0) { layer.msg('请选择修改数据'); } else { let selIds = selected.map(item => { return item.id }); layer.open({ type: 1, title: '批量修改', area: ['500px'], shadeClose: true, content: $('#batchModifties'), success: function (layero, index) { layer.iframeAuto(index); form.on('submit(batchModify)', function (data) { let params = {...data?.field} params.id = selIds $.ajax({ url: baseUrl + "/mat/batch/auth", headers: {'token': localStorage.getItem('token')}, data: JSON.stringify(params), dataType: 'json', contentType: 'application/json;charset=UTF-8', method: 'POST', success: function (res) { layer.closeAll(); if (res.code === 200) { } else if (res.code === 403) { top.location.href = baseUrl + "/"; } else { layer.msg(res.msg) } } }); layer.closeAll(); }); }, end: function () { } }); } break; // case "batchModifties": // var selected = checkStatus.data; // if (selected.length === 0) { // layer.msg('请选择修改数据'); // } else { // let selIds = selected.map(item => { // return item.id // }); // layer.open({ // type: 1, // title: '批量修改', // area: ['500px'], // shadeClose: true, // content: $('#batchModifties'), // success: function (layero, index) { // layer.iframeAuto(index); // form.on('submit(batchModify)', function (data) { // let params = {...data?.field} // params.id = selIds // $.ajax({ // url: baseUrl + "/mat/batch/auth", // headers: {'token': localStorage.getItem('token')}, // data: JSON.stringify(params), // dataType: 'json', // contentType: 'application/json;charset=UTF-8', // method: 'POST', // success: function (res) { // layer.closeAll(); // if (res.code === 200) { // // } else if (res.code === 403) { // top.location.href = baseUrl + "/"; // } else { // layer.msg(res.msg) // } // } // }); // layer.closeAll(); // }); // }, // end: function () { // // } // }); // } // break; default: break; } src/main/webapp/views/basWhs/basWhs.html
@@ -31,7 +31,8 @@ <!-- 表格 --> <div class="layui-form"> <table class="layui-hide" id="basWhsType" lay-filter="basWhsType"></table> <!-- <table class="layui-hide" id="basWhsType" lay-filter="basWhsType"></table>--> <table class="layui-hide" id="basWhs" lay-filter="basWhs"></table> </div> <script type="text/html" id="toolbar"> <div class="layui-btn-container"> @@ -49,7 +50,7 @@ <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/basWhsType/basWhsType.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/basWhs/basWhs.js" charset="utf-8"></script> <iframe id="detail-iframe" scrolling="auto" style="display:none;"></iframe> src/main/webapp/views/pda/comb.html
@@ -54,11 +54,11 @@ limit: 500, cellMinWidth: 50, cols: [[ {fixed: 'left', align: 'center', field: 'count', title: '数量', style:'color: blue', width:50}, {fixed: 'left', align: 'center', field: 'anfme', title: '数量', style:'color: blue', width:50}, {field: 'matnr', align: 'center', title: '商品编号'}, {field: 'maktx', align: 'center', title: '商品名称'} ]], done: function (res, curr, count) { done: function (res, curr, anfme) { } }); @@ -100,7 +100,7 @@ let toPush = true; for (var j=0;j<matData.length;j++){ if (data.matnr === matData[j].matnr) { matData[j].count = Number(matData[j].count) + Number(data.count); matData[j].anfme = Number(matData[j].anfme) + Number(data.anfme); toPush = false; } } src/main/webapp/views/pda/login.html
@@ -123,7 +123,8 @@ debugger $.ajax({ url: baseUrl+"/login.action", data: user, headers: {'Content-Type': 'application/json'}, data: JSON.stringify(user), method: 'POST', success: function (res) { if (res.code === 200){ src/main/webapp/views/pda/matQuery.html
@@ -124,9 +124,10 @@ success: function (res) { if (res.code === 200) { if (res.data != null) { $('#matName').val(res.data.matName); $('#str1').val(res.data.str1); $('#str2').val(res.data.str2); console.log(res.data) $('#matName').val(res.data.maktx); $('#str1').val(res.data.unit); $('#str2').val(res.data.specs); countDom.val(initMatCount); $('#count').focus().select(); } @@ -144,9 +145,9 @@ */ function confirm(){ var data = { matNo: $('#matNo').val(), matName: $('#matName').val(), count: countDom.val() matnr: $('#matNo').val(), maktx: $('#matName').val(), anfme: Number(countDom.val()) }; parent.addTableData(data); parent.layer.close(parent.matCodeLayerIdx);