Browse Source

对接PLC及编写叠包机空托移动任务生成逻辑

zhifei 1 year ago
parent
commit
23a0a5a313
21 changed files with 304 additions and 199 deletions
  1. 6 0
      pom.xml
  2. 4 0
      ruoyi-admin/pom.xml
  3. 10 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/ams/WcsTaskController.java
  4. 31 45
      ruoyi-admin/src/main/resources/application-dev.yml
  5. 1 0
      ruoyi-admin/src/main/resources/application.yml
  6. 8 8
      ruoyi-admin/src/main/resources/logback-test.xml
  7. 8 8
      ruoyi-admin/src/main/resources/logback.xml
  8. 9 1
      ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/WarehouseTest.java
  9. 2 2
      ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java
  10. 49 0
      ruoyi-dongfangyaiye/pom.xml
  11. 2 2
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
  12. 1 2
      ruoyi-system/src/main/java/com/ruoyi/system/init/PlcConnectServiceRunner.java
  13. 3 11
      ruoyi-ui/src/views/ams/flowConfig/index.vue
  14. 27 13
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/AmsNdcEventServiceImpl.java
  15. 14 49
      warewms-ams/src/main/java/com/ruoyi/ams/business/BusinessServiceImpl.java
  16. 1 1
      warewms-ams/src/main/java/com/ruoyi/ams/locationView/service/LocationViewService.java
  17. 10 8
      warewms-ams/src/main/java/com/ruoyi/ams/task/mapper/WcsTaskMapper.java
  18. 2 0
      warewms-ams/src/main/java/com/ruoyi/ams/task/service/IWcsTaskService.java
  19. 84 1
      warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java
  20. 20 0
      warewms-ams/src/main/resources/mapper/ams/WcsTaskMapper.xml
  21. 12 48
      warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java

+ 6 - 0
pom.xml

@@ -243,6 +243,11 @@
                 <version>${iotCommunication.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.ruoyi</groupId>
+                <artifactId>ruoyi-dongfangyaiye</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -256,6 +261,7 @@
         <module>warewms-base</module>
         <module>warewms-ams</module>
         <module>warewms-hard</module>
+        <module>ruoyi-dongfangyaiye</module>
     </modules>
     <packaging>pom</packaging>
 

+ 4 - 0
ruoyi-admin/pom.xml

@@ -90,6 +90,10 @@
             <artifactId>warewms-hard</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-dongfangyaiye</artifactId>
+        </dependency>
     </dependencies>
 
 <!--    <build>-->

+ 10 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/ams/WcsTaskController.java

@@ -203,6 +203,16 @@ public class WcsTaskController extends BaseController {
     }
 
 
+    /**
+     * 新增托盘移库任务
+     */
+    @Log(title = "AGV任务", businessType = BusinessType.INSERT)
+    @PostMapping("moveEmptyPallets")
+    public AjaxResult moveEmptyPallets(@RequestBody WcsTask wcsTask) {
+        return toAjax(wcsTaskService.moveEmptyPallets(wcsTask));
+    }
+
+
     public static class ToChargeForm {
         private Integer agvNo;
 

+ 31 - 45
ruoyi-admin/src/main/resources/application-dev.yml

@@ -6,7 +6,7 @@ spring:
         druid:
             # 主库数据源
             master:
-                url: jdbc:mysql://47.100.220.92:3306/wareams_dongfangtaiye?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
+                url: jdbc:mysql://47.100.220.92:3306/warewms_dongfangtaiye?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
                 username: warewms
                 password: warewms123
             # 从库数据源
@@ -68,49 +68,35 @@ init-task:
     autosend: false # 自动下发任务
     aciservice: false # ndc通讯
 
-modbus:
-    tcp-master:
-        first: # 自动门(靠马路)
-            open: false
-            host: 192.168.42.201
-            port: 9000
-        second: # 自动门(靠里面)
-            open: false
-            host: 192.168.42.202
-            port: 9000
-        sixth: # 自动门(靠马路-第二层)
-            open: false
-            host: 192.168.42.210
-            port: 9000
-        seventh: # 卷帘门
-            open: false
-            host: 192.168.42.211
-            port: 9000
-        third: # 按钮盒
-            open: false
-            host: 192.168.42.205
-            port: 9000
-        fourth: # 充电机(三向车)
-            open: false
-            host: 192.168.42.208
-            port: 8899
-        fifth: # 充电机(迷你堆垛)
-            open: false
-            host: 192.168.42.209
-            port: 8899
+    # plc连接配置
+plc:
+    plcList[0]:
+        ip: 192.68.100.101
+        enable: false
+        name: packingMachine_1Plc
+        ePlcType: S1200
+        heartbeat: DB5000.2
+        confirmTheStatus:
+    plcList[1]:
+        ip: 192.68.100.102
+        enable: false
+        name: packingMachine_2Plc
+        ePlcType: S1200
+        heartbeat: DB5000.2
+        confirmTheStatus:
+    plcList[2]:
+        ip: 192.68.100.103
+        enable: false
+        name: packingMachine_3Plc
+        ePlcType: S1200
+        heartbeat: DB5000.2
+        confirmTheStatus:
+    plcList[3]:
+        ip: 192.68.100.104
+        enable: false
+        name: stackingMachinePlc
+        ePlcType: S1200
+        heartbeat: DB5000.2
+        confirmTheStatus:
 
-# 注意:这玩意只能跑在window上
-rfid:
-  first:
-      open: false
-      host: 169.168.42.203
-      port: 5084
-      number-of-tags: 3 # 一次读取标签的数量
-      timeout-milliseconds: 5000
-  second: # 靠里面
-      open: false
-      host: 192.168.42.204
-      port: 5084
-      number-of-tags: 3 # 一次读取标签的数量
-      timeout-milliseconds: 5000
 

+ 1 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -96,6 +96,7 @@ pagehelper:
   helperDialect: mysql
   supportMethodsArguments: true
   params: count=countSql
+  reasonable: false
 
 # Swagger配置
 swagger:

+ 8 - 8
ruoyi-admin/src/main/resources/logback-test.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <!-- 日志存放路径 -->
-	<property name="log.path" value="/Users/gizmo/JavaProjectsFiles/Logs/ruoyi/logs" />
+	<property name="log.path" value="../logs" />
     <!-- 日志输出格式 -->
 	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
 
@@ -11,7 +11,7 @@
 			<pattern>${log.pattern}</pattern>
 		</encoder>
 	</appender>
-	
+
 	<!-- 系统日志输出 -->
 	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-info.log</file>
@@ -34,7 +34,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
 	</appender>
-	
+
 	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-error.log</file>
         <!-- 循环政策:基于时间创建日志文件 -->
@@ -56,7 +56,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
     </appender>
-	
+
 	<!-- 用户访问日志输出  -->
     <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<file>${log.path}/sys-user.log</file>
@@ -70,7 +70,7 @@
             <pattern>${log.pattern}</pattern>
         </encoder>
     </appender>
-	
+
 	<!-- 系统模块日志级别控制  -->
 	<logger name="com.ruoyi" level="info" />
 	<!-- Spring日志级别控制  -->
@@ -79,15 +79,15 @@
 	<root level="info">
 		<appender-ref ref="console" />
 	</root>
-	
+
 	<!--系统操作日志-->
     <root level="info">
         <appender-ref ref="file_info" />
         <appender-ref ref="file_error" />
     </root>
-	
+
 	<!--系统用户操作日志-->
     <logger name="sys-user" level="info">
         <appender-ref ref="sys-user"/>
     </logger>
-</configuration> 
+</configuration>

+ 8 - 8
ruoyi-admin/src/main/resources/logback.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <!-- 日志存放路径 -->
-	<property name="log.path" value="../../../logs/ruoyi/logs" />
+	<property name="log.path" value="../logs" />
     <!-- 日志输出格式 -->
 	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
 
@@ -11,7 +11,7 @@
 			<pattern>${log.pattern}</pattern>
 		</encoder>
 	</appender>
-	
+
 	<!-- 系统日志输出 -->
 	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-info.log</file>
@@ -34,7 +34,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
 	</appender>
-	
+
 	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-error.log</file>
         <!-- 循环政策:基于时间创建日志文件 -->
@@ -56,7 +56,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
     </appender>
-	
+
 	<!-- 用户访问日志输出  -->
     <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<file>${log.path}/sys-user.log</file>
@@ -70,7 +70,7 @@
             <pattern>${log.pattern}</pattern>
         </encoder>
     </appender>
-	
+
 	<!-- 系统模块日志级别控制  -->
 	<logger name="com.ruoyi" level="info" />
 	<!-- Spring日志级别控制  -->
@@ -79,15 +79,15 @@
 	<root level="info">
 		<appender-ref ref="console" />
 	</root>
-	
+
 	<!--系统操作日志-->
     <root level="info">
         <appender-ref ref="file_info" />
         <appender-ref ref="file_error" />
     </root>
-	
+
 	<!--系统用户操作日志-->
     <logger name="sys-user" level="info">
         <appender-ref ref="sys-user"/>
     </logger>
-</configuration> 
+</configuration>

+ 9 - 1
ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/WarehouseTest.java

@@ -41,6 +41,11 @@ import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.base.service.IBaseWarehouseService;
 import com.ruoyi.base.utils.IdSequenceUtils;
 import com.ruoyi.framework.web.domain.server.Sys;
+import com.ruoyi.system.enums.PLCConnectNameEnum;
+import com.ruoyi.taiye.domain.DeviceLog;
+import com.ruoyi.taiye.mapper.DeviceLogMapper;
+import com.ruoyi.taiye.service.IDeviceLogService;
+import com.ruoyi.taiye.service.impl.DeviceLogServiceImpl;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -297,9 +302,12 @@ public class WarehouseTest {
         initDocOrderData();
     }
 
+    @Autowired
+    IDeviceLogService deviceLogService;
     @Test
     public void testAmsTask() {
-        businessService.autoSend();
+        deviceLogService.insertDeviceLog(new DeviceLog(PLCConnectNameEnum.PACKING_MACHINE_2.getMetadata(),PLCConnectNameEnum.PACKING_MACHINE_2.getMetaName(),"获取到下料信号:"+true,"1"));
+
     }
 
     @Test

+ 2 - 2
ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageDomain.java

@@ -4,7 +4,7 @@ import com.ruoyi.common.utils.StringUtils;
 
 /**
  * 分页数据
- * 
+ *
  * @author ruoyi
  */
 public class PageDomain
@@ -89,7 +89,7 @@ public class PageDomain
     {
         if (StringUtils.isNull(reasonable))
         {
-            return Boolean.TRUE;
+            return Boolean.FALSE;
         }
         return reasonable;
     }

+ 49 - 0
ruoyi-dongfangyaiye/pom.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ruoyi</groupId>
+        <artifactId>ruoyi</artifactId>
+        <version>3.8.1</version>
+    </parent>
+
+    <artifactId>ruoyi-dongfangyaiye</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <!-- 通用工具-->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common</artifactId>
+        </dependency>
+
+        <!-- 系统模块-->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-system</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>warewms-base</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>warewms-hard</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>warewms-ams</artifactId>
+        </dependency>
+
+
+    </dependencies>
+</project>

+ 2 - 2
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java

@@ -79,8 +79,8 @@ public abstract class AbstractQuartzJob implements Job
         sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
         sysJobLog.setStartTime(startTime);
         sysJobLog.setStopTime(new Date());
-        long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
-        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
+//        long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
+//        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
         if (e != null)
         {
             sysJobLog.setStatus(Constants.FAIL);

+ 1 - 2
ruoyi-system/src/main/java/com/ruoyi/system/init/PlcConnectServiceRunner.java

@@ -118,8 +118,7 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
             scheduledExecutorService.scheduleWithFixedDelay(()->{
                 if (!reTryPlc.contains(plcConfig.getName())){
                     try {
-                        byte b = s7PLC.readByte(plcConfig.getHeartbeat());
-                        s7PLC.writeByte(plcConfig.getConfirmTheStatus(),b);
+                        s7PLC.readByte(plcConfig.getHeartbeat());
                     }catch (Exception e){
                         log.error("device:{},The connection is lost",plcConfig.getName());
                         retry(plcConfig);

+ 3 - 11
ruoyi-ui/src/views/ams/flowConfig/index.vue

@@ -120,7 +120,7 @@
             <el-form-item label="操作类型" prop="flowType">
               <el-select style="width: 100%" v-model="form.flowType" placeholder="请选操作类型" clearable size="small">
                 <el-option
-                  v-for="dict in flowTypeDict"
+                  v-for="dict in dict.type.flow_type_dict"
                   :key="dict.value"
                   :label="dict.label"
                   :value="dict.value"
@@ -429,7 +429,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 export default {
   name: "FlowConfig",
   components: { Treeselect },
-  dicts: ['sys_yes_no'],
+  dicts: ['sys_yes_no','flow_type_dict'],
   data() {
     return {
       // 遮罩层
@@ -490,14 +490,6 @@ export default {
       qtyEnd: null,
       weightStart: null,
       weightEnd: null,
-      flowTypeDict: [
-        {label : '收货', value : 'RECEIPT'},
-        {label : 'AGV入库上架', value : 'ASN'},
-        {label : '标准入库上架', value : 'BASASN'},
-        {label : 'AGV拣货出库', value : 'SO'},
-        {label : 'AGV按单出库', value : 'BATCHSO'},
-        {label : '移库', value : 'MV'}
-      ],
       flowDict: [],
       attShowFlag: true,
       eventData: []
@@ -658,7 +650,7 @@ export default {
         this.$modal.msgSuccess("删除成功");
       }).catch(() => {});
     },
-	/** 流程配置体序号 */
+    /** 流程配置体序号 */
     rowFlowConfigDetailsIndex({ row, rowIndex }) {
       row.index = rowIndex + 1;
     },

+ 27 - 13
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/AmsNdcEventServiceImpl.java

@@ -1,6 +1,12 @@
 package com.ruoyi.ams.agv.ndc.service.impl;
 
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.ruoyi.common.core.redis.RedisCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.ams.agv.ndc.mapper.AmsNdcEventMapper;
@@ -9,19 +15,22 @@ import com.ruoyi.ams.agv.ndc.service.IAmsNdcEventService;
 
 /**
  * Ndc反馈事件代码字典Service业务层处理
- * 
+ *
  * @author andy
  * @date 2022-08-08
  */
 @Service
-public class AmsNdcEventServiceImpl implements IAmsNdcEventService 
+public class AmsNdcEventServiceImpl implements IAmsNdcEventService
 {
     @Autowired
     private AmsNdcEventMapper amsNdcEventMapper;
 
+    @Autowired
+    private RedisCache redisCache;
+
     /**
      * 查询Ndc反馈事件代码字典
-     * 
+     *
      * @param id Ndc反馈事件代码字典主键
      * @return Ndc反馈事件代码字典
      */
@@ -33,7 +42,7 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
 
     /**
      * 查询Ndc反馈事件代码字典列表
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return Ndc反馈事件代码字典
      */
@@ -52,17 +61,22 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
     @Override
     public AmsNdcEvent selectAmsNdcEventByModel(AmsNdcEvent amsNdcEvent)
     {
-        List<AmsNdcEvent> list = amsNdcEventMapper.selectAmsNdcEventList(amsNdcEvent);
-        if (list!=null && list.size()>0) {
-            return list.get(0);
-        } else {
-            return null;
+        Map<String, AmsNdcEvent> eventTable = redisCache.getCacheObject("ecodeType:" + amsNdcEvent.getType());
+        if (ObjectUtil.isNull(eventTable)) {
+            AmsNdcEvent e = new AmsNdcEvent();
+            e.setType(amsNdcEvent.getType());
+            eventTable = amsNdcEventMapper.selectAmsNdcEventList(e).stream().collect(Collectors.toMap((i) -> i.getEcode().toString(), Function.identity()));
+            if(ObjectUtil.isNull(eventTable)){
+                return null;
+            }
+            redisCache.setCacheObject("ecodeType:" + amsNdcEvent.getType(), eventTable);
         }
+        return eventTable.get(amsNdcEvent.getEcode().toString());
     }
 
     /**
      * 新增Ndc反馈事件代码字典
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return 结果
      */
@@ -74,7 +88,7 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
 
     /**
      * 修改Ndc反馈事件代码字典
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return 结果
      */
@@ -86,7 +100,7 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
 
     /**
      * 批量删除Ndc反馈事件代码字典
-     * 
+     *
      * @param ids 需要删除的Ndc反馈事件代码字典主键
      * @return 结果
      */
@@ -98,7 +112,7 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
 
     /**
      * 删除Ndc反馈事件代码字典信息
-     * 
+     *
      * @param id Ndc反馈事件代码字典主键
      * @return 结果
      */

+ 14 - 49
warewms-ams/src/main/java/com/ruoyi/ams/business/BusinessServiceImpl.java

@@ -123,16 +123,11 @@ public class BusinessServiceImpl implements IBusinessService {
             AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy();
 
             for (AgvCallDTO agvCallDTO : agvCallDTOList) {
-                //如果是入库把起始库位相同的数据整合到一起生成库存记录
                 BaseLocationInfo locationFrom = null;
                 BaseLocationInfo locationTo = null;
-                List<WcsTask> wcsTaskList = new ArrayList<>();
                 String paramLocationFrom = agvCallDTO.getLocationFrom();
                 String paramLocationTo = agvCallDTO.getLocationTo();
                 List<String> zoneIdList = new ArrayList<>();
-                if (StringUtils.isEmpty(paramLocationFrom)) {
-                    paramLocationFrom = flowConfigHeaderVO.getLocationFrom();
-                }
                 if (StringUtils.isEmpty(paramLocationTo)) {
                     paramLocationTo = flowConfigHeaderVO.getLocationTo();
                 }
@@ -140,43 +135,26 @@ public class BusinessServiceImpl implements IBusinessService {
                     zoneIdList = Arrays.stream(flowConfigHeaderVO.getLocationFrom().split(",")).collect(Collectors.toList());
                 }
 
-                if (flowConfigHeaderVO.getFlowType().equals("ASN")) {
-                    // 统计入库箱数
-                    List<AgvCallItemDTO> agvCallItemDTOList = agvCallDTO.getAgvCallItemDTOList();
-                    int boxNum = agvCallItemDTOList.size();
-//                    int boxNum = agvCallItemDTOList.stream()
-//                            .mapToInt(v -> v.getQty().intValue())
-//                            .reduce(Integer::sum).getAsInt();
-                    asnSoStrategy.setAsnHeightLimit(boxNum + "");
-                    log.info("统计箱数量:" + boxNum);
-
-                    List<BaseLocationInfo> locationFromList = this.convertLocation(paramLocationFrom, agvCallDTO.getWarehouseId(), null);
-                    List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), "shift_no+ 0,shift_index");
-                    locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "ASN", asnSoStrategy, token);
-                    locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "ASN", asnSoStrategy, token);
+                List<WcsTask> wcsTaskList = new ArrayList<>();
+                if ("PM_L".equals(flowConfigHeaderVO.getRemark())) {
+                    locationFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(agvCallDTO.getLocationFrom(),Constant.WAREHOUSE_ID);
+                    locationTo =  baseLocationInfoService.selectBaseLocationInfoByIdOrNo(agvCallDTO.getLocationTo(),Constant.WAREHOUSE_ID);
+                    baseLocationInfoService.occupyLocation(locationTo.getId(),Constant.WAREHOUSE_ID,"AMS");
+                    baseLocationInfoService.unOccupyLocation(locationFrom.getId(),Constant.WAREHOUSE_ID,"AMS");
                     wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
 
-                } else if (flowConfigHeaderVO.getFlowType().equals("SO")) {
+                }
+                if ("PM_UP".equals(flowConfigHeaderVO.getRemark())){
                     AgvCallItemDTO agvCall = agvCallDTO.getAgvCallItemDTOList().get(0);
                     List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), null);
                     HashMap<String, String> hashMap = JSON.parseObject(JSON.toJSONString(agvCall.getLotattDTO()), HashMap.class);
                     List<BaseLocationInfo> locationFromList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneIdListOrderBy(zoneIdList
                             , agvCallDTO.getWarehouseId(), hashMap, agvCall.getSku(), "inv.create_time");
-                    locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "SO", asnSoStrategy, token);
-                    locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "SO", asnSoStrategy, token);
-                    wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
-
-                } else if (flowConfigHeaderVO.getFlowType().equals("MV")) {
-                    List<BaseLocationInfo> locationFromList = this.convertLocation(paramLocationFrom, agvCallDTO.getWarehouseId(), null);
-                    List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), null);
-                    locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "MV", asnSoStrategy, token);
-                    locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "MV", asnSoStrategy, token);
-                    // 初始化库存
-                    if (agvCallDTO.getAgvCallItemDTOList().size() > 0) {
-                        iInvLotAttService.deleteInvLotAttBylocationId(locationFrom.getId());
-                        invLotLocIdService.deleteInvLotLocIdById(locationFrom.getId());
-                        invLotLocIdService.initInv(locationFrom.getId().toString(), agvCallDTO);
-                    }
+                    locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "PM_UP", asnSoStrategy, token);
+                    locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "PM_UP", asnSoStrategy, token);
+                    iInvLotAttService.deleteInvLotAttBylocationId(locationTo.getId());
+                    invLotLocIdService.deleteInvLotLocIdById(locationTo.getId());
+                    baseLocationInfoService.updateLocationIdleAndNoEmpty(locationTo.getId(),Constant.WAREHOUSE_ID,"AMS");
                     wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
                 }
             }
@@ -451,22 +429,9 @@ public class BusinessServiceImpl implements IBusinessService {
             wcsTask.setShopId(Constant.WAREHOUSE_ID.toString());
             wcsTask.setCreateDate(new Date());
             wcsTask.setBusinessType("01");
-            wcsTask.setTaskType(Constant.TASK_TYPE.FORWARD.getValue());
+            wcsTask.setTaskType(flowConfigHeaderVO.getFlowType());
             wcsTask.setExt8(token.toString());
             wcsTask.setExt7(flowConfigHeaderVO.getId().toString());
-            wcsTask.setExt6(StringUtils.isNotEmpty(agvCallDTO.getToArea()) ? agvCallDTO.getToArea() : "");
-            // 三向车叉尺方向(货叉朝左1,朝右2,中位或其他0)
-            // 如果起始点是仓储区,左1,右2,我们系统A是靠马路也就是叉尺的右边
-            if (locationFrom.getZoneId() != null
-                    && Objects.equals(locationFrom.getZoneId(), Constant.ZONE_TYPE.STORAGE.getValue())) {
-                wcsTask.setExt4(locationFrom.getRowNo().equals("A") ? "2" : "1");
-            }
-            // 如果起始点是接驳位,默认给1
-            if (locationFrom.getZoneId() != null
-                    && Objects.equals(locationFrom.getZoneId(), Constant.ZONE_TYPE.TRANSIT.getValue())) {
-                wcsTask.setExt4("1");
-            }
-            wcsTask.setExtParam(agvCallDTO.getExtParam());
             wcsTaskList.add(wcsTask);
             businessService.addTask(wcsTask);
         } else {

+ 1 - 1
warewms-ams/src/main/java/com/ruoyi/ams/locationView/service/LocationViewService.java

@@ -189,7 +189,7 @@ public class LocationViewService {
                     .stream()
                     .mapToInt(t -> t.getBaseLocationGuiDTOList().size())
                     .max()
-                    .getAsInt();
+                    .orElse(1);
             basLocationGuiColDTOList.stream().forEach(v -> {
                 int size = v.getBaseLocationGuiDTOList().size();
                 List<BaseLocationGuiDTO> locationGuiDTOList = v.getBaseLocationGuiDTOList();

+ 10 - 8
warewms-ams/src/main/java/com/ruoyi/ams/task/mapper/WcsTaskMapper.java

@@ -7,15 +7,15 @@ import org.apache.ibatis.annotations.Param;
 
 /**
  * AGV任务Mapper接口
- * 
+ *
  * @author andy
  * @date 2022-03-10
  */
-public interface WcsTaskMapper 
+public interface WcsTaskMapper
 {
     /**
      * 查询AGV任务
-     * 
+     *
      * @param taskNo AGV任务主键
      * @return AGV任务
      */
@@ -23,7 +23,7 @@ public interface WcsTaskMapper
 
     /**
      * 查询AGV任务列表
-     * 
+     *
      * @param wcsTask AGV任务
      * @return AGV任务集合
      */
@@ -38,7 +38,7 @@ public interface WcsTaskMapper
 
     /**
      * 新增AGV任务
-     * 
+     *
      * @param wcsTask AGV任务
      * @return 结果
      */
@@ -46,7 +46,7 @@ public interface WcsTaskMapper
 
     /**
      * 修改AGV任务
-     * 
+     *
      * @param wcsTask AGV任务
      * @return 结果
      */
@@ -54,7 +54,7 @@ public interface WcsTaskMapper
 
     /**
      * 删除AGV任务
-     * 
+     *
      * @param taskNo AGV任务主键
      * @return 结果
      */
@@ -62,7 +62,7 @@ public interface WcsTaskMapper
 
     /**
      * 批量删除AGV任务
-     * 
+     *
      * @param taskNos 需要删除的数据主键集合
      * @return 结果
      */
@@ -107,4 +107,6 @@ public interface WcsTaskMapper
      * @return
      */
      List<WcsTask> selectBeforeTask(@Param("taskNo") String taskNo);
+
+    List<WcsTask> getTasking(WcsTask wcsTask);
 }

+ 2 - 0
warewms-ams/src/main/java/com/ruoyi/ams/task/service/IWcsTaskService.java

@@ -175,4 +175,6 @@ public interface IWcsTaskService {
      * @return
      */
     AjaxResult moveStartingPointToDestination(WcsTask wcsTask);
+
+    int moveEmptyPallets(WcsTask wcsTask);
 }

+ 84 - 1
warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java

@@ -1,9 +1,11 @@
 package com.ruoyi.ams.task.service.impl;
 
 import java.lang.reflect.Method;
+import java.rmi.ServerException;
 import java.util.Date;
 import java.util.List;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.ams.agv.ndc.domain.AmsTask;
 import com.ruoyi.ams.agv.ndc.entity.CallbackResult;
 import com.ruoyi.ams.agv.ndc.service.IAmsTaskService;
@@ -21,10 +23,15 @@ import com.ruoyi.base.domain.BaseLocationInfo;
 import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.common.utils.uuid.SnowflakeIdWorker;
 import com.ruoyi.hard.modbus.tcp.AutoDoorClient;
+import com.ruoyi.system.enums.PLCConnectNameEnum;
+import com.ruoyi.system.enums.PLCEnum;
+import com.ruoyi.system.init.PlcConnectServiceRunner;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -66,6 +73,12 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
     @Autowired
     private AutoDoorClient autoDoorClient;
 
+    @Autowired
+    PlcConnectServiceRunner plcConnectServiceRunner;
+
+    @Autowired
+    private IBaseLocationInfoService iBaseLocationInfoService;
+
     //任务状态翻译
     private String codeConvert(int code) {
         switch (code) {
@@ -402,6 +415,20 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                         if (!StringUtils.isEmpty(wcsTask.getExt8())) {
                             redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()));
                         }
+                        if (wcsTask.getTaskType().substring(0, 4).equals("PM_L")) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.STACKING_MACHINE.getMetadata()).writeBoolean(PLCEnum.STACKING_MACHINE_FEEDING_FINISH.getMetadata(), true);
+                        }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_UP_1.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_1.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UP_EMPTY_Leave_1.getMetadata(), true);
+                        }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_UP_2.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_2.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UP_EMPTY_Leave_2.getMetadata(), true);
+                        }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_UP_3.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_2.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UP_EMPTY_Leave_3.getMetadata(), true);
+                        }
+
+
                         break;
                     case 3:
                         break;
@@ -426,12 +453,22 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                         if (!StringUtils.isEmpty(wcsTask.getExt8())) {
                             redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()), wcsTask.getLocationFrom());
                         }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_L_1.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_1.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UNLOADING_Leave_2.getMetadata(), true);
+                        }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_L_2.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_1.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UNLOADING_Leave_2.getMetadata(), true);
+                        }
+                        if (wcsTask.getTaskType().equals(Constant.FLOW_CONFIG_ID.PM_L_3.name())) {
+                            plcConnectServiceRunner.getPlcServer(PLCConnectNameEnum.PACKING_MACHINE_1.getMetadata()).writeBoolean(PLCEnum.PACKING_MACHINE_UNLOADING_Leave_3.getMetadata(), true);
+                        }
+
                         break;
                     case 5:
                         break;
                     case 6://卸货
                         if (wcsTask.getState() != 4
-                                && (StringUtils.isEmpty(wcsTask.getBeforeTask())|| !wcsTask.getBeforeTask().equals("1"))) {
+                                && (StringUtils.isEmpty(wcsTask.getBeforeTask()) || !wcsTask.getBeforeTask().equals("1"))) {
                             log.info("任务未取货,不能直接完成!" + taskNo);
                             return AjaxResult.error("任务未取货,不能直接完成!" + taskNo);
                         }
@@ -585,6 +622,51 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
         return AjaxResult.success();
     }
 
+    @Override
+    public int moveEmptyPallets(WcsTask wcsTask) {
+        BaseLocationInfo formAddress = iBaseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationFrom(), Constant.WAREHOUSE_ID);
+        if (ObjectUtil.isNull(formAddress)) {
+            throw new BaseException("起始位置不存在");
+        }
+        WcsTask task = new WcsTask();
+        task.setLocationFrom(formAddress.getId()+"");
+        List<WcsTask> tasking = wcsTaskMapper.getTasking(task);
+        if (!tasking.isEmpty()){
+            throw new BaseException("起始位置存在任务!");
+        }
+        BaseLocationInfo toAddress = null;
+        BaseLocationInfo baseLocationInfo = new BaseLocationInfo();
+        baseLocationInfo.setIsEmpty("Y");
+        baseLocationInfo.setStockStatus("00");
+        baseLocationInfo.setZoneId(10002L);
+        List<BaseLocationInfo> baseLocationInfos = iBaseLocationInfoService.selectBaseLocationInfoList(baseLocationInfo);
+        for (BaseLocationInfo locationInfo : baseLocationInfos) {
+            task = new WcsTask();
+            task.setLocationTo(locationInfo.getId()+"");
+            tasking = wcsTaskMapper.getTasking(task);
+            if (!tasking.isEmpty()){
+                continue;
+            }
+            toAddress = locationInfo;
+        }
+        if (ObjectUtil.isNull(toAddress)){
+            throw new BaseException("没有合适的空库位");
+        }
+        WcsTask wcsTask1 = new WcsTask();
+        wcsTask1.setTaskNo(System.currentTimeMillis() + "");
+        wcsTask1.setState(9L);
+        wcsTask1.setTaskType("M_EP");
+        wcsTask1.setBusinessType("01");
+        wcsTask1.setAreaFrom(formAddress.getZoneId().toString());
+        wcsTask1.setLocationFrom(formAddress.getId().toString());
+        wcsTask1.setAreaTo(toAddress.getZoneId().toString());
+        wcsTask1.setLocationTo(toAddress.getId().toString());
+        wcsTask1.setCreateUser(SecurityUtils.getLoginUser().getUsername());
+        wcsTask1.setShopId(Constant.WAREHOUSE_ID.toString());
+        wcsTask1.setPriority(10L);
+        return wcsTaskMapper.insertWcsTask(wcsTask1);
+    }
+
     /**
      * 修改库存出入库标记
      *
@@ -642,4 +724,5 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
         }
         return AjaxResult.success();
     }
+
 }

+ 20 - 0
warewms-ams/src/main/resources/mapper/ams/WcsTaskMapper.xml

@@ -337,4 +337,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select * from wcs_task
         where task_no = #{taskNo} and state not in (2,7,4,11,12)
     </select>
+
+    <select id="getTasking" parameterType="WcsTask" resultMap="WcsTaskResult">
+        <include refid="selectWcsTaskVo"/>
+        <where>
+            <if test="locationFrom != null  and locationFrom != ''"> and location_from = #{locationFrom}</if>
+            <if test="areaFrom != null  and areaFrom != ''"> and area_from = #{areaFrom}</if>
+            <if test="locationTo != null  and locationTo != ''"> and location_to = #{locationTo}</if>
+            <if test="areaTo != null  and areaTo != ''"> and area_to = #{areaTo}</if>
+            <if test="priority != null "> and priority = #{priority}</if>
+            <if test="createUser != null  and createUser != ''"> and create_user = #{createUser}</if>
+            <if test="createDate != null "> and create_date = #{createDate}</if>
+            <if test="taskType != null  and taskType != ''"> and task_type = #{taskType}</if>
+            <if test="shopId != null  and shopId != ''"> and shop_id = #{shopId}</if>
+            <if test="startTime != null "> and start_time = #{startTime}</if>
+            <if test="endTime != null "> and end_time = #{endTime}</if>
+            <if test="parentTask != null  and parentTask != ''"> and parent_task = #{parentTask}</if>
+            <if test="agvNo != null  and agvNo != ''"> and agv_no like concat('%', #{agvNo}, '%')</if>
+        </where>
+        and state in(1,3,4,5,6,8,9,10)
+    </select>
 </mapper>

+ 12 - 48
warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java

@@ -29,66 +29,30 @@ public class Constant {
      * 搬运任务配置id
      */
     public enum FLOW_CONFIG_ID {
-        /***
-         * 补空托(空托暂存区)
-         */
-        ONE(1l),
-        /**
-         * 空托上料(硫酸镍)
-         */
-        TWO(2l),
-        /**
-         * 空托上料(氯化镍)
-         */
-        THREE(3l),
-        /**
-         * 废料搬运(硫酸镍)
-         */
-        FOUR(4l),
-        /**
-         * 废料退空(硫酸镍)
-         */
-        FIVE(5l),
-        /**
-         * 废料搬运(氯化镍)
-         */
-        SIX(6l),
-        /**
-         * 废料退空(氯化镍)
-         */
-        SEVEN(7l),
-        /**
-         * 成品下线(硫酸镍)->裹膜
-         */
-        EIGHT(8l),
-        /**
-         * 成品下线(硫酸镍)->仓储区
-         */
-        NINE(9l),
         /**
-         * 成品下线(硫酸镍)-裹膜->仓储区
+         * 一号包装机下料
          */
-        TEN(10l),
+        PM_L_1(26L),
         /**
-         * 成品下线(氯化镍)->裹膜
+         * 二号包装机下料
          */
-        ELEVEN(11l),
+        PM_L_2(27L),
         /**
-         * 成品下线(氯化镍)->仓储区
+         * 三号包装机下料
          */
-        TWELVE(12l),
+        PM_L_3(28L),
         /**
-         * 成品下线(氯化镍)-裹膜->仓储区
+         * 一号包装机上空托
          */
-        THIRTEEN(13l),
+        PM_UP_1(29L),
         /**
-         * 成品出库(硫酸镍)
+         * 一号包装机上空托
          */
-        FOURTEEN(14l),
+        PM_UP_2(30L),
         /**
-         * 成品出库(氯化镍)
+         * 三号包装机上空托
          */
-        FIFTEEN(15l);
+        PM_UP_3(31L);
 
         private Long flowId;