自动化立体仓库 - WMS系统
#
pang.jiabao
2025-12-03 52b21b24130c75197c039ae0fd761e2ef5b43cb3
#
56个文件已添加
44个文件已修改
2 文件已重命名
5854 ■■■■■ 已修改文件
pom.xml 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/DigitalTwinController.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MesController.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MobileController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/RcsController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/WaitPakinController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/AgvInfo.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BlockStation.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BlockTask.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocCount.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocDetl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/MatItemBarcode.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/Task.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/TaskDetlLog.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WaitPakin.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkDetl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkMast.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtDetainMatVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtEquipmentVo.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtInAndOutBoundVo.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtLocDetailVo.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtLocVo.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtOrderVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/digitaltwin/DtOverviewVo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesCallOutApply.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesInApply.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesMatInfo.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesMatRecvForm.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesOutApply.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesOutFeedback.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesParent.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesRecvFeedback.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/MesReturn.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/TransArrivalStation.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/TransInOutStationAllow.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/TransParent.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/TransTask.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/mes/TransTaskFeedback.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsEqptNotify.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsReporterEqpt.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsReporterTask.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsReturn.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsTaskCancel.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsTaskContinue.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsTaskSubmit.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/rcs/RcsTaskTargetRoute.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/enums/RcsRetMethodEnum.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/AgvInfoMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BlockStationMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BlockTaskMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/DigitalTwinMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocCountMapper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/MatItemBarcodeMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/DigitalTwinService.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MesService.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MobileService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/RcsService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java 272 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MatServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MesServiceImpl.java 1325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java 624 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/TaskDetlLogServiceImpl.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/TaskLogServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/TaskServiceImpl.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WrkDetlServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/BlockScheduler.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/OrderMoveHistoryScheduler.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java 162 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/WorkMastScheduler.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/OrderSyncHandler.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/VersionUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/ControllerResAdvice.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/LogAspect.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/WebConfig.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/LocTypeDto.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/route/RouteFilter.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/libs/framework-3.2.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback-spring.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BlockStationMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BlockTaskMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocCountMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/OrderDetlPakinMapper.xml 128 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ViewDigitalTwinMapper.xml 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/common.js 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locDetl/locDetl.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/mat/mat.js 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakin/order.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/task/task.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/waitPakin/waitPakin.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basWhs/basWhs.html 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/mat/mat.html 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pda/comb.html 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pda/login.html 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pda/matQuery.html 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/task/task.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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,8 +105,10 @@
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
            <scope>provided</scope>
            <version>1.18.30</version>
            <optional>true</optional>
<!--            <version>1.16.22</version>-->
<!--            <scope>provided</scope>-->
        </dependency>
        <!-- okHttp3 -->
        <dependency>
@@ -120,13 +124,42 @@
    </dependencies>
    <build>
        <finalName>wms</finalName>
        <finalName>jgwms</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>-->
<!--&lt;!&ndash;                    <include>**/log/**</include>&ndash;&gt;-->
<!--                    <include>**/libs/**</include>-->
<!--&lt;!&ndash;                    <include>**/*.properties</include>&ndash;&gt;-->
<!--&lt;!&ndash;                    <include>**/*.xml</include>&ndash;&gt;-->
<!--                </includes>-->
<!--                <filtering>false</filtering>-->
<!--            </resource>-->
<!--        </resources>-->
    </build>
</project>
src/main/java/com/zy/asrs/controller/DigitalTwinController.java
New file
@@ -0,0 +1,306 @@
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("刀把");
        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("刀具库");
        locDetl2.setMatnr("mat10001");
        locDetl2.setMaktx("刀把");
        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,123 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.core.annotations.AppAuth;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.service.MesService;
import com.zy.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@RestController
@Slf4j
public class MesController extends BaseController {
    @Resource
    private MesService mesService;
    private void auth(String appkey, Object obj, HttpServletRequest request) {
        log.info("{}接口被访问;appkey:{};请求数据:{}", request.getRequestURI(), appkey, JSON.toJSONString(obj));
        request.setAttribute("cache", obj);
    }
    // 物料信息同步
    @PostMapping("/api/mes/synMatInfo")
    @AppAuth(memo = "物料信息同步")
    public MesReturn synMatInfo(@RequestHeader(required = false) String appkey,@RequestBody MesMatRecvForm param, HttpServletRequest request){
        auth(appkey, param, request);
        MesReturn mesReturn = new MesReturn();
        try {
            mesReturn = mesService.matInfoAndInBound(param);
        } catch (Exception e) {
            mesReturn.setSuccess("2");
            mesReturn.setMessage("物料信息同步失败");
        }
        return mesReturn;
    }
    // 出库申请
    @PostMapping("/api/mes/outBoundOrder")
    public MesReturn outBoundOrder(@RequestBody MesOutApply 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) == 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);
    }
    // region 临时测试
    @GetMapping("/api/mes/testInFeedback")
    public int test(@RequestParam String orderNo){
        return mesService.inFeedback(orderNo);
    }
    @GetMapping("/api/mes/testInFeedback2")
    public int test(@RequestParam String orderNo, @RequestParam String zapplet){
        return mesService.recvFeedback(orderNo, zapplet);
    }
    // endregion
    // 库存查询接口
    // 按 物料编码+oderNo
    @PostMapping("/api/mes/queryInventory")
    public MesReturn queryInventory(@RequestBody JSONObject param){
        MesReturn mesReturn = new MesReturn();
        String itemno = param.getString("itemno");
        String orderNo = param.getString("orderNo");
        if(Cools.isEmpty(itemno,orderNo)) {
            mesReturn.setSuccess("2");
            mesReturn.setMessage("参数不能为空");
            return mesReturn;
        }
        return mesService.queryInventory(itemno,orderNo);
    }
}
src/main/java/com/zy/asrs/controller/MobileController.java
@@ -525,4 +525,14 @@
        return R.ok("出库成功");
    }
    // pda呼叫空料框出库
    @PostMapping("/callEmptyBinOutBound")
    @ManagerAuth(memo = "pda呼叫空料框出库")
    public synchronized R callEmptyBinOutBound(@RequestBody JSONObject param) {
        if(!param.containsKey("staNo") || !param.containsKey("locType")){ // 1.窄,2.宽
            return R.parse(BaseRes.PARAM);
        }
        return mobileService.callEmptyBinOutBound(param.getString("staNo"),param.getString("locType"),getUserId());
    }
}
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/controller/WaitPakinController.java
@@ -10,9 +10,11 @@
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.R;
import com.zy.asrs.entity.OrderDetlPakin;
import com.zy.asrs.entity.WaitPakin;
import com.zy.asrs.entity.WrkDetl;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.OrderDetlPakinService;
import com.zy.asrs.service.OrderDetlService;
import com.zy.asrs.service.WaitPakinService;
import com.zy.asrs.service.WrkMastService;
@@ -22,6 +24,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -36,6 +39,9 @@
    private OrderDetlService orderDetlService;
    @Autowired
    private WrkMastService wrkMastService;
    @Resource
    private OrderDetlPakinService orderDetlPakinService;
    @RequestMapping(value = "/waitPakin/{id}/auth")
    @ManagerAuth
@@ -113,6 +119,12 @@
                        ,entity.getStandby1(),entity.getStandby2(),entity.getStandby3()
                        ,entity.getBoxType1(),entity.getBoxType2(),entity.getBoxType3()
                        , entity.getAnfme());
                // 恢复到待处理状态
                List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectByOrderId(entity.getOrderId());
                long count = orderDetlPakins.stream().filter(orderDetlPakin -> orderDetlPakin.getWorkQty() != 0).count();
                if (count == 0) {
                    OrderInAndOutUtil.updateOrder(Boolean.TRUE, entity.getOrderId(), 1L, getUserId());
                }
            }
        }
        return R.ok();
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
@@ -18,6 +18,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
@@ -121,7 +122,8 @@
    private Double weight;
    @ApiModelProperty(value= "长度")
    private Double man_length;
    @TableField("man_length")
    private Double manLength;
    @ApiModelProperty(value= "体积")
    private Double volume;
@@ -337,7 +339,7 @@
    }
    public void sync(Object source) {
        Synchro.Copy(source, this);
        BeanUtils.copyProperties(source,this);
    }
    public String getFrozen$() {
src/main/java/com/zy/asrs/entity/MatItemBarcode.java
New file
@@ -0,0 +1,75 @@
package com.zy.asrs.entity;
import com.alibaba.excel.annotation.ExcelProperty;
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("man_mat_item_barcode")
public class MatItemBarcode implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 零件二维码
     */
    @ApiModelProperty(value= "零件二维码")
    @TableId(value = "item_barcode")
    private String itemBarcode;
    /**
     * 零件质量状态
     */
    @ApiModelProperty(value= "零件质量状态")
    @TableId(value = "quality_status")
    private Integer qualityStatus;
    /**
     * 生产订单号
     */
    @ApiModelProperty(value= "生产订单号")
    @TableField("order_no")
    private String orderNo;
    /**
     * 托盘号
     */
    @ApiModelProperty(value= "托盘号")
    @TableField("zapplet")
    private String zapplet;
    /**
     * 库位编号
     */
    @ApiModelProperty(value= "库位编号")
    @ExcelProperty(value = "loc_no")
    private String loc_no;
    /**
     * 运输任务号
     */
    @ApiModelProperty(value= "运输任务号")
    @ExcelProperty(value = "task_no")
    private String taskNo;
    /**
     * 状态,-1 废弃;0 在库;1 运输中;
     */
    @ApiModelProperty(value= "状态")
    @ExcelProperty(value = "status")
    private String status;
    /**
     * 更新时间
     */
    @ApiModelProperty(value= "更新时间")
    @ExcelProperty(value = "update_time")
    private Date updateTime;
}
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$(){
@@ -388,7 +395,7 @@
    public String getTaskType$(){
        if (Cools.isEmpty(this.taskType)){return  null;}
        if (taskType.equals("agv")) {
        if (taskType.equals("AGV")) {
            return "AGV任务";
        } else {
            return "堆垛机任务";
src/main/java/com/zy/asrs/entity/TaskDetlLog.java
@@ -1,8 +1,12 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableField;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.format.annotation.DateTimeFormat;
import com.core.common.SpringUtils;
import com.zy.system.service.UserService;
@@ -26,6 +30,8 @@
    private static final long serialVersionUID = 1L;
    @TableField("id")
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField("log_id")
src/main/java/com/zy/asrs/entity/WaitPakin.java
@@ -8,6 +8,8 @@
import com.zy.asrs.service.BasProcessProceduresService;
import com.zy.asrs.service.BasQualityTestingService;
import com.zy.common.utils.Synchro;
import com.zy.system.entity.User;
import com.zy.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -272,6 +274,15 @@
        return this.boxType1;
    }
    public String getAppeUser$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.appeUser);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getUsername());
        }
        return null;
    }
    public String getBoxType2$(){
        BasQualityTestingService service = SpringUtils.getBean(BasQualityTestingService.class);
        BasQualityTesting basQualityTesting = service.selectOne(new EntityWrapper<BasQualityTesting>().eq("box_type", this.boxType1));
src/main/java/com/zy/asrs/entity/WrkDetl.java
@@ -10,6 +10,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
@@ -401,7 +402,7 @@
    }
    public void sync(Object source) {
        Synchro.Copy(source, this);
        BeanUtils.copyProperties(source,this);
    }
}
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,95 @@
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() {
        ProductInfo = new ArrayList<>();
    }
//    // 任务编号
//    private String taskno;
//    // 任务名称
//    private String taskname;
//    // 生产线编码
//    @JsonProperty("ProductLineId")
//    private String ProductLineId;
//    // 工位编码
//    @JsonProperty("StationId")
//    private String StationId;
// 任务编号
    @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("TuoPanId")
    @JSONField(name = "TuoPanId")
    private String TuoPanId;
    // 数量,托盘零件数量
    @JsonProperty("Qty")
    @JSONField(name = "Qty")
    private Integer Qty;
    // 版本号
    @JsonProperty("VersionNo")
    @JSONField(name = "VersionNo")
    private String VersionNo;
    // 运输类型
    @JsonProperty("TransType")
    @JSONField(name = "TransType")
    private String TransType;
//    // 生产订单号
//    @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;
        // 质量状态,0 OK;1 NG;
        @JsonProperty("QualityStatus")
        @JSONField(name = "QualityStatus")
        private Integer QualityStatus;
    }
}
src/main/java/com/zy/asrs/entity/mes/MesMatInfo.java
New file
@@ -0,0 +1,117 @@
package com.zy.asrs.entity.mes;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
// MES物料信息
@Data
public class MesMatInfo {
    // 物料编码,唯一标识
//    @NotNull
    @JsonProperty("itemNo")
    @JSONField(name = "itemNo")
    private String itemNo;
    // 物料名称
//    @NotNull
    @JsonProperty("description")
    @JSONField(name = "description")
    private String description;
    // 单位
    @JsonProperty("unitOfMeasure")
    @JSONField(name = "unitOfMeasure")
    private String unitOfMeasure;
    // 物料类型
//    @NotNull
    @JsonProperty("itemType")
    @JSONField(name = "itemType")
    private String itemType;
    // 材质
    @JsonProperty("cz")
    @JSONField(name = "cz")
    private String cz;
    // 重量
    @JsonProperty("weight")
    @JSONField(name = "weight")
    private float weight;
    // 物料属性
//    @NotNull
    @JsonProperty("classificationCode")
    @JSONField(name = "classificationCode")
    private String classificationCode;
    // 图号
    @JsonProperty("drawingNo")
    @JSONField(name = "drawingNo")
    private String drawingNo;
    // 设计备注
    @JsonProperty("itemComments")
    @JSONField(name = "itemComments")
    private String itemComments;
    // 创建时间,timestamp
    @JsonProperty("createDate")
    @JSONField(name = "createDate")
    private String createDate;
    // 最近一次修改时间,timestamp
    @JsonProperty("modifiedDate1")
    @JSONField(name = "modifiedDate1")
    private String modifiedDate1;
    // 最近修改人
    @JsonProperty("modifiedOperator1")
    @JSONField(name = "modifiedOperator1")
    private String modifiedOperator1;
    // 生产单位
    @JsonProperty("dept")
    @JSONField(name = "dept")
    private String dept;
    // 是否关键件
    @JsonProperty("gtCode")
    @JSONField(name = "gtCode")
    private String gtCode;
    // 规格型号
    @JsonProperty("specification")
    @JSONField(name = "specification")
    private String specification;
    // 工艺备注
    @JsonProperty("procComments")
    @JSONField(name = "procComments")
    private String procComments;
    // 工艺修改人
    @JsonProperty("procOperator")
    @JSONField(name = "procOperator")
    private String procOperator;
    // 工艺修改时间,timestamp
    @JsonProperty("procModifiedDate")
    @JSONField(name = "procModifiedDate")
    private String procModifiedDate;
    // ABC码
    @JsonProperty("abcCode")
    @JSONField(name = "abcCode")
    private String abcCode;
    // 供应商编码
    @JsonProperty("vendorNo")
    @JSONField(name = "vendorNo")
    private String vendorNo;
    // 版本号
    @JsonProperty("drawingVersion")
    @JSONField(name = "drawingVersion")
    private String drawingVersion;
    // 生产订单号
//    @NotNull
    @JsonProperty("OrderNo")
    @JSONField(name = "OrderNo")
    private String OrderNo;
    // 本单入库数量
//    @NotNull
    @JsonProperty("qty")
    @JSONField(name = "qty")
    private Integer qty;
    // 零件二维码
    @JsonProperty("ItemBarcode")
    @JSONField(name = "ItemBarcode")
    private List<String> ItemBarcode;
}
src/main/java/com/zy/asrs/entity/mes/MesMatRecvForm.java
New file
@@ -0,0 +1,29 @@
package com.zy.asrs.entity.mes;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
// MES发出的领料入库单
@Data
public class MesMatRecvForm {
    // 来源单号
    @JsonProperty("sourceNo")
    @JSONField(name = "sourceNo")
    private String sourceNo;
    // 来源单名称
    @JsonProperty("sourceName")
    @JSONField(name = "sourceName")
    private String sourceName;
    // 操作人
    @JsonProperty("operuser")
    @JSONField(name = "operuser")
    private String operuser;
    // 物料信息
    @JsonProperty("itemdata")
    @JSONField(name = "itemdata")
    private List<MesMatInfo> itemdata;
}
src/main/java/com/zy/asrs/entity/mes/MesOutApply.java
New file
@@ -0,0 +1,48 @@
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 MesOutApply extends MesParent {
//    // 任务编号
//    private String taskno;
//    // 任务名称
//    private String taskname;
//    // 生产订单号
//    @JsonProperty("OrderNo")
//    @JSONField(name = "OrderNo")
//    private String OrderNo;
    // 运输类型,字典值(wms_tranfs_type) 01:立库出空托;02 立库入空托;03 立库出毛坯; 04 立库回毛坯; 05 立库出成品;06 立库入成品;
    @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 List<String> ItemBarcode;
}
src/main/java/com/zy/asrs/entity/mes/MesOutFeedback.java
New file
@@ -0,0 +1,47 @@
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;
// 返回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 List<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,42 @@
package com.zy.asrs.entity.mes;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
// 入库反馈
@Data
public class MesRecvFeedback {
    // 来源单号
    private String sourceNo;
    // 操作人
    @JsonProperty("operuser")
    @JSONField(name = "operuser")
    private String operuser;
    // 反馈信息
    @JsonProperty("itemdata")
    @JSONField(name = "itemdata")
    private List<MesRecvFeedbackItem> itemdata;
    @Data
    public static class MesRecvFeedbackItem {
        // 物料编码
        private String itemNo;
        // 生产订单号
        @JsonProperty("OrderNo")
        @JSONField(name = "OrderNo")
        private String OrderNo;
        // 本单入库数量
        private Integer qty;
        // 本单实际数量
        private Integer realQty;
        // 零件编码
        @JsonProperty("ItemBarcode")
        @JSONField(name = "ItemBarcode")
        private List<String> ItemBarcode;
    }
}
src/main/java/com/zy/asrs/entity/mes/MesReturn.java
New file
@@ -0,0 +1,20 @@
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 MesReturn {
    // 1:成功;2:失败
    @JsonProperty("Success")
    @JSONField(name = "Success")
    private String Success;
    // 失败消息
    @JsonProperty("Message")
    @JSONField(name = "Message")
    private String Message;
}
src/main/java/com/zy/asrs/entity/mes/TransArrivalStation.java
New file
@@ -0,0 +1,58 @@
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;
}
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,71 @@
package com.zy.asrs.entity.mes;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
// 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 List<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;
    // 托盘ID
    @JsonProperty("TuoPanId")
    @JSONField(name = "TuoPanId")
    private String TuoPanId;
}
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/mapper/MatItemBarcodeMapper.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.MatItemBarcode;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface MatItemBarcodeMapper extends BaseMapper<MatItemBarcode> {
}
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,150 @@
package com.zy.asrs.service;
import com.alibaba.fastjson.JSONObject;
import com.zy.asrs.entity.Task;
import com.zy.asrs.entity.mes.*;
import com.zy.asrs.entity.rcs.RcsReporterTask;
public interface MesService {
    /**
     * 物料信息同步
     *
     * @param matRecvForm
     * @return
     */
    MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm);
    /**
     * 领料入库反馈
     * 触发条件:物料同步接口入库单,入库后
     * 推送时机:当订单中有物料入库后(应该在每托入库完成后)则推送,不必等全部订单完成
     *
     * @param orderNo
     * @param zpallet
     * @return
     */
    int recvFeedback(String orderNo, String zpallet);
    /**
     * 出库申请
     *
     * @param mesOutApply
     * @return
     */
    int outBoundOrder(MesOutApply mesOutApply);
    /**
     * 出库申请(叫料),齐套性配盘
     *
     * @param mesCallOutApply
     * @return
     */
    int callOutBoundOrder(MesCallOutApply mesCallOutApply);
    /**
     * 出库完成
     *
     * @param orderNo
     * @return
     */
    int outFeedbackByTuo(String orderNo, Task agvTask);
//    /**
//     * 出库完成
//     *
//     * @param orderNo
//     * @return
//     */
//    int outFeedback(String orderNo);
    /**
     * 入库完成
     *
     * @param orderNo
     * @return
     */
    int inFeedback(String orderNo);
    /**
     * 入库申请
     *
     * @param mesInApply
     * @return
     */
    int inBoundOrder(MesInApply mesInApply);
    /**
     * 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);
    /**
     * 离站请求:转发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);
    MesReturn queryInventory(String itemno,String orderNo);
}
src/main/java/com/zy/asrs/service/MobileService.java
@@ -99,4 +99,12 @@
     * @version 1.0
     */
    R OutCallAgv(AgvCallParams params, Long userId);
    /**
     * pda呼叫空料框出库
     * @param staNo 出库站点
     * @param locType 托盘类型 1.窄,2.宽
     * @param userId 用户id
     */
    R callEmptyBinOutBound(String staNo, String locType, Long userId);
}
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,1325 @@
package com.zy.asrs.service.impl;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
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.param.EmptyPlateOutParam;
import com.zy.asrs.entity.rcs.*;
import com.zy.asrs.mapper.AgvInfoMapper;
import com.zy.asrs.mapper.MatItemBarcodeMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.OrderInAndOutUtil;
import com.zy.common.model.DetlDto;
import com.zy.common.model.enums.WorkNoType;
import com.zy.common.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
@Service
public class MesServiceImpl implements MesService {
    @Value("${mes.url}")
    public String MES_URL;
    @Value("${wms.currentName}")
    public String WMS_CURRENT_NAME;
    @Value("${wms.wmsTransStartStation1}")
    public String WMS_TRANS_START_STATION_1;
    @Value("${wms.wmsTransStartStation2}")
    public String WMS_TRANS_START_STATION_2;
    @Value("${wms.wmsTransStartStation3}")
    public String WMS_TRANS_START_STATION_3;
    @Value("${mes.defaultUserId}")
    public long defaultUserId;
    @Value("${wms.zpalletId}")
    public String WMS_ZPALLET_ID;
    @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 WaitPakinService waitPakinService;
    @Resource
    private TaskService taskService;
    @Resource
    private TaskDetlService taskDetlService;
    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;
    @Resource
    private CommonService commonService;
    @Resource
    private AgvInfoMapper agvInfoMapper;
    @Resource
    private WorkService workService;
    @Resource
    private MatItemBarcodeMapper matItemBarcodeMapper;
    @Resource
    private LocMastService locMastService;
    @Resource
    private LocDetlService locDetlService;
    @Resource
    private MobileService mobileService;
    // region MES接口
    /**
     * 物料信息同步,MES->WMS
     * 功能:同步物料信息->生成入库单
     * 后续流程:入库时,需要实时调用recvFeedback返回入库数量
     *
     * @param matRecvForm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm) throws CoolException {
        MesReturn mesReturn = new MesReturn();
        // 1、物料信息同步
        int matSuccess = 0;
        for (MesMatInfo mesMatInfo : matRecvForm.getItemdata()) {
            if (synMatInfo(mesMatInfo) == 1) {
                matSuccess++;
            } else {
                throw new CoolException("同步物料信息失败");
            }
        }
        // 2、生成入库单
        if (inBoundOrder_List(matRecvForm) == 1) {
            mesReturn.setSuccess("1");
            mesReturn.setMessage("");
        } else {
            throw new CoolException("同步物料信息,生成入库单失败");
        }
        return mesReturn;
    }
    /**
     * 新增、修改物料信息
     *
     * @param mesMatInfo
     * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败;
     * @throws ParseException
     */
    public int synMatInfo(MesMatInfo mesMatInfo) {
        // 规则定义:默认第2层为库名(如:加工库),第3层为同步的物料类型
        long secondPath = 2;
        String secondParentName = WMS_CURRENT_NAME;
        Date now = new Date();
        // 物料类型更新
        long tagId = 0;
        EntityWrapper<Tag> wrapper = new EntityWrapper<>();
        wrapper.eq("name", mesMatInfo.getItemType());
        Tag tag = tagService.selectByName(mesMatInfo.getItemType(), 3);
        if (tag == null || StringUtils.isEmpty(tag.getName())) {
            Tag newTag = new Tag();
            newTag.setName(mesMatInfo.getItemType());
            newTag.setParentId(secondPath);
            newTag.setParentName(secondParentName);
            newTag.setPath("2");
            newTag.setPathName(secondParentName);
            newTag.setLevel(3);
            newTag.setStatus(1);
            newTag.setCreateBy(defaultUserId);
            newTag.setCreateTime(now);
            newTag.setUpdateBy(defaultUserId);
            newTag.setUpdateTime(now);
            if (!tagService.insert(newTag))
                return -1;
            tagId = newTag.getId();
        } else {
            tagId = tag.getId();
        }
        // 物料更新
        if (tagId > 0) {
            //        tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId();
            Mat mat = matService.selectByMatnr(mesMatInfo.getItemNo());
            Mat newMat = new Mat();
            newMat.setMatnr(mesMatInfo.getItemNo());
            newMat.setMaktx(mesMatInfo.getDescription());
            newMat.setTagId(tagId);
            newMat.setLocType(tagId);   //locType
            newMat.setSpecs(mesMatInfo.getSpecification());
            newMat.setUnit(mesMatInfo.getUnitOfMeasure());
            newMat.setModel(mesMatInfo.getClassificationCode());
            newMat.setMemo(JSONObject.toJSONString(mesMatInfo));
            newMat.setCreateBy(defaultUserId);
            newMat.setCreateTime(now);
            newMat.setUpdateBy(defaultUserId);
            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");
                dbMemo.remove("ItemBarcode");
                JSONObject newMemo = JSONObject.parseObject(newMat.getMemo());
                newMemo.remove("OrderNo");
                newMemo.remove("qty");
                dbMemo.remove("ItemBarcode");
                if (!dbMemo.equals(newMemo)) {
                    newMat.setId(mat.getId());
                    if (!matService.updateById(newMat))
                        return -2;
                }
            }
        } else {
            return -1;
        }
        return 1;
    }
    /**
     * 物料同步入库单,按OrderNo生成多个订单
     *
     *
     * @param matRecvForm
     * @return
     */
    public int inBoundOrder_List(MesMatRecvForm matRecvForm){
        long docType = 4;   // docType根据库类型确定
        long settle = 1;
        Date now = new Date();
        // 按OrderNo分组,然后再生成入库单
        List<MesMatInfo> mesInApply = matRecvForm.getItemdata();
        Map<String, List<MesMatInfo>> map = mesInApply.stream().collect(Collectors.groupingBy(MesMatInfo::getOrderNo));
        for (Map.Entry<String, List<MesMatInfo>> entry : map.entrySet()) {
            List<MesMatInfo> list = entry.getValue();
            // 校验订单是否重复
            OrderPakin order = orderPakinService.selectByNo(entry.getKey());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                return -1;
            }
            // 生成订单
            JSONObject newMemo = new JSONObject();
            newMemo.put("sourceNo", matRecvForm.getSourceNo());
            newMemo.put("sourceName", matRecvForm.getSourceName());
            newMemo.put("operuser", matRecvForm.getOperuser());
            newMemo.put("itemdata", list);
            OrderPakin orderPakin = new OrderPakin();
            orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
            orderPakin.setOrderNo(entry.getKey());
            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(newMemo.toJSONString());  //为领料入库完成反馈保存   JSONObject.toJSONString(matRecvForm)
            orderPakin.setPakinPakoutStatus(1);
            if (!orderPakinService.insert(orderPakin)) {
                log.error("MES保存入库订单主档失败");
                throw new CoolException("保存入库订单主档失败");
            }
            // 生成明细
            for (MesMatInfo mesMat : list) {
                Mat mat = matService.selectByMatnr(mesMat.getItemNo());
                OrderDetlPakin orderDetlPakin = new OrderDetlPakin();
                orderDetlPakin.setOrderId(orderPakin.getId());
                orderDetlPakin.setOrderNo(orderPakin.getOrderNo());
                orderDetlPakin.setAnfme(Double.valueOf(mesMat.getQty()));
                orderDetlPakin.setQty(0.0);
                orderDetlPakin.setMatnr(mat.getMatnr());
                orderDetlPakin.setMaktx(mat.getMaktx());
                orderDetlPakin.setSpecs(mat.getSpecs());
                orderDetlPakin.setModel(mat.getModel());
                orderDetlPakin.setStandby1(JSONObject.toJSONString(mesMat.getItemBarcode()));   // 零件二维码
                orderDetlPakin.setStandby2("1");  //保存齐套性检查标识,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");
                }
            }
        }
        return 1;
    }
    /**
     * 领料入库反馈
     * 触发条件:物料同步接口入库单,入库后
     * 推送时机:当订单中有物料入库后(应该在每托入库完成后,可以在更新OrderDetlPakin之后)则推送,不等全部订单完成
     *
     * @param orderNo
     * @param zapplet
     * @return
     */
    public int recvFeedback(String orderNo, String zapplet) {
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            List<MesRecvFeedback.MesRecvFeedbackItem> list = new ArrayList<>();
            JSONObject dbMemo = JSONObject.parseObject(order.getMemo());
            // 从组托信息中查询入库的信息
            EntityWrapper<WaitPakin> waitPakinEntityWrapper = new EntityWrapper<>();
            waitPakinEntityWrapper.eq("zpallet", zapplet);
            List<WaitPakin> zpalletMat = waitPakinService.selectList(waitPakinEntityWrapper);
            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) {
                    for (WaitPakin zMat : zpalletMat) {
                        if (orderDetl.getMatnr().equals(zMat.getMatnr())) {
                            MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem();
                            item.setItemNo(orderDetl.getMatnr());
                            item.setOrderNo(orderNo);
                            item.setQty(orderDetl.getAnfme().intValue());
                            item.setRealQty(zMat.getAnfme().intValue());
                            // 回传托盘绑定的零件二维码
                            EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();
                            matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);
                            List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);
                            if (barcodes != null) {
                                List<String> itemBarcode = new ArrayList<>();
                                for (MatItemBarcode barcode : barcodes) {
                                    itemBarcode.add(barcode.getItemBarcode());
                                }
                                item.setItemBarcode(itemBarcode);
                                list.add(item);
                            }
                        }
                    }
                }
            }
            MesRecvFeedback mesRecvFeedback = new MesRecvFeedback();
            mesRecvFeedback.setSourceNo(dbMemo.getString("sourceNo"));
            mesRecvFeedback.setOperuser(dbMemo.getString("operuser"));
            mesRecvFeedback.setItemdata(list);
            String url = MES_URL + "MaterialReceiptAndReturn";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    return 1;
                }
            }
        }
        return 0;
    }
    /**
     * 出库申请,加工库、刀具库
     * 出库后需要自动呼叫AGV送货
     * 出库规则:需要按零件二维码(一件一码)出库,整托出库,该托上有其他物料也一起出库,他们后期会再入库
     *
     * @param mesOutApply
     * @return 1 成功;-1 订单重复;
     */
    public int outBoundOrder(MesOutApply mesOutApply){
        // 空托出库
        if (StringUtils.isEmpty(mesOutApply.getOrderNo()) && "01".equals(mesOutApply.getTransType())) {
            // 生成空托出库任务
            mobileService.callEmptyBinOutBound(WMS_TRANS_START_STATION_1,"1",defaultUserId);
            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(mesOutApply.getTransType());
                    transTask.setCurStationId(WMS_TRANS_START_STATION_1);
                    transTask.setNextProcess(mesOutApply.getProductLineId());
                    transTask.setNextStationId(mesOutApply.getStationId());
                    transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码
                    transTask.setQty(1);    // 空托只出1个
                    transTask.setProductLineId(mesOutApply.getProductLineId());
                    transTask.setOperateType(1);
                    transTask.setAgvFactory(1);
                    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;
        } else {    // 毛坯(物料)出库
            // docType根据库类型确定
            long docType = 7;
            long settle = 1;
            // 校验订单是否重复
            OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                log.error("出库订单号重复:{}",mesOutApply.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("保存出库订单主档失败");
            }
            // 生成明细
            Mat mat = matService.selectByMatnr(mesOutApply.getItemno());
            OrderDetlPakout orderDetlPakout = new OrderDetlPakout();
            orderDetlPakout.setOrderId(orderPakout.getId());
            orderDetlPakout.setOrderNo(orderPakout.getOrderNo());
            orderDetlPakout.setAnfme(Double.valueOf(mesOutApply.getQty()));
            orderDetlPakout.setQty(0.0);
            orderDetlPakout.setMatnr(mat.getMatnr());
            orderDetlPakout.setMaktx(mat.getMaktx());
            orderDetlPakout.setSpecs(mat.getSpecs());
            orderDetlPakout.setModel(mat.getModel());
            orderDetlPakout.setStandby1(barCodeListToStr(mesOutApply.getItemBarcode()));
            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:若AGV和输送线没有安全交互,则要保证立库出货完成后再呼叫AGV。
            // 立库生成订单后,自动调度AGV运送到站点,目前多托生成多个。
            try {
                if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) {
                    // 按零件二维码查询有几个托,多托生成多个任务,每托对应零件二维码
                    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());
                            }
                            TransTask transTask = new TransTask();
                            transTask.setTaskno(mesOutApply.getTaskno());
                            transTask.setTaskname(mesOutApply.getTaskname());
                            transTask.setOrderNo(mesOutApply.getOrderNo());
                            transTask.setTransType(mesOutApply.getTransType());
                            transTask.setCurStationId(WMS_TRANS_START_STATION_3);
                            transTask.setNextProcess(mesOutApply.getProductLineId());
                            transTask.setNextStationId(mesOutApply.getStationId());
                            transTask.setItemno(mesOutApply.getItemno());
                            transTask.setQty(list.size());
                            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));
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error("下发AGV运输任务失败", e);
            }
        }
        return 1;
    }
    /**
     * 入库申请
     * 收到入库申请后自动呼叫AGV取货
     *
     * @param mesInApply
     */
    @Transactional
    public int inBoundOrder(MesInApply mesInApply){
        // 空托回库
        if (StringUtils.isEmpty(mesInApply.getOrderNo()) && StringUtils.isEmpty(mesInApply.getItemno())) {
                if (!StringUtils.isEmpty(mesInApply.getTaskno()) && !StringUtils.isEmpty(mesInApply.getStationID())) {
                    TransTask transTask = new TransTask();
                    transTask.setTaskno(mesInApply.getTaskno());
                    transTask.setTaskname(mesInApply.getTaskname());
                    transTask.setOrderNo(mesInApply.getOrderNo());
                    transTask.setTransType(mesInApply.getTransType());
                    transTask.setCurProcess(mesInApply.getProductLineId());
                    transTask.setCurStationId(mesInApply.getStationID());
                    transTask.setNextStationId(WMS_TRANS_START_STATION_2);
                    transTask.setItemno(WMS_ZPALLET_ID);  // 固定为空托的编码
                    transTask.setQty(1);    // 空托只回1个
                    transTask.setProductLineId(mesInApply.getProductLineId());
                    transTask.setOperateType(1);
                    transTask.setAgvFactory(1);
                    JSONObject sendAgvTask = submitTask(transTask);
                    if (!"1".equals(sendAgvTask.getString("Success"))) {
                        log.error("出库下发agv运输任务失败,{}", JSONObject.toJSONString(transTask));
                        return 2;
                    }
                } else {
                    log.error("无任务号:{},或无物料编码:{}",mesInApply.getTaskno(),mesInApply.getItemno() );
                    return 2;
                }
            return 1;
        } else {    // 毛坯、成品回库
            // docType根据库类型确定
            long docType = 3;
            long settle = 1;
            // 校验订单是否重复
            OrderPakin order = orderPakinService.selectByNo(mesInApply.getOrderNo());
            if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
                log.error("订单重复:{}", mesInApply.getOrderNo());
                return 2;
            }
            // 生成订单
            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);
            orderPakinService.insert(orderPakin);
            // 生成明细
            Mat mat = matService.selectByMatnr(mesInApply.getItemno());
            OrderDetlPakin orderDetlPakin = new OrderDetlPakin();
            orderDetlPakin.setOrderId(orderPakin.getId());
            orderDetlPakin.setOrderNo(orderPakin.getOrderNo());
            orderDetlPakin.setAnfme(Double.valueOf(mesInApply.getQty()));
            orderDetlPakin.setQty(0.0);
            orderDetlPakin.setMatnr(mat.getMatnr());
            orderDetlPakin.setMaktx(mat.getMaktx());
            orderDetlPakin.setSpecs(mat.getSpecs());
            orderDetlPakin.setModel(mat.getModel());
            if (mesInApply.getProductInfo() != null) {
                orderDetlPakin.setStandby1(JSONObject.toJSONString(mesInApply.getProductInfo())); //零件详情存在1
            }
            orderDetlPakin.setStandby2("0");  //保存齐套性检查标识,1 检查;0 不检查;
            orderDetlPakin.setCreateBy(defaultUserId);
            orderDetlPakin.setCreateTime(now);
            orderDetlPakin.setUpdateBy(defaultUserId);
            orderDetlPakin.setUpdateTime(now);
            orderDetlPakin.setStatus(1);
            orderDetlPakin.setPakinPakoutStatus(1);
            orderDetlPakinService.insert(orderDetlPakin);
            // 生成入库通知档
            WaitPakin waitPakin = new WaitPakin();
            BeanUtils.copyProperties(mat, waitPakin);
//                waitPakin.sync(mat);
            waitPakin.setOrderNo(orderPakin.getOrderNo());   // 单据编号
            waitPakin.setOrderId(orderPakin.getId());
            waitPakin.setZpallet(mesInApply.getTuoPanId());   // 托盘码
            waitPakin.setIoStatus("N");     // 入出状态
            waitPakin.setAnfme(orderDetlPakin.getAnfme());  // 数量
            waitPakin.setStatus("Y");    // 状态
            waitPakin.setAppeUser(defaultUserId);
            waitPakin.setAppeTime(now);
            waitPakin.setModiUser(defaultUserId);
            waitPakin.setModiTime(now);
            List<String> itemBarcode = mesInApply.getProductInfo().stream().map(MesInApply.ProductInfo::getItemBarcode).collect(Collectors.toList());
            waitPakin.setStandby1(barCodeListToStr(itemBarcode));
            waitPakinService.insert(waitPakin);
            OrderInAndOutUtil.increaseWorkQty(Boolean.TRUE, orderPakin.getId(), orderDetlPakin.getMatnr(), orderDetlPakin.getBatch(),
                    orderDetlPakin.getBrand(), orderDetlPakin.getStandby1(), orderDetlPakin.getStandby2(), orderDetlPakin.getStandby3(),
                    orderDetlPakin.getBoxType1(), orderDetlPakin.getBoxType2(), orderDetlPakin.getBoxType3(), orderDetlPakin.getAnfme());
            OrderInAndOutUtil.updateOrder(Boolean.TRUE, orderPakin.getId(), 2L, defaultUserId);
            // 呼叫AGV从产线运回立库
            try {
                if (!StringUtils.isEmpty(mesInApply.getTaskno())) {
                    TransTask transTask = new TransTask();
                    transTask.setTaskno(mesInApply.getTaskno());
                    transTask.setTaskname(mesInApply.getTaskname());
                    transTask.setOrderNo(mesInApply.getOrderNo());
                    transTask.setTransType(mesInApply.getTransType());
                    transTask.setCurProcess(mesInApply.getProductLineId());
                    transTask.setCurStationId(mesInApply.getStationID());
                    transTask.setNextStationId(WMS_TRANS_START_STATION_2);
                    transTask.setItemno(mesInApply.getItemno());
                    transTask.setQty(mesInApply.getQty());
                    transTask.setProductLineId(mesInApply.getProductLineId());
                    transTask.setItemBarcode(itemBarcode);
                    transTask.setTuoPanId(mesInApply.getTuoPanId());
                    transTask.setOperateType(1);
                    transTask.setAgvFactory(1);
                    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 orderNo
     * @return
     */
    public int outFeedbackByTuo(String orderNo, Task agvTask) {
        int success = 0;
        OrderPakout order = orderPakoutService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            JSONObject dbMemo = JSONObject.parseObject(order.getMemo());
            // TODO:出库完成后,若未解绑托盘和物料,则执行托盘解绑
            // TODO:出库完成后,若未清除零件二维码,则执行清除,也可以在AGV送货完成后清除
//            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) {
//                    StringBuilder palletId = new StringBuilder();
//                    EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>();
//                    wrapper2.eq("order_no", orderDetl.getOrderNo());
//                    List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2);
//                    if (waitPakins != null && waitPakins.size() > 0) {
//                        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());
//                    mesOutFeedback.setTuoPanId(zpalletId);
//                    mesOutFeedback.setQty(orderDetl.getQty().intValue());
//                    if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) {
//                        mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
//                    }
//                    mesOutFeedback.setOrderNo(orderNo);
//                }
//            }
            EntityWrapper<TaskDetl> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("wrk_no", agvTask.getWrkNo());
            TaskDetl taskDetl = taskDetlService.selectOne(entityWrapper);
            String zpalletId = taskDetl.getZpallet();
            List<String> itemBarCode = new ArrayList<>();
            JSONArray array = JSONArray.parseArray(taskDetl.getMemo());
            for (Object one : array) {
                itemBarCode.add(one.toString());
                // TODO:入库时存储零件码(ItemBarCode),并绑定托盘,出库后这里考虑解绑
            }
            MesOutFeedback mesOutFeedback = new MesOutFeedback();
            mesOutFeedback.setTaskno(agvTask.getTaskNo());
            mesOutFeedback.setTaskname(dbMemo.getString("taskname"));
            mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId"));
            mesOutFeedback.setStationId(dbMemo.getString("StationId"));
            mesOutFeedback.setItemno(dbMemo.getString("Itemno"));
            mesOutFeedback.setTuoPanId(zpalletId);
            if (itemBarCode != null && itemBarCode.size() > 0) {
                mesOutFeedback.setQty(itemBarCode.size());
                mesOutFeedback.setItemBarcode(itemBarCode);
            }
            mesOutFeedback.setOrderNo(orderNo);
            String url = MES_URL + "issueComplete";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    success = 1;
                }
            }
        }
        return success;
    }
    /**
     * 入库完成
     * 入库后,按托推送,非整个订单
     *
     * @param orderNo
     * @param zapplet
     * @return
     */
    public int inFeedbackByTuo(String orderNo, String zapplet) {
        int success = 0;
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            List<MesInApply.ProductInfo> list = new ArrayList<>();
            // 从托盘绑定的零件二维码中查询信息
            EntityWrapper<MatItemBarcode> matItemBarcodeEntityWrapper = new EntityWrapper<>();
            matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1);
            List<MatItemBarcode> barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper);
            for (MatItemBarcode barcode : barcodes) {
                MesInApply.ProductInfo productInfo = new MesInApply.ProductInfo();
                productInfo.setItemBarcode(barcode.getItemBarcode());
                productInfo.setQualityStatus(barcode.getQualityStatus());
                list.add(productInfo);
            }
            MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class);
            result.setProductInfo(list);
            result.setQty(list.size());
            String url = MES_URL + "loadComplete";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));
            if (!StringUtils.isEmpty(response) && response.contains("Success")){
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if("1".equals(mesReturn.getSuccess())) {
                    success = 1;
                }
            }
        }
        return success;
    }
    /**
     * 零件二维码,数组转string
     *
     * @param list
     * @return
     */
    public static String barCodeListToStr(List<String> list) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String str : list) {
            stringBuilder.append(str).append(",");
        }
        String result = stringBuilder.toString();
        return result.endsWith(",") ? result.substring(0, result.length() - 1) : result;
    }
    /**
     * 零件二维码,string转数组
     *
     * @param str
     * @return
     */
    public static List<String> barCodeStrToList(String str) {
        String[] array = str.split(",");
        return Arrays.asList(array);
    }
    /**
     * 入库完成
     * 入库单完成后,整单推送
     *
     * @param orderNo
     * @return
     */
    public int inFeedback(String orderNo) {
        int success = 0;
        OrderPakin order = orderPakinService.selectByNo(orderNo);
        if (order != null && !StringUtils.isEmpty(order.getOrderNo())) {
            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.setQty(orderDetl.getQty().intValue());
                    String url = MES_URL + "loadComplete";
                    String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));
                    if (!StringUtils.isEmpty(response) && response.contains("Success")){
                        MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                        if("1".equals(mesReturn.getSuccess())) {
                            success++;
                        }
                    }
                }
                if (success == orderDetlPakins.size()) {
                    success = 1;
                } else {
                    success = 0;
                }
            }
        }
        return success;
    }
    /**
     * (备份)出库订单完成
     *
     * @param orderNo
     * @return
     */
    public int outFeedback(String orderNo) {
        int success = 0;
        OrderPakout order = orderPakoutService.selectByNo(orderNo);
        if (order != null && order.getSettle() == 4) {   // 校验是否完成
            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) {
                    StringBuilder palletId = new StringBuilder();
                    EntityWrapper<WaitPakin> wrapper2 = new EntityWrapper<>();
                    wrapper2.eq("order_no", orderDetl.getOrderNo());
                    List<WaitPakin> waitPakins = waitPakinService.selectList(wrapper2);
                    if (waitPakins != null && waitPakins.size() > 0) {
                        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(orderDetl.getQty().intValue());
                    if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) {
                        mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
                    }
                    mesOutFeedback.setOrderNo(orderNo);
                    // TODO:备注:出库完成后解绑托盘和物料,若前面未解绑,此处需要解绑
                    String url = MES_URL + "issueComplete";
                    String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback));
                    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;
                    // TODO:立库出库后自动调度AGV运送到站点
                    String taskNo = dbMemo.getString("taskno");
                    if (!StringUtils.isEmpty(taskNo)) {
                        TransTask transTask = new TransTask();
                        transTask.setTaskno(dbMemo.getString("taskno"));
                        transTask.setTaskname(dbMemo.getString("taskname"));
                        transTask.setOrderNo(dbMemo.getString("OrderNo"));
                        transTask.setTransType(dbMemo.getString("TransType"));
//                    transTask.setCurProcess();
                        transTask.setCurStationId(WMS_TRANS_START_STATION_1);
                        transTask.setNextProcess(dbMemo.getString("ProductLineId"));
                        transTask.setNextStationId(dbMemo.getString("StationId"));
                        transTask.setItemno(dbMemo.getString("Itemno"));
                        transTask.setQty(dbMemo.getInteger("Qty"));
                        transTask.setProductLineId(dbMemo.getString("ProductLineId"));
                        transTask.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode")));
                        transTask.setOperateType(1);
                        transTask.setAgvFactory(1);
                        JSONObject sendAgvTask = submitTask(transTask);
                        if (!"1".equals(sendAgvTask.getString("Success"))) {
                            log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask));
                        }
                    }
                } else {
                    success = 0;
                }
            }
        }
        return success;
    }
    /**
     * 出库申请(叫料),装配库、滑块库
     *
     * @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;
    }
    // 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()) {
            log.error("agv任务号重复:{}", transTask.getTaskno());
            result.put("Success", "2");
            result.put("Message", "agv任务号重复:" + transTask.getTaskno());
            return result;
        }
        // 下发给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());
        int success = 1;
        if (success == 1) {
            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.setSourceStaNo(transTask.getCurStationId());
            task.setStaNo(transTask.getNextStationId());
            task.setBarcode(transTask.getTuoPanId());
            task.setModiUser(defaultUserId);
            task.setModiTime(now);
            task.setAppeUser(defaultUserId);
            task.setAppeTime(now);
            task.setTaskNo(transTask.getTaskno());
            task.setMemo(JSONObject.toJSONString(transTask));
            taskService.insert(task);
            Mat mat = matService.selectByMatnr(transTask.getItemno());
            TaskDetl taskDetl = new TaskDetl();
            taskDetl.setWrkNo(task.getWrkNo());
            taskDetl.setIoTime(task.getIoTime());
            taskDetl.setMatnr(transTask.getItemno());
            taskDetl.setAnfme(0.0);
            taskDetl.setStandby1(String.valueOf(transTask.getQty()));
            taskDetl.setMaktx(mat.getMaktx());
            taskDetl.setSpecs(mat.getSpecs());
            taskDetl.setOrderNo(transTask.getOrderNo());
            taskDetl.setZpallet(transTask.getTuoPanId());
            taskDetl.setMemo(JSONObject.toJSONString(transTask.getItemBarcode()));
            taskDetl.setModiUser(defaultUserId);
            taskDetl.setModiTime(now);
            taskDetl.setAppeUser(defaultUserId);
            taskDetl.setAppeTime(now);
            taskDetlService.insert(taskDetl);
            result.put("Success", "1");
            result.put("Message", "任务接收成功");
        } else {
            result.put("Success", "2");
            result.put("Message", "任务下发给RCS失败");
        }
        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, JSONObject.toJSONString(transTaskFeedback));
            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, JSONObject.toJSONString(apply));
        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 path = ("LL").equals(apply.getProductLineId()) ? "AGVTransportPalletNotice" : "AprsAGVTransportPalletNotice";
        String url = MES_URL + path;
        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) {
        if ("01".equals(arrivalStation.getDaotype())) {
            arrivalStation.setItemno(null);
            arrivalStation.setItemBarcode(new ArrayList<>());
            arrivalStation.setOrderNo(null);
        }
        String url = MES_URL + "AGVArrivalCompleted";
        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 + "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 MesReturn queryInventory(String itemno,String orderNo) {
        MesReturn mesReturn = new MesReturn();
        mesReturn.setSuccess("1");
        List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr", itemno).eq("order_no",orderNo));
        int count = 0;
        for(LocDetl locDetl:locDetls) {
            count += locDetl.getAnfme();
        }
        mesReturn.setMessage(String.valueOf(count));
        return mesReturn;
    }
    // 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/MobileServiceImpl.java
@@ -632,7 +632,7 @@
            param.getCombMats().forEach(elem -> {
                Order order = OrderInAndOutUtil.selectByNo(Boolean.TRUE, elem.getOrderNo());
                if (Cools.isEmpty(order) || order.getSettle() > 2) {
                    throw new CoolException("单据编号已过期");
                    throw new CoolException("订单号不存在或者已执行完成");
                }
                // 订单明细数量校验
//                OrderDetl orderDetl = OrderInAndOutUtil.selectItem(Boolean.TRUE, order.getId(), elem.getMatnr(), elem.getBatch(), elem.getBrand(), elem.getStandby1(), elem.getStandby2(), elem.getStandby3(),
@@ -663,38 +663,38 @@
                }
            });
            BasContainer container = basContainerService.selectOne(new EntityWrapper<BasContainer>().eq("barcode", param.getBarcode()));
            if (Objects.isNull(container)) {
                throw new CoolException("数据错误:容器码不存在!!");
            }
            if (container.getMixMax() < detlDtos.size()) {
                throw new CoolException("超出容器最大混装数量,当前容器最大数量为:" + container.getMixMax() + "!!");
            }
            Set<String> matnrs = detlDtos.stream().map(DetlDto::getMatnr).collect(Collectors.toSet());
            List<Mat> mats = matService.selectList(new EntityWrapper<Mat>().in("matnr", matnrs));
            Set<Long> tagIds = mats.stream().map(Mat::getTagId).collect(Collectors.toSet());
            if (tagIds.size() > 1) {
                throw new CoolException("组托物料类型不一致,只有相同的物料分类才可以组托!!");
            }
//            BasContainer container = basContainerService.selectOne(new EntityWrapper<BasContainer>().eq("barcode", param.getBarcode()));
//            if (Objects.isNull(container)) {
//                throw new CoolException("数据错误:容器码不存在!!");
//            }
//            if (container.getMixMax() < detlDtos.size()) {
//                throw new CoolException("超出容器最大混装数量,当前容器最大数量为:" + container.getMixMax() + "!!");
//            }
//            Set<String> matnrs = detlDtos.stream().map(DetlDto::getMatnr).collect(Collectors.toSet());
//            List<Mat> mats = matService.selectList(new EntityWrapper<Mat>().in("matnr", matnrs));
//            Set<Long> tagIds = mats.stream().map(Mat::getTagId).collect(Collectors.toSet());
//            if (tagIds.size() > 1) {
//                throw new CoolException("组托物料类型不一致,只有相同的物料分类才可以组托!!");
//            }
            //还可以放入多少种物料
            Integer suplus = container.getMixMax();
//            Integer suplus = container.getMixMax();
            for (DetlDto detlDto : detlDtos) {
                Mat mat = matService.selectByMatnr(detlDto.getMatnr());
                if (Cools.isEmpty(mat)) {
                    throw new CoolException(detlDto.getMatnr() + "商品档案不存在");
                }
                //最多可放数量
                Double singleMax = mat.getUpQty() * suplus;
                if (singleMax.compareTo(detlDto.getAnfme()) < 0) {
                    throw new CoolException("物料:" + detlDto.getMatnr() + "单次组托上限为:" + mat.getUpQty() + ",当前总量超出托盘装载上限!!");
                }
                BigDecimal decimal = new BigDecimal(detlDto.getAnfme() / mat.getUpQty());
                //当前物料需要占用料箱格数
                Integer curr = decimal.setScale(0, RoundingMode.CEILING).intValue();
                suplus = suplus - curr;
                if (suplus < 0) {
                    throw new CoolException("物料:" + detlDto.getMatnr() + ", 超出当前托盘装载上限!!");
                }
//                Double singleMax = mat.getUpQty() * suplus;
//                if (singleMax.compareTo(detlDto.getAnfme()) < 0) {
//                    throw new CoolException("物料:" + detlDto.getMatnr() + "单次组托上限为:" + mat.getUpQty() + ",当前总量超出托盘装载上限!!");
//                }
//                BigDecimal decimal = new BigDecimal(detlDto.getAnfme() / mat.getUpQty());
//                //当前物料需要占用料箱格数
//                Integer curr = decimal.setScale(0, RoundingMode.CEILING).intValue();
//                suplus = suplus - curr;
//                if (suplus < 0) {
//                    throw new CoolException("物料:" + detlDto.getMatnr() + ", 超出当前托盘装载上限!!");
//                }
                WaitPakin waitPakin = new WaitPakin();
                BeanUtils.copyProperties(mat, waitPakin);
@@ -1272,6 +1272,57 @@
        return R.ok();
    }
    @Override
    @Transactional
    public R callEmptyBinOutBound(String staNo, String locType, Long userId) {
        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", 'D').eq("loc_type2", locType));
        if(locMast == null) {
            return R.parse("该类型:" + locType +"空托盘不存在");
        }
        // 获取路径
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", 110)
                .eq("stn_no", staNo)
                .eq("crn_no", locMast.getCrnNo());
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (staDesc == null) {
            R.parse("出库路径不存在,站点:" + staNo);
        }
        Date now = new Date();
        // 生成工作档
        int workNo = commonService.getWorkNo(WorkNoType.PAKOUT.type);
        WrkMast wrkMast = new WrkMast();
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(now);
        wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
        wrkMast.setIoType(110); // 入出库状态: 110.空板出库
        wrkMast.setIoPri(10D);
        wrkMast.setSourceStaNo(staDesc.getCrnStn$()); // 源站
        wrkMast.setStaNo(staDesc.getStnNo$()); // 目标站
        wrkMast.setCrnNo(staDesc.getCrnNo());
        wrkMast.setSourceLocNo(locMast.getLocNo()); // 源库位
        wrkMast.setFullPlt("N"); // 满板:Y
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setEmptyMk("Y"); // 空板
        wrkMast.setLinkMis("N");
        wrkMast.setAppeUser(userId);
        wrkMast.setAppeTime(now);
        wrkMast.setModiUser(userId);
        wrkMast.setModiTime(now);
        wrkMastService.insert(wrkMast);
        // 更新库位状态
        if (locMast.getLocSts().equals("D")) {
            locMast.setLocSts("R");
            locMast.setModiUser(userId);
            locMast.setModiTime(now);
            locMastService.updateById(locMast);
        }
        return R.ok("出库成功");
    }
    /**
     * @author Ryan
     * @date 2025/9/25
src/main/java/com/zy/asrs/service/impl/RcsServiceImpl.java
New file
@@ -0,0 +1,624 @@
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@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){
        String url = rcsFactory == 2 ? HIK_URL : HX_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 ? HIK_URL : HX_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 ? HIK_URL : HX_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 ? HIK_URL : HX_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");
        String slotCategory = values.getString("slotCategory");
        String slotCode = values.getString("slotCode");
        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: {
                        // TODO:立库出库一托,AGV开始运输后,给MES发送出库完成(一托发一次)
                        JSONObject taskMemo = JSONObject.parseObject(task.getMemo());
                        mesService.outFeedbackByTuo(taskMemo.getString("OrderNo"), task);
                    } 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);
                        String transType = memo.getString("TransType");
                        apply.setTransType(transType);
                        apply.setProductLineId(memo.getString("ProductLineId"));
                        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: {
                        // TODO: 如果产线是运输起点,则不发送到站完成,暂时调试使用lG,未实现判断
                        if (rcsReporterTask.getCurrentSeq() == 0 && task.getSourceStaNo().startsWith("LG")) {
                            break;
                        }
                        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.getZpallet());  // memo.getString("TuoPanId")
                        arrivalStation.setProductLineId(memo.getString("ProductLineId"));
                        String transType = memo.getString("TransType");
                        arrivalStation.setDaotype(transType);
                        if(transType.equals("02") || transType.equals("04") || transType.equals("06")) {
                            arrivalStation.setStationID(task.getSourceStaNo());
                        } else {
                            arrivalStation.setStationID(task.getStaNo());
                        }
                        arrivalStation.setOrderNo(memo.getString("OrderNo"));
                        arrivalStation.setAgvCode(singleRobotCode);
                        arrivalStation.setItemno(memo.getString("Itemno"));
                        String memo2 = taskDetl.getMemo();
                        List<String> itemBarCode = new ArrayList<>();
                        Matcher matcher = Pattern.compile("\"([^\"]*)\"").matcher(memo2);
                        while (matcher.find()) {
                            itemBarCode.add(matcher.group(1));
                        }
                        arrivalStation.setItemBarcode(itemBarCode);
                        mesService.arriveOnStation(arrivalStation);
                    } 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/TaskDetlLogServiceImpl.java
@@ -30,18 +30,18 @@
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Integer wrkNo) {
        List<TaskDetl> detls = taskDetlService.selectList(new EntityWrapper<TaskDetl>().eq("wrk_no", wrkNo));
        if (Objects.isNull(detls) || detls.isEmpty()) {
            throw new CoolException("数据错误:任务不存在!!");
        if (!detls.isEmpty()) {
            detls.forEach(detl -> {
                TaskDetlLog detlLog = new TaskDetlLog();
                BeanUtils.copyProperties(detl, detlLog);
                detlLog.setId(null);
                detlLog.setLogId(detl.getId());
                if (!this.insert(detlLog)) {
                    throw new CoolException("工作档明细历史保存失败!!");
                }
            });
        }
        detls.forEach(detl -> {
            TaskDetlLog detlLog = new TaskDetlLog();
            BeanUtils.copyProperties(detl, detlLog);
            detlLog.setId(null);
            detlLog.setLogId(detl.getId());
            if (!this.insert(detlLog)) {
                throw new CoolException("工作档明细历史保存失败!!");
            }
        });
        return false;
        return true;
    }
}
src/main/java/com/zy/asrs/service/impl/TaskLogServiceImpl.java
@@ -40,10 +40,8 @@
        BeanUtils.copyProperties(task, taskLog);
        taskLog.setLogId(task.getId());
        if (!this.insert(taskLog)) {
            throw new CoolException("任务日志保存失败!!");
        }
        this.insert(taskLog);
        return false;
        return true;
    }
}
src/main/java/com/zy/asrs/service/impl/TaskServiceImpl.java
@@ -165,16 +165,16 @@
                locSts = "D";
                // 库位转移 ===>> D.空桶/空栈板
            } else if (wrkMast.getIoType() == 11) {
                locSts = wrkMast.getFullPlt().equalsIgnoreCase("N") ? "D" : "F";
                // 库位转移:目标库位
                LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", wrkMast.getLocNo()));
                if (Cools.isEmpty(locMast)) {
                    throw new CoolException("取消库位转移失败,目标库位不存在:" + wrkMast.getSourceLocNo());
                }
                locMast.setLocSts("O");
                locMast.setModiTime(now);
                locMast.setModiUser(userId);
                locCacheService.updateById(locMast);
//                locSts = wrkMast.getFullPlt().equalsIgnoreCase("N") ? "D" : "F";
//                // 库位转移:目标库位
//                LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", wrkMast.getLocNo()));
//                if (Cools.isEmpty(locMast)) {
//                    throw new CoolException("取消库位转移失败,目标库位不存在:" + wrkMast.getSourceLocNo());
//                }
//                locMast.setLocSts("O");
//                locMast.setModiTime(now);
//                locMast.setModiUser(userId);
//                locCacheService.updateById(locMast);
            }
        } else {
            throw new CoolException("当前工作状态无法取消");
@@ -271,17 +271,17 @@
        }
        // 修改库位状态
        LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", locNo));
        if (Cools.isEmpty(locMast)) {
            throw new CoolException("取消工作档失败,库位不存在:" + locNo);
        }
        locMast.setLocSts(locSts);
        locMast.setModiTime(now);
        locMast.setModiUser(userId);
        boolean locMastRes = locCacheService.updateById(locMast);
        if (!wrkMastRes || !locMastRes) {
            throw new CoolException("保存数据失败");
        }
//        LocCache locMast = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", locNo));
//        if (Cools.isEmpty(locMast)) {
//            throw new CoolException("取消工作档失败,库位不存在:" + locNo);
//        }
//        locMast.setLocSts(locSts);
//        locMast.setModiTime(now);
//        locMast.setModiUser(userId);
//        boolean locMastRes = locCacheService.updateById(locMast);
//        if (!wrkMastRes || !locMastRes) {
//            throw new CoolException("保存数据失败");
//        }
    }
}
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("保存工作档明细失败");
            }
@@ -1224,7 +1235,7 @@
    @Override
    @Transactional
    public void pickWrkMast(String workNo, Long userId) {
        WrkMast wrkMast = wrkMastService.selectById(workNo);
        WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no",workNo));
        if (Cools.isEmpty(wrkMast)) {
            throw new CoolException(workNo + "工作档不存在");
        }
@@ -1247,7 +1258,7 @@
        // 获取目标站
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", wrkMast.getIoType() - 50)
                .eq("stn_no", wrkMast.getStaNo()) // 作业站点 = 拣料出库的目标站
                .eq("stn_no", Integer.parseInt(wrkMast.getStaNo())-2) // 作业站点 = 拣料出库的目标站
                .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
        StaDesc staDesc = staDescService.selectOne(wrapper);
        if (Cools.isEmpty(staDesc)) {
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/OrderMoveHistoryScheduler.java
@@ -6,7 +6,7 @@
import org.springframework.stereotype.Component;
@Component
//@Component
public class OrderMoveHistoryScheduler {
    @Autowired
    private OrderMoveHistoryHandler orderMoveHistoryHandler;
@@ -14,7 +14,7 @@
    /**
     * 将已完成order和orderDetl移动到log表
     */
    @Scheduled(cron = "0/30 * * * * ?")
//    @Scheduled(cron = "0/30 * * * * ?")
    public void execute(){
        orderMoveHistoryHandler.start();
    }
@@ -22,7 +22,7 @@
    /**
     * 将已上报order和orderDetl移动到log表
     */
    @Scheduled(cron = "0/30 * * * * ?")
//    @Scheduled(cron = "0/30 * * * * ?")
    public void executeOrder(){
        orderMoveHistoryHandler.startOrder();
    }
src/main/java/com/zy/asrs/task/OrderSyncScheduler.java
@@ -1,9 +1,15 @@
package com.zy.asrs.task;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
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.*;
import com.zy.asrs.entity.mes.MesInApply;
import com.zy.asrs.entity.mes.MesRecvFeedback;
import com.zy.asrs.entity.mes.MesReturn;
import com.zy.asrs.service.*;
import com.zy.asrs.service.impl.RcsServiceImpl;
import com.zy.asrs.task.core.ReturnT;
import com.zy.asrs.task.handler.OrderSyncHandler;
import com.zy.asrs.utils.OrderInAndOutUtil;
@@ -15,7 +21,11 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * updated by IX in 2024/12/17
@@ -30,6 +40,18 @@
    private OrderService orderService;
    @Autowired
    private ApiLogService apiLogService;
    @Resource
    private OrderPakinService orderPakinService;
    @Resource
    private OrderPakoutService orderPakoutService;
    @Resource
    private MesService mesService;
    @Resource
    private OrderDetlPakinService orderDetlPakinService;
    @Value("${mes.url}")
    public String MES_URL;
    @Value("${erp.switch.ErpReportOld}")
    private boolean ErpReportOld;
@@ -43,7 +65,7 @@
        }
    }
    @Scheduled(cron = "0 1 * * * ? ")
//    @Scheduled(cron = "0 1 * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderIssuedOnceMore() {
        List<Order> orderList = orderService.selectComplete99();
@@ -60,7 +82,7 @@
        }
    }
    @Scheduled(cron = "0/30 * * * * ? ")
//    @Scheduled(cron = "0/30 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderIssued() {
//        String erpReport = Parameter.get().getErpReport();
@@ -101,26 +123,126 @@
//        }
    }
//    @Scheduled(cron = "0/30 * * * * ? ")
    // 入库订单完成上报-领料单,原材料
    @Scheduled(cron = "0/30 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderReport() {
        if (!ErpReportOld){
            return;
        }
    void inOrderCompleteReport() {
        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());
            OrderPakin orderPakin = orderPakinService.selectOne(new EntityWrapper<OrderPakin>().eq("settle", 4)
                    .eq("doc_type",4).orderBy("update_time"));
            if (orderPakin == null) {
                return;
            }
            String orderNo = orderPakin.getOrderNo();
            List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectByOrderId(orderPakin.getId());
            List<MesRecvFeedback.MesRecvFeedbackItem> list = new ArrayList<>();
            JSONObject dbMemo = JSONObject.parseObject(orderPakin.getMemo());
            for (OrderDetlPakin orderDetl : orderDetlPakins) {
                MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem();
                item.setItemNo(orderDetl.getMatnr());
                item.setOrderNo(orderNo);
                item.setQty(orderDetl.getAnfme().intValue());
                item.setRealQty(orderDetl.getAnfme().intValue());
                // 回传托盘绑定的零件二维码
                String itemBarcode = orderDetl.getStandby1();
                List<String> itemBarCodeList = new ArrayList<>();
                Matcher matcher = Pattern.compile("\"([^\"]*)\"").matcher(itemBarcode);
                while (matcher.find()) {
                    itemBarCodeList.add(matcher.group(1));
                }
                item.setItemBarcode(itemBarCodeList);
                list.add(item);
            }
            MesRecvFeedback mesRecvFeedback = new MesRecvFeedback();
            mesRecvFeedback.setSourceNo(dbMemo.getString("sourceNo"));
            mesRecvFeedback.setOperuser(dbMemo.getString("operuser"));
            mesRecvFeedback.setItemdata(list);
            String url = MES_URL + "MaterialReceiptAndReturn";
            String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback));
            if (!StringUtils.isEmpty(response) && response.contains("Success")) {
                MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
                if ("1".equals(mesReturn.getSuccess())) {
                    orderPakin.setSettle(6L);
                    orderPakinService.updateById(orderPakin);
                    log.info("订单上报成功,orderNo={}", orderNo);
                }
            }
        }
    }
    // 其他入库单上报
    @Scheduled(cron = "0/30 * * * * ? ")
    @Async("orderThreadPool")
    void otherInOrderCompleteReport() {
        String erpReport = Parameter.get().getErpReport();
        if (!Cools.isEmpty(erpReport) && erpReport.equals("true")) {
            OrderPakin orderPakin = orderPakinService.selectOne(new EntityWrapper<OrderPakin>().eq("settle", 4)
                    .eq("doc_type", 3).orderBy("update_time"));
            if (orderPakin == null) {
                return;
            }
            List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectByOrderId(orderPakin.getId());
            for (OrderDetlPakin orderDetl : orderDetlPakins) {
                MesInApply result = JSONObject.parseObject(orderPakin.getMemo(), MesInApply.class);
                result.setQty(orderDetl.getQty().intValue());
//                String url = MES_URL + "loadComplete";
//                String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result));
//                if (!StringUtils.isEmpty(response) && response.contains("Success")) {
//                    MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class);
//                    if ("1".equals(mesReturn.getSuccess())) {
                        orderPakin.setSettle(6L);
                        orderPakinService.updateById(orderPakin);
                        log.info("订单上报成功,orderNo={}", orderPakin.getOrderNo());
//                    }
//                }
            }
        }
    }
//    @Scheduled(cron = "0/30 * * * * ? ")
    @Async("orderThreadPool")
    public void completeAndReportOrderReport() {
//        // 入库完成
//        List<OrderPakin> pakins = orderPakinService.selectComplete();
//        for (OrderPakin orderPakin : pakins) {
//            try {
//                 mesService.inFeedback(orderPakin.getOrderNo());
//            } catch (Exception e) {
//                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/asrs/utils/VersionUtils.java
@@ -28,7 +28,7 @@
     **/
    public static boolean locMoveCheckLocTypeComplete(LocMast loc, LocTypeDto dto) {
        // 如果源库位是高库位,目标库位是低库位
        return dto.getLocType1().equals(loc.getLocType1());
        return dto.getLocType1().equals(loc.getLocType2());
    }
}
src/main/java/com/zy/common/config/ControllerResAdvice.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.mes.MesReturn;
import com.zy.asrs.service.ApiLogService;
import com.zy.common.utils.IpTools;
import lombok.extern.slf4j.Slf4j;
@@ -59,6 +60,21 @@
                        );
                    }
                }
                if (o instanceof MesReturn) {
                    MesReturn mesReturn = (MesReturn) o;
                    String appkey = request.getHeader("appkey");
                    Object reqCache = request.getAttribute("cache");
                        // 保存接口日志
                        apiLogService.save(
                                String.valueOf(appAuth),
                                request.getRequestURI(),
                                appkey,
                                IpTools.gainRealIp(request),
                                reqCache==null?"": JSON.toJSONString(reqCache),
                                JSON.toJSONString(o),
                                String.valueOf(mesReturn.getSuccess()).equalsIgnoreCase("1")
                        );
                }
            }
        }
        return o;
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/model/LocTypeDto.java
@@ -26,13 +26,13 @@
    }
    public LocTypeDto(BasDevp basDevp) {
        if (basDevp.getLocType1() == null || basDevp.getLocType1() == 0) {
        if (basDevp.getLocType2() == null || basDevp.getLocType2() == 0) {
            throw new CoolException("plc高低检测异常");
        }
        if (basDevp.getLocType1() == 1) {
            this.locType1 = 1; // 低库位
        if (basDevp.getLocType2() == 1) {
            this.locType2 = 1; // 低库位
        } else {
            this.locType1 = 2; // 高库位
            this.locType2 = 2; // 高库位
        }
        log.info(JSON.toJSONString(this));
    }
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/service/CommonService.java
@@ -156,6 +156,37 @@
        return null;
    }
    @Transactional
    public StartupDto getLocNoNew(Integer staDescId,Integer sourceStaNo, LocTypeDto locTypeDto) {
        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().eq("crn_sts", 3).eq("crn_err", 0).eq("in_enable", "Y"));
        if(basCrnps.size() == 0) {
            log.error("入库请求库位失败:堆垛机报警/无可用/无可入");
            throw new CoolException("入库请求库位失败:堆垛机报警/无可用/无可入");
        }
        StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("type_no", staDescId).eq("stn_no", sourceStaNo).eq("crn_no", 1));
        if (staDesc == null) {
            log.error("入库请求库位失败:路径不存在" + staDescId +"," + sourceStaNo);
            throw new CoolException("入库请求库位失败:路径不存在" + staDescId +"," + sourceStaNo);
        }
        Short locType2 = locTypeDto.getLocType2();
        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", "O").eq("loc_type2", locType2).orderBy("lev1").orderBy("bay1").orderBy("row1"));
        if (locMast == null) {
            log.error("入库请求库位失败:无库位" + locType2);
            throw new CoolException("入库请求库位失败:无库位" + locType2);
        }
        StartupDto startupDto = new StartupDto();
        startupDto.setWorkNo(getWorkNo(0));
        startupDto.setCrnNo(locMast.getCrnNo());
        startupDto.setSourceStaNo(staDesc.getCrnStn());
        startupDto.setStaNo(staDesc.getStnNo());
        startupDto.setLocNo(locMast.getLocNo());
        return startupDto;
    }
    /**
     * 检索库位号
     *
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) {
@@ -86,7 +88,7 @@
        // 源站点状态检测
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getSourceStaNo(), true);
        sourceStaNo.setLocType1(param.getLocType1());
        sourceStaNo.setLocType2(param.getLocType1());
        LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
        StartupDto dto = null;
@@ -166,8 +168,9 @@
//        List<String> matnrs = waitPakins.stream().map(WaitPakin::getMatnr).distinct().collect(Collectors.toList());
//        List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList());
//        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(matnrs.get(0), batchs.get(0));
        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0));
        StartupDto dto = commonService.getLocNo( 1, devpNo,findLocNoAttributeVo, locTypeDto);
//        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0));
//        StartupDto dto = commonService.getLocNo( 1, devpNo,findLocNoAttributeVo, locTypeDto);
        StartupDto dto = commonService.getLocNoNew(1,devpNo,locTypeDto);
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
src/main/resources/application-dev.yml
@@ -1,5 +1,5 @@
server:
  port: 8080
  port: 8089
  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=jgwms
#    username: sa
#    password: Skyouc#23
#    url: jdbc:sqlserver://192.168.4.24:1433;databasename=jsxswms
  mvc:
    static-path-pattern: /**
  redis:
@@ -109,4 +112,34 @@
    acctID: "647e849ab6fa0f"
    username: "llw"
    password: "666666"
    lcid: 2052
    lcid: 2052
#分库配置
wms:
  #当前是第几库
  currentId: 2
  #当前库名称
  currentName: 加工库
  #立库AGV自动运货出库口编码
  wmsTransStartStation1: 205
  #立库AGV自动运货入库口编码(输送线)
  wmsTransStartStation2: 202
  #立库AGV自动运货出库口编码(输送线)
  wmsTransStartStation3: 204
  #托盘物料号
  zpalletId: tuopan
#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/
src/main/resources/libs/framework-3.2.0.jar
Binary files differ
src/main/resources/logback-spring.xml
@@ -19,6 +19,9 @@
        </encoder>
    </appender>
    <!-- 日志保存路径 -->
    <property name="LOG_PATH" value="D:/wmslogs/jg" />
    <!--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 &gt; #{startDate} AND date &lt; #{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/LocDetlMapper.xml
@@ -20,6 +20,7 @@
        <result column="price" property="price" />
        <result column="sku" property="sku" />
        <result column="units" property="units" />
        <result column="units" property="units" />
        <result column="barcode" property="barcode" />
        <result column="origin" property="origin" />
        <result column="manu" property="manu" />
src/main/resources/mapper/OrderDetlPakinMapper.xml
@@ -57,70 +57,70 @@
    </resultMap>
    <sql id="standbyAll">
        <choose>
            <when test="batch != null and batch != ''">
                and batch = #{batch}
            </when>
            <otherwise>
                and (batch IS NULL OR batch = '')
            </otherwise>
        </choose>
        <choose>
            <when test="brand != null and brand != ''">
                and brand = #{brand}
            </when>
            <otherwise>
                and (brand IS NULL OR brand = '')
            </otherwise>
        </choose>
        <choose>
            <when test="standby1 != null and standby1 != ''">
                and standby1 = #{standby1}
            </when>
            <otherwise>
                and (standby1 IS NULL OR standby1 = '')
            </otherwise>
        </choose>
        <choose>
            <when test="standby2 != null and standby2 != ''">
                and standby2 = #{standby2}
            </when>
            <otherwise>
                and (standby2 IS NULL OR standby2 = '')
            </otherwise>
        </choose>
        <choose>
            <when test="standby3 != null and standby3 != ''">
                and standby3 = #{standby3}
            </when>
            <otherwise>
                and (standby3 IS NULL OR standby3 = '')
            </otherwise>
        </choose>
        <choose>
            <when test="boxType1 != null and boxType1 != ''">
                and box_type1 = #{boxType1}
            </when>
            <otherwise>
                and (box_type1 IS NULL OR box_type1 = '')
            </otherwise>
        </choose>
        <choose>
            <when test="boxType2 != null and boxType2 != ''">
                and box_type2 = #{boxType2}
            </when>
            <otherwise>
                and (box_type2 IS NULL OR box_type2 = '')
            </otherwise>
        </choose>
        <choose>
            <when test="boxType3 != null and boxType3 != ''">
                and box_type3 = #{boxType3}
            </when>
            <otherwise>
                and (box_type3 IS NULL OR box_type3 = '')
            </otherwise>
        </choose>
<!--        <choose>-->
<!--            <when test="batch != null and batch != ''">-->
<!--                and batch = #{batch}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (batch IS NULL OR batch = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="brand != null and brand != ''">-->
<!--                and brand = #{brand}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (brand IS NULL OR brand = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="standby1 != null and standby1 != ''">-->
<!--                and standby1 = #{standby1}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (standby1 IS NULL OR standby1 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="standby2 != null and standby2 != ''">-->
<!--                and standby2 = #{standby2}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (standby2 IS NULL OR standby2 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="standby3 != null and standby3 != ''">-->
<!--                and standby3 = #{standby3}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (standby3 IS NULL OR standby3 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="boxType1 != null and boxType1 != ''">-->
<!--                and box_type1 = #{boxType1}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (box_type1 IS NULL OR box_type1 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="boxType2 != null and boxType2 != ''">-->
<!--                and box_type2 = #{boxType2}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (box_type2 IS NULL OR box_type2 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
<!--        <choose>-->
<!--            <when test="boxType3 != null and boxType3 != ''">-->
<!--                and box_type3 = #{boxType3}-->
<!--            </when>-->
<!--            <otherwise>-->
<!--                and (box_type3 IS NULL OR box_type3 = '')-->
<!--            </otherwise>-->
<!--        </choose>-->
    </sql>
    <sql id="standbyAllMemo">
        --         and line_number = #{lineNumber}
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 &lt; #{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 = "/jgwms";
// 详情窗口-高度
var detailHeight = '80%';
@@ -180,15 +180,15 @@
}
var matCols = [
    {field: 'matnr', align: 'center',title: '商品编号(品号)', width: 180}
    {field: 'matnr', align: 'center',title: '物料编号', width: 180}
    // {field: 'id', align: 'center',title: 'ID'}
    // ,{field: 'uuid', align: 'center',title: '编号'}
    ,{field: 'maktx', align: 'center',title: '商品名称(品名)', width: 200}
    ,{field: 'maktx', align: 'center',title: '物料名称', width: 200}
    ,{field: 'specs', align: 'center',title: '规格'}
    ,{field: 'model', align: 'center',title: '代码', hide: true}
    ,{field: 'model', align: 'center',title: '属性'}
    ,{field: 'color', align: 'center',title: '颜色', hide: true}
    ,{field: 'brand', align: 'center',title: '品牌', hide: true}
    ,{field: 'upQty', align: 'center',title: '组托上限'}
    // ,{field: 'upQty', align: 'center',title: '组托上限'}
    ,{field: 'unit', align: 'center',title: '单位', hide: false}
    ,{field: 'price', align: 'center',title: '单价', hide: true}
    ,{field: 'sku', align: 'center',title: 'sku', hide: true}
@@ -213,10 +213,11 @@
    ,{field: 'danger$', align: 'center',title: '危险品', hide: true}
    // ,{field: 'status$', align: 'center',title: '状态'}
    // ,{field: 'createBy$', align: 'center',title: '添加人员'}
    // ,{field: 'createTime$', align: 'center',title: '添加时间'}
    ,{field: 'memo', align: 'center',title: '备注', hide: false}
    ,{field: 'createTime$', align: 'center',title: '添加时间',width: 165}
    ,{field: 'updateBy$', align: 'center',title: '修改人员', hide: true}
    ,{field: 'updateTime$', align: 'center',title: '修改时间', hide: true}
    ,{field: 'memo', align: 'center',title: '备注', hide: true}
]
@@ -242,14 +243,14 @@
]
var detlCols = [
    {field: 'matnr', align: 'center',title: '商品编号(品号)', sort:true}
    ,{field: 'maktx', align: 'center',title: '商品名称(品名)', sort:true}
    {field: 'matnr', align: 'center',title: '物料编号', sort:true}
    ,{field: 'maktx', align: 'center',title: '物料名称', sort:true}
    ,{field: 'orderNo', align: 'center',title: '单据编号', hide: false}
    ,{field: 'batch', align: 'center',title: '货品特征', sort:true}
    // ,{field: 'batch', align: 'center',title: '货品特征', sort:true}
    ,{field: 'anfme', align: 'center',title: '数量', hide: false}
    ,{field: 'zpallet', align: 'center',title: '托盘条码', hide: false}
    ,{field: 'specs', align: 'center',title: '规格', hide: false}
    ,{field: 'model', align: 'center',title: '代码', hide: true}
    ,{field: 'model', align: 'center',title: '属性', hide: false}
    ,{field: 'color', align: 'center',title: '颜色', hide: true}
    ,{field: 'brand', align: 'center',title: '品牌', hide: true}
    ,{field: 'unit', align: 'center',title: '单位', hide: false}
src/main/webapp/static/js/locDetl/locDetl.js
@@ -6,8 +6,8 @@
        ,{field: 'storeDate', align: 'center',title: '库龄(天)', sort:true}
        ,{field: 'matnr', align: 'center',title: '商品编号', sort:true}
        ,{field: 'maktx', align: 'center',title: '商品名称', sort:true}
        ,{field: 'orderNo', align: 'center',title: '单据编号', hide: true}
        ,{field: 'batch', align: 'center',title: '批号', width: 300, sort:true}
        ,{field: 'orderNo', align: 'center',title: '单据编号'}
        ,{field: 'batch', align: 'center',title: '批号', width: 300, hide:true}
        ,{field: 'anfme', align: 'center',title: '数量'}
        ,{field: 'zpallet', align: 'center',title: '托盘条码'}
        ,{field: 'specs', align: 'center',title: '规格'}
src/main/webapp/static/js/mat/mat.js
@@ -6,7 +6,7 @@
    var cols = [
        {type: 'checkbox'}
        , {field: 'tagId$', align: 'center', title: '归类', templet: '#tagTpl'}
        , {field: 'locType$', align: 'center', title: '库位类型'}
        // , {field: 'locType$', align: 'center', title: '库位类型'}
        // ,{field: 'store_max', align: 'center',title: '库存上限'}
        // ,{field: 'store_min', align: 'center',title: '库存下限'}
        // ,{field: 'store_max_date', align: 'center',title: '库龄上限(天)'}
@@ -211,52 +211,53 @@
                    });
                }
                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":
            //     console.log('顶顶顶')
            //     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/static/js/orderPakin/order.js
@@ -45,9 +45,9 @@
            {field: 'orderNo', title: '单据编号', templet: '#orderNoTpl'},
            {field: 'docType$', align: 'center', title: '类型',  minWidth: 160, width: 160},
            {align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160},
            {field: 'memo', align: 'center',title: '备注'},
            {field: 'createTime$', title: '创建时间', minWidth: 200, width: 200},
            {field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl',  minWidth: 160, width: 160},
            {field: 'memo', align: 'center',title: '备注', hide: true},
            {align: 'center', title: '操作', toolbar: '#operate', width: 180}
        ]],
        request: {
@@ -122,12 +122,15 @@
                        cellMinWidth: 100,
                        cols: [[
                            {type: 'numbers'},
                            {field: 'matnr', title: '商品编码', width: 160},
                            {field: 'maktx', title: '商品名称', width: 160},
                            {field: 'batch', title: '批号'},
                            {field: 'matnr', title: '商品编码'},
                            {field: 'maktx', title: '商品名称'},
                            {field: 'specs', title: '规格'},
                            // {field: 'batch', title: '批号'},
                            {field: 'anfme', title: '数量'},
                            {field: 'workQty', title: '作业数量'},
                            {field: 'qty', title: '完成数量', style: 'font-weight: bold'},
                            {field: 'standby1', title: '零件二维码'},
                            {field: 'standby2', title: '齐套性检查'}
                            // {field: 'unit', title: '单位'},
                            // {
                            //     field: 'createTime$', title: '创建时间', sort: true, templet: function (d) {
@@ -136,7 +139,7 @@
                            // },
                            // {field: 'inQty', title: '已入库量'},
                            // {field: 'color', title: '颜色'},
                            {field: 'specs', title: '规格'}
                        ]],
                        request: {
                            pageName: 'curr',
src/main/webapp/static/js/task/task.js
@@ -22,20 +22,23 @@
        height: 'full-120',
        cols: [[
            {type: 'checkbox'}
            , {field: 'wrkNo', align: 'center', title: '工作号', sort: true, width: 105}
            , {field: 'ioTime$', align: 'center', title: '工作时间', width: 160}
            , {field: 'wrkNo', align: 'center', title: '工作号', sort: true}
            , {field: 'taskNo', align: 'center', title: 'AGV任务号', sort: true}
            // , {field: 'ioTime$', align: 'center', title: '工作时间', width: 160}
            , {field: 'wrkSts$', align: 'center', title: '工作状态', width: 150}
            , {field: 'ioType$', align: 'center', title: '入出库类型', width: 150}
            , {field: 'ioPri', align: 'center', title: '优先级', width: 80}
            , {field: 'taskType$', align: 'center', title: '任务类型'}
            , {field: 'crnNo$', align: 'center', title: '堆垛机', hide: true}
            , {field: 'sourceStaNo$', align: 'center', title: '源站'}
            , {field: 'staNo$', align: 'center', title: '目标站', width: 120}
            , {field: 'sourceLocNo', align: 'center', title: '源库位', width: 120}
            , {field: 'locNo', align: 'center', title: '目标库位', width: 120}
            , {field: 'sourceStaNo', align: 'center', title: '源站'}
            , {field: 'staNo', align: 'center', title: '目标站', width: 120}
            // , {field: 'sourceLocNo', align: 'center', title: '源库位', width: 120}
            // , {field: 'locNo', align: 'center', title: '目标库位', width: 120}
            , {field: 'barcode', align: 'center', title: '条码', width: 110}
            , {field: 'preHave', align: 'center', title: '先入品', hide: true}
            , {field: 'takeNone', align: 'center', title: '空操作', hide: true}
            // , {field: 'preHave', align: 'center', title: '先入品', hide: true}
            // , {field: 'takeNone', align: 'center', title: '空操作', hide: true}
            , {field: 'modiUser$', align: 'center', title: '创建人员'}
            , {field: 'appeTime$', align: 'center', title: '创建时间'}
            , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
            , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true, width: 160}
            , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 200}
@@ -171,7 +174,7 @@
                        title: '工作号:' + data.wrkNo,
                        shadeClose: true
                    }, function () {
                        http.post(baseUrl + "/hand/control/wrkMast", {workNo: data.wrkNo, type: 2}, function (res) {
                        http.post(baseUrl + "/task/control", {workNo: data.wrkNo, type: 2}, function (res) {
                            $(".layui-laypage-btn")[0].click();
                            layer.msg(data.wrkNo + res.msg);
                        })
@@ -182,7 +185,7 @@
                        title: '工作号:' + data.wrkNo,
                        shadeClose: true
                    }, function () {
                        http.post(baseUrl + "/hand/control/wrkMast", {workNo: data.wrkNo, type: 2}, function (res) {
                        http.post(baseUrl + "/task/control", {workNo: data.wrkNo, type: 2}, function (res) {
                            $(".layui-laypage-btn")[0].click();
                            layer.msg(data.wrkNo + res.msg);
                        })
@@ -193,7 +196,7 @@
            //  拣料入库
            case 'pick':
                layer.confirm('拣料入库该笔工作档?', {title: '工作号:' + data.wrkNo, shadeClose: true}, function () {
                    http.post(baseUrl + "/hand/control/wrkMast", {workNo: data.wrkNo, type: 3}, function (res) {
                    http.post(baseUrl + "/task/control", {workNo: data.wrkNo, type: 3}, function (res) {
                        $(".layui-laypage-btn")[0].click();
                        layer.msg(data.wrkNo + res.msg);
                    })
src/main/webapp/static/js/waitPakin/waitPakin.js
@@ -24,8 +24,8 @@
                return html;
            }
        }
        , {field: 'modiUser$', align: 'center', title: '修改人员', hide: true}
        , {field: 'modiTime$', align: 'center', title: '修改时间', hide: true})
        ,{field: 'appeUser$', align: 'center',title: '创建人', hide: false}
        ,{field: 'appeTime$', align: 'center',title: '创建时间', hide: false})
    return cols;
}
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/mat/mat.html
@@ -97,12 +97,12 @@
                                <input name="maktx" class="layui-input" placeholder="输入商品名称"/>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <label class="layui-form-label" style="padding: 8px 15px 8px 15px">商品规格:</label>
                            <div class="layui-input-inline">
                                <input name="specs" class="layui-input" placeholder="输入商品规格"/>
                            </div>
                        </div>
<!--                        <div class="layui-inline">-->
<!--                            <label class="layui-form-label" style="padding: 8px 15px 8px 15px">商品规格:</label>-->
<!--                            <div class="layui-input-inline">-->
<!--                                <input name="specs" class="layui-input" placeholder="输入商品规格"/>-->
<!--                            </div>-->
<!--                        </div>-->
                        <div class="layui-inline">&emsp;
                            <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                                <i class="layui-icon">&#xe615;</i>搜索
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);
src/main/webapp/views/task/task.html
@@ -19,7 +19,7 @@
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off">
                            <input class="layui-input" type="text" name="wrk_no" placeholder="工作号" autocomplete="off">
                        </div>
                    </div>
                    <div class="layui-inline" style="width: 300px">