zhang
9 天以前 a9cf56a7be8b5e27e2c3dcb416b734093e7a8dc3
Merge branch 'rcs_master' into ctu_conveyor
1个文件已删除
6个文件已添加
42个文件已修改
1128 ■■■■ 已修改文件
version/db/new.sql 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/db/sqlIndex 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/AGV-RCS 通信协议 V1.0.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/AGV-RCS 通信协议 V1.1.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/RCS开发进度表.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/charge/AGV自动充电机-调度无线启动模式充电流程图.docx 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/charge/APL-AGV锂电智能充电机调度标准协议-Modbus RTU V4.2.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/HeightDepthDto.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyReleaseToConveyorSta.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyReleaseToShelvesLoc.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyTakeFromConveyorSta.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyTakeFromShelvesLoc.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/utils/Base62.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/utils/Utils.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/i18n/en.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/i18n/zh.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/tool.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/StaCreate.jsx 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/StaEdit.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/StaList.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/StaPanel.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/rowSx.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/travel/TravelList.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/conveyor/ConveyorController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/conveyor/SiemensConveyorStationService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/dto/ConveyorQueryResult.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/wms/OpenController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/ConveyorAutoRunScheduler.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/KernelScheduler.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AllocateService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TransferStationHandler.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/StaController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Segment.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Sta.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Travel.java 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AgvService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/SegmentService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/StaService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/TravelService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/BusServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/SegmentServiceImpl.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/StaServiceImpl.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/TravelServiceImpl.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/db/new.sql
@@ -1,2 +1,31 @@
alter table man_code
    add dir_rule varchar(255) null comment '方向规则' after corner;
alter table man_travel
    add roller_waiting int(1) default 0 null comment '滚筒线等待' after task_ids;
alter table man_travel
    add roller_waiting_code bigint null comment '滚筒线等待地码' after roller_waiting;
alter table man_travel_log
    add roller_waiting int(1) default 0 null comment '滚筒线等待' after task_ids;
alter table man_travel_log
    add roller_waiting_code bigint null comment '滚筒线等待地码' after roller_waiting;
CREATE INDEX idx_agv_state_wait
    ON man_travel (agv_id, state, roller_waiting, deleted);
alter table man_sta
    add height decimal(24, 9) null comment '作业高度' after offset;
alter table man_sta
    add depth decimal(24, 9) null comment '作业深度' after height;
alter table man_sta
    add inbound_wait int null comment '连续入库等待' after angle;
alter table man_sta
    add outbound_wait int null comment '连续出库等待' after inbound_wait;
version/db/sqlIndex
@@ -1,3 +1,4 @@
# todo idx ==> deleted
# man_action
CREATE INDEX idx_agv_action ON man_action(agv_id, action_sts);
CREATE INDEX idx_group_io_time ON man_action(group_id, io_time);
@@ -8,7 +9,8 @@
# man_action_type
CREATE INDEX idx_action_type_uuid ON man_action_type(uuid);
# man_travel
CREATE INDEX idx_agv_id_state on man_travel(agv_id, state);
CREATE INDEX idx_agv_id_state ON man_travel(agv_id, state);
CREATE INDEX idx_agv_state_wait ON man_travel (agv_id, state, roller_waiting, deleted);
# man_agv_model
CREATE INDEX idx_agv_model_type ON man_agv_model(type);
# man_bus_sts
version/doc/AGV-RCS ͨÐÅЭÒé V1.0.xlsx
Binary files differ
version/doc/AGV-RCS ͨÐÅЭÒé V1.1.xlsx
Binary files differ
version/doc/RCS¿ª·¢½ø¶È±í.xlsx
Binary files differ
version/doc/charge/AGV×Ô¶¯³äµç»ú-µ÷¶ÈÎÞÏ߯ô¶¯Ä£Ê½³äµçÁ÷³Ìͼ.docx
Binary files differ
version/doc/charge/APL-AGV﮵çÖÇÄܳäµç»úµ÷¶È±ê׼ЭÒé-Modbus RTU V4.2.xlsx
Binary files differ
zy-acs-common/src/main/java/com/zy/acs/common/domain/HeightDepthDto.java
New file
@@ -0,0 +1,34 @@
package com.zy.acs.common.domain;
import com.zy.acs.framework.exception.CoolException;
import lombok.Data;
import java.io.Serializable;
@Data
public class HeightDepthDto implements Serializable {
    private static final long serialVersionUID = 1304095271854524735L;
    // é«˜åº¦ï¼ˆmm)
    private Short height;
    // æ·±åº¦ï¼ˆmm)
    private Short depth;
    public HeightDepthDto() {
    }
    public HeightDepthDto(Number height, Number depth) {
        this.height = toShort(height);
        this.depth  = toShort(depth);
    }
    private static Short toShort(Number value) {
        if (value == null) {
            throw new CoolException("HeightDepthDto parameter is null");
        }
        return value.shortValue();
    }
}
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyReleaseToConveyorSta.java
@@ -20,6 +20,15 @@
    @Override
    public byte[] writeToBytes() {
        return Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] heightBytes = Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] depthBytes = Utils.reverse(RadixTools.shortToByte(this.depth));
//        return Utils.merge(heightBytes, depthBytes);
//        byte heightByte = (byte) ((this.height == null ? 0 : this.height) & 0xFF);
//        byte depthByte  = (byte) ((this.depth  == null ? 0 : this.depth)  & 0xFF);
//        return Utils.merge(heightByte, depthByte);
//        return new byte[]{ heightByte, depthByte };
    }
    @Override
@@ -30,4 +39,7 @@
    // å–货高度
    private Short height;
    // å–货深度
    private Short depth;
}
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyReleaseToShelvesLoc.java
@@ -1,8 +1,8 @@
package com.zy.acs.common.domain.protocol.action;
import com.zy.acs.framework.common.RadixTools;
import com.zy.acs.common.domain.protocol.IActionBody;
import com.zy.acs.common.utils.Utils;
import com.zy.acs.framework.common.RadixTools;
import lombok.Data;
import java.io.Serializable;
@@ -20,6 +20,15 @@
    @Override
    public byte[] writeToBytes() {
        return Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] heightBytes = Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] depthBytes = Utils.reverse(RadixTools.shortToByte(this.depth));
//        return Utils.merge(heightBytes, depthBytes);
//        byte heightByte = (byte) ((this.height == null ? 0 : this.height) & 0xFF);
//        byte depthByte  = (byte) ((this.depth  == null ? 0 : this.depth)  & 0xFF);
//        return Utils.merge(heightByte, depthByte);
//        return new byte[]{ heightByte, depthByte };
    }
    @Override
@@ -30,4 +39,7 @@
    // å–货高度
    private Short height;
    // å–货深度
    private Short depth;
}
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyTakeFromConveyorSta.java
@@ -20,7 +20,17 @@
    @Override
    public byte[] writeToBytes() {
        return Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] heightBytes = Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] depthBytes = Utils.reverse(RadixTools.shortToByte(this.depth));
//        return Utils.merge(heightBytes, depthBytes);
//        byte heightByte = (byte) ((this.height == null ? 0 : this.height) & 0xFF);
//        byte depthByte  = (byte) ((this.depth  == null ? 0 : this.depth)  & 0xFF);
//        return Utils.merge(heightByte, depthByte);
//        return new byte[]{ heightByte, depthByte };
    }
    @Override
    public void readFromBytes(byte[] messageBodyBytes) {
@@ -30,4 +40,7 @@
    // å–货高度
    private Short height;
    // å–货深度
    private Short depth;
}
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/ReadyTakeFromShelvesLoc.java
@@ -1,8 +1,8 @@
package com.zy.acs.common.domain.protocol.action;
import com.zy.acs.framework.common.RadixTools;
import com.zy.acs.common.domain.protocol.IActionBody;
import com.zy.acs.common.utils.Utils;
import com.zy.acs.framework.common.RadixTools;
import lombok.Data;
import java.io.Serializable;
@@ -20,7 +20,17 @@
    @Override
    public byte[] writeToBytes() {
        return Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] heightBytes = Utils.reverse(RadixTools.shortToByte(this.height));
//        byte[] depthBytes = Utils.reverse(RadixTools.shortToByte(this.depth));
//        return Utils.merge(heightBytes, depthBytes);
//        byte heightByte = (byte) ((this.height == null ? 0 : this.height) & 0xFF);
//        byte depthByte  = (byte) ((this.depth  == null ? 0 : this.depth)  & 0xFF);
//        return Utils.merge(heightByte, depthByte);
//        return new byte[]{ heightByte, depthByte };
    }
    @Override
    public void readFromBytes(byte[] messageBodyBytes) {
@@ -30,4 +40,7 @@
    // å–货高度
    private Short height;
    // å–货深度
    private Short depth;
}
zy-acs-common/src/main/java/com/zy/acs/common/utils/Base62.java
New file
@@ -0,0 +1,17 @@
package com.zy.acs.common.utils;
public class Base62 {
    private static final char[] CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    public static String encode(long value) {
        if (value == 0) return "0";
        StringBuilder sb = new StringBuilder();
        while (value > 0) {
            sb.append(CHARS[(int) (value % 62)]);
            value /= 62;
        }
        return sb.reverse().toString();
    }
}
zy-acs-common/src/main/java/com/zy/acs/common/utils/Utils.java
@@ -1,6 +1,7 @@
package com.zy.acs.common.utils;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SnowflakeIdWorker;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
@@ -252,6 +253,10 @@
        return str;
    }
    public static void main(String[] args) {
        System.out.println(Base62.encode(new SnowflakeIdWorker().nextId()));
    }
    public static String generateSeqNum(String lastSeqNum) {
        if (Cools.isEmpty(lastSeqNum)) {
            return zeroFill("1", 4);
zy-acs-flow/src/i18n/en.js
@@ -92,7 +92,8 @@
        earlier: 'Earlier...',
    },
    validate: {
        pwdMisMatch: 'The password confirmation is not the same as the password.'
        pwdMisMatch: 'The password confirmation is not the same as the password.',
        gtZero: 'The value must be greater than 0.',
    },
    settings: {
        base: 'Base',
@@ -287,7 +288,11 @@
                staType: "station type",
                code: "code",
                offset: "offset",
                height: "height",
                depth: "depth",
                angle: 'angle',
                inboundWait: 'inbound wait(ms)',
                outboundWait: 'outbound wait(ms)',
                autoing: "autoing",
                loading: "loading",
                inEnable: "in enable",
@@ -493,6 +498,8 @@
                currSeg: "curr seg",
                taskContent: "tasks",
                taskIds: "task list",
                rollerWaiting: 'roller waiting',
                rollerWaitingCode: 'waiting code',
                state: "state",
            },
            segment: {
@@ -664,6 +671,7 @@
            bottomOffset: 'bottom offset',
        },
        sta: {
            depthHint: 'Set depth to 0 to keep the default value.',
            enums: {
                type: {
                    in: 'UNLOAD',
@@ -722,6 +730,14 @@
                },
            },
        },
        travel: {
            enums: {
                state: {
                    running: 'RUNNING',
                    finish: 'FINISH',
                },
            },
        },
        jam: {
            enums: {
                state: {
zy-acs-flow/src/i18n/zh.js
@@ -92,7 +92,8 @@
        earlier: '更早...',
    },
    validate: {
        pwdMisMatch: '密码不一致'
        pwdMisMatch: '密码不一致',
        gtZero: '请输入大于0的数值',
    },
    settings: {
        base: '基本设置',
@@ -287,7 +288,11 @@
                staType: "站点类型",
                code: "地面码",
                offset: "偏移量",
                height: "作业高度",
                depth: "作业深度",
                angle: '作业角度',
                inboundWait: '入库等待(毫秒)',
                outboundWait: '出库等待(毫秒)',
                autoing: "自动",
                loading: "载货",
                inEnable: "可入",
@@ -493,6 +498,8 @@
                currSeg: "当前作业",
                taskContent: "任务内容",
                taskIds: "任务列表",
                rollerWaiting: '滚筒线等待',
                rollerWaitingCode: '等待位地码',
                state: "状态",
            },
            segment: {
@@ -664,6 +671,7 @@
            bottomOffset: '底部偏移量',
        },
        sta: {
            depthHint: '深度设置为 0 è¡¨ç¤ºæ²¿ç”¨é»˜è®¤å€¼ã€‚',
            enums: {
                type: {
                    in: '放货',
@@ -722,6 +730,14 @@
                },
            },
        },
        travel: {
            enums: {
                state: {
                    running: '正在运行',
                    finish: '已完成',
                },
            },
        },
        jam: {
            enums: {
                state: {
zy-acs-flow/src/map/tool.js
@@ -194,8 +194,8 @@
                    y: (event.global.y - batchMoveStartPos.y) / scaleY
                };
                for (let sprite of selectedSprites) {
                    sprite.position.x = sprite.batchMoveStartPos.x - mouseMovement.x;
                    sprite.position.y = sprite.batchMoveStartPos.y - mouseMovement.y;
                    sprite.position.x = sprite.batchMoveStartPos.x + mouseMovement.x;
                    sprite.position.y = sprite.batchMoveStartPos.y + mouseMovement.y;
                }
            }
        }
@@ -855,7 +855,7 @@
        if (backpackCount !== prevBackpackCount || battery !== prevBattery) {
            const agvStatusMode = getAgvStatusMode(backpackCount, battery);
            const agvTexture = generateAgvSpriteTexture(agvStatusMode);
            const agvTexture = generateAgvSpriteTexture(agvModel, agvStatusMode);
            agvSprite.texture = PIXI.Texture.from(agvTexture, { resourceOptions: { scale: 1 } });
            // update backpackCount and battery
            agvSprite.data.backpackCount = backpackCount;
zy-acs-flow/src/page/sta/StaCreate.jsx
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import React, { useMemo } from "react";
import {
    CreateBase,
    useTranslate,
@@ -36,6 +36,12 @@
    const translate = useTranslate();
    const notify = useNotify();
    const greaterThanZero = useMemo(() => (value) => {
        if (value === undefined || value === null || value === '') {
            return undefined;
        }
        return Number(value) >= 0 ? undefined : translate('validate.gtZero');
    }, [translate]);
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
@@ -150,21 +156,50 @@
                                    <NumberInput
                                        label="table.field.sta.capacity"
                                        source="capacity"
                                        validate={required()}
                                        validate={[required(), greaterThanZero]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.offset"
                                        source="offset"
                                        validate={required()}
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.height"
                                        source="height"
                                        validate={[required(), greaterThanZero]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.depth"
                                        source="depth"
                                        helperText={translate('page.sta.depthHint')}
                                        validate={[required(), greaterThanZero]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.angle"
                                        source="angle"
                                        validate={required()}
                                        validate={[required(), greaterThanZero]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.inboundWait"
                                        source="inboundWait"
                                        validate={greaterThanZero}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.sta.outboundWait"
                                        source="outboundWait"
                                        validate={greaterThanZero}
                                    />
                                </Grid>
                                {/* <Grid item xs={6} display="flex" gap={1}>
@@ -216,9 +251,9 @@
                                    </ReferenceInput>
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                </Grid> */}
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
zy-acs-flow/src/page/sta/StaEdit.jsx
@@ -42,6 +42,12 @@
const StaEdit = () => {
    const translate = useTranslate();
    const greaterThanZero = useMemo(() => (value) => {
        if (value === undefined || value === null || value === '') {
            return undefined;
        }
        return Number(value) >= 0 ? undefined : translate('validate.gtZero');
    }, [translate]);
    return (
        <Edit
@@ -127,20 +133,45 @@
                            <NumberInput
                                label="table.field.sta.capacity"
                                source="capacity"
                                validate={required()}
                                validate={[required(), greaterThanZero]}
                            />
                            <NumberInput
                                label="table.field.sta.angle"
                                source="angle"
                                validate={[required(), greaterThanZero]}
                            />
                            {/* <NumberInput
                                label="table.field.sta.offset"
                                source="offset"
                                validate={required()}
                            /> */}
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.sta.height"
                                source="height"
                                validate={[required(), greaterThanZero]}
                            />
                            <NumberInput
                                label="table.field.sta.depth"
                                source="depth"
                                helperText={translate('page.sta.depthHint')}
                                validate={[required(), greaterThanZero]}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.sta.angle"
                                source="angle"
                                validate={required()}
                                label="table.field.sta.inboundWait"
                                source="inboundWait"
                                validate={greaterThanZero}
                            />
                            <NumberInput
                                label="table.field.sta.outboundWait"
                                source="outboundWait"
                                validate={greaterThanZero}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            {/* <NumberInput
                                label="table.field.sta.occCnt"
                                source="occCnt"
zy-acs-flow/src/page/sta/StaList.jsx
@@ -134,7 +134,8 @@
                    expand={() => <StaPanel />}
                    expandSingle={true}
                    rowSx={rowSx(drawerVal || null)}
                    omit={['id', 'uuid', 'name', 'zpallet', 'updateBy', 'createTime', 'createBy', 'memo']}
                    omit={['id', 'uuid', 'name', 'offset', 'zpallet'
                        , 'updateTime', 'updateBy', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <ReferenceField source="zoneId" label="table.field.sta.zoneId" reference="zone" link={false} sortable={false}>
@@ -157,7 +158,11 @@
                    <NumberField source="rsvInCnt" label="table.field.sta.rsvInCnt" />
                    <NumberField source="rsvOutCnt" label="table.field.sta.rsvOutCnt" />
                    <NumberField source="offset" label="table.field.sta.offset" />
                    <NumberField source="height" label="table.field.sta.height" />
                    <NumberField source="depth" label="table.field.sta.depth" />
                    <NumberField source="angle" label="table.field.sta.angle" />
                    <NumberField source="inboundWait" label="table.field.sta.inboundWait" />
                    <NumberField source="outboundWait" label="table.field.sta.outboundWait" />
                    {/* <TextField source="autoing" label="table.field.sta.autoing" />
                    <TextField source="loading" label="table.field.sta.loading" />
                    <TextField source="inEnable" label="table.field.sta.inEnable" />
zy-acs-flow/src/page/sta/StaPanel.jsx
@@ -41,7 +41,11 @@
    { labelKey: 'table.field.sta.capacity', valueKey: 'capacity' },
    { labelKey: 'table.field.sta.rsvInCnt', valueKey: 'rsvInCnt' },
    { labelKey: 'table.field.sta.rsvOutCnt', valueKey: 'rsvOutCnt' },
    { labelKey: 'table.field.sta.offset', valueKey: 'offset' },
    // { labelKey: 'table.field.sta.offset', valueKey: 'offset' },
    { labelKey: 'table.field.sta.height', valueKey: 'height' },
    { labelKey: 'table.field.sta.depth', valueKey: 'depth' },
    { labelKey: 'table.field.sta.inboundWait', valueKey: 'inboundWait' },
    { labelKey: 'table.field.sta.outboundWait', valueKey: 'outboundWait' },
    { labelKey: 'table.field.sta.zpallet', valueKey: 'zpallet' },
];
@@ -159,14 +163,14 @@
                    {/* <Typography variant="subtitle2" color="textSecondary" gutterBottom>
                        {translate('common.field.status')}
                    </Typography> */}
                    <Grid container spacing={2}>
                    {/* <Grid container spacing={2}>
                        {STATUS_FIELDS.map(({ key, labelKey }) => (
                            <Grid item xs={6} sm={3} key={key}>
                                <StatusIndicator labelKey={labelKey} value={record[key]} />
                            </Grid>
                        ))}
                    </Grid>
                    <Divider sx={{ my: 2 }} />
                    <Divider sx={{ my: 2 }} /> */}
                    <Box>
                        <Typography variant="subtitle1" gutterBottom>
zy-acs-flow/src/page/sta/rowSx.jsx
@@ -15,6 +15,20 @@
            backgroundColor: 'action.selected',
        };
    }
    if (record.staType$ === 'ROLLER')
        return {
            ...style,
            borderLeftColor: orange[500],
            borderLeftWidth: 5,
            borderLeftStyle: 'solid',
        };
    if (record.staType$ === 'RACK')
        return {
            ...style,
            borderLeftColor: blue[500],
            borderLeftWidth: 5,
            borderLeftStyle: 'solid',
        };
    if (record.connect)
        return {
            ...style,
zy-acs-flow/src/page/travel/TravelList.jsx
@@ -30,6 +30,7 @@
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
    FunctionField,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
@@ -57,23 +58,42 @@
    },
}));
const tabs = [
    { id: 'RUNNING', name: 'page.travel.enums.state.running' },
    { id: 'FINISH', name: 'page.travel.enums.state.finish' },
];
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="uuid" label="table.field.travel.uuid" />,
    <TextInput source="travelId" label="table.field.travel.travelId" />,
    <ReferenceInput source="agvId" label="table.field.travel.agvId" reference="agv">
    <ReferenceInput source="agvId" label="table.field.travel.agvId" reference="agv" alwaysOn>
        <AutocompleteInput label="table.field.travel.agvId" optionText="uuid" filterToQuery={(val) => ({ uuid: val })} />
    </ReferenceInput>,
    <ReferenceInput source="currSeg" label="table.field.travel.currSeg" reference="segment">
        <AutocompleteInput label="table.field.travel.currSeg" optionText="id" filterToQuery={(val) => ({ id: val })} />
    <SelectInput
        label="table.field.travel.rollerWaiting"
        source="rollerWaiting"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        alwaysOn
    />,
    <ReferenceInput source="rollerWaitingCode" label="table.field.travel.rollerWaitingCode" reference="code">
        <AutocompleteInput label="table.field.travel.rollerWaitingCode" optionText="data" filterToQuery={(val) => ({ uuid: val })} />
    </ReferenceInput>,
    <TextInput source="taskContent" label="table.field.travel.taskContent" />,
    <TextInput source="taskIds" label="table.field.travel.taskIds" />,
    <TextInput source="state" label="table.field.travel.state" />,
    // <ReferenceInput source="currSeg" label="table.field.travel.currSeg" reference="segment">
    //     <AutocompleteInput label="table.field.travel.currSeg" optionText="id" filterToQuery={(val) => ({ id: val })} />
    // </ReferenceInput>,
    <SelectInput
        source="state"
        label="table.field.travel.state"
        choices={tabs}
        translateChoice
        alwaysOn
    />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
@@ -109,7 +129,7 @@
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */}
                        <SelectColumnsButton preferenceKey='travel' />
                        <MyExportButton />
                    </TopToolbar>
@@ -122,7 +142,7 @@
                    rowClick={(id, resource, record) => false}
                    expand={() => <TravelPanel />}
                    expandSingle={true}
                    omit={['id', 'updateBy', 'createTime', 'createBy', 'memo']}
                    omit={['id', 'currSeg', 'rollerWaitingCode', 'updateBy', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="uuid" label="table.field.travel.uuid" />
@@ -134,8 +154,16 @@
                        <TextField source="id" />
                    </ReferenceField>
                    <TextField source="taskIds" label="table.field.travel.taskIds" />
                    <TextField source="state" label="table.field.travel.state" />
                    <BooleanField source="rollerWaitingBool" label="table.field.travel.rollerWaiting" sortable={false} />
                    <ReferenceField source="rollerWaitingCode" label="table.field.travel.rollerWaitingCode" reference="code" link={false} sortable={false}>
                        <TextField source="data" />
                    </ReferenceField>
                    {/* <TextField source="state" label="table.field.travel.state" /> */}
                    <FunctionField label="table.field.travel.state" cellClassName="state" render={record => (
                        <>
                            {translate(tabs.find(item => item.id === record.state)?.name)}
                        </>
                    )} />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
@@ -146,10 +174,10 @@
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    {/* <BooleanField source="statusBool" label="common.field.status" sortable={false} /> */}
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                    {/* <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                    </WrapperField> */}
                </StyledDatagrid>
            </List>
            <TravelCreate
zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java
@@ -1,6 +1,8 @@
package com.zy.acs.manager.core;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.domain.HeightDepthDto;
import com.zy.acs.common.enums.AgvStatusType;
import com.zy.acs.framework.common.R;
import com.zy.acs.manager.core.integrate.conveyor.ConveyorStationService;
@@ -9,16 +11,17 @@
import com.zy.acs.manager.core.service.PatrolService;
import com.zy.acs.manager.manager.entity.*;
import com.zy.acs.manager.manager.enums.FuncStaType;
import com.zy.acs.manager.manager.enums.StaReserveType;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.*;
import com.zy.acs.manager.system.controller.BaseController;
import com.zy.acs.manager.system.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -44,10 +47,14 @@
    private AgvModelService agvModelService;
    @Autowired
    private StaService staService;
    @Autowired
    private SegmentService segmentService;
//    @Autowired
//    private ConveyorStationService siemensConveyorStationService;
    @Autowired
    private ConveyorStationService siemensConveyorStationService;
    @Autowired
    private ConfigService configService;
    @RequestMapping(value = "/system/info", method = {RequestMethod.GET, RequestMethod.POST})
    public R systemInfo() {
@@ -56,9 +63,12 @@
    @RequestMapping(value = "/system/demo", method = {RequestMethod.GET, RequestMethod.POST})
    public R demo() {
        Sta sta = staService.selectByStaNo("1006");
        boolean b = siemensConveyorStationService.allowAgvWork(sta, null, null, StaReserveType.IN);
        return R.ok().add(b);
        Double defaultShelfDepth = configService.getVal("defaultShelfDepth", Double.class);
        defaultShelfDepth = Optional.ofNullable(defaultShelfDepth).orElse((double) 0);
        Double ss = 10.0;
        String jsonString = JSON.toJSONString(new HeightDepthDto(ss, defaultShelfDepth));
        return R.ok(jsonString);
    }
    // http://localhost:8088/demo/auto/go/standby
@@ -151,8 +161,6 @@
    @Autowired
    private MapService mapService;
    @Autowired
    private SegmentService segmentService;
    @GetMapping("/astarDemo") // astar spend time: 3866, count:3855
    public R astarDemo() {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
@@ -3,8 +3,8 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.utils.Base62;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.common.utils.Utils;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.R;
import com.zy.acs.framework.common.SnowflakeIdWorker;
@@ -165,7 +165,8 @@
        task.setAgvId(agv.getId());
        task.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
        List<Task> lastTasks = taskService.list(new LambdaQueryWrapper<Task>().orderByDesc(Task::getId));
        task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum()));
//        task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum()));
        task.setSeqNum(Base62.encode(snowflakeIdWorker.nextId()));
        task.setTaskType(param.getTaskMode().val());
        task.setTaskSts(TaskStsType.WAITING.val());
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/conveyor/ConveyorController.java
@@ -6,6 +6,7 @@
import com.zy.acs.manager.core.integrate.dto.ConveyorQueryParam;
import com.zy.acs.manager.core.integrate.dto.ConveyorQueryResult;
import com.zy.acs.manager.manager.entity.Sta;
import com.zy.acs.manager.manager.entity.Task;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.StaService;
import com.zy.acs.manager.system.controller.BaseController;
@@ -38,8 +39,16 @@
                    .orderByAsc(Sta::getStaNo)
            );
            for (Sta sta : list) {
                resultList.add(new ConveyorQueryResult(sta.getStaNo()
                        , !staService.hasWorkingAgv(sta.getId())));
                Long staId = sta.getId();
                boolean conveyable = !staService.hasWorkingAgv(staId);
                String taskNo = null;
                if (conveyable) {
                    Task task = staService.checkoutTask(staId);
                    if (null != task) {
                        taskNo = task.getSeqNum();
                    }
                }
                resultList.add(new ConveyorQueryResult(sta.getStaNo(), conveyable, taskNo));
            }
        } else {
            for (String staNo : staNos) {
@@ -48,8 +57,16 @@
                    resultList.add(new ConveyorQueryResult(staNo, Boolean.FALSE));
                    continue;
                }
                resultList.add(new ConveyorQueryResult(staNo
                        , !staService.hasWorkingAgv(sta.getId())));
                Long staId = sta.getId();
                boolean conveyable = !staService.hasWorkingAgv(staId);
                String taskNo = null;
                if (conveyable) {
                    Task task = staService.checkoutTask(staId);
                    if (null != task) {
                        taskNo = task.getSeqNum();
                    }
                }
                resultList.add(new ConveyorQueryResult(staNo, conveyable, taskNo));
            }
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/conveyor/SiemensConveyorStationService.java
@@ -46,7 +46,7 @@
        final String staNo = sta.getStaNo();
        // url
        String url = this.buildUrl("/station/query");
        String url = this.buildUrl("/cv/station/query");
        // headers
        Map<String, String> headers = new HashMap<>();
        // params
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/dto/ConveyorQueryResult.java
@@ -9,6 +9,8 @@
    private Boolean conveyable;
    private String taskNo;
    public ConveyorQueryResult() {
    }
@@ -17,4 +19,10 @@
        this.conveyable = conveyable;
    }
    public ConveyorQueryResult(String staNo, Boolean conveyable, String taskNo) {
        this.staNo = staNo;
        this.conveyable = conveyable;
        this.taskNo = taskNo;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/integrate/wms/OpenController.java
@@ -24,7 +24,7 @@
    @Autowired
    private MainService mainService;
    @PreAuthorize("hasAuthority('open:bus:submit')")
//    @PreAuthorize("hasAuthority('open:bus:submit')")
    @PostMapping("/bus/submit")
    @OperationLog("generate task from open api")
    public R save(@RequestBody OpenBusSubmitParam param) {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/ConveyorAutoRunScheduler.java
New file
@@ -0,0 +1,178 @@
package com.zy.acs.manager.core.scheduler;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SnowflakeIdWorker;
import com.zy.acs.manager.common.domain.TaskDto;
import com.zy.acs.manager.core.service.AreaGovernService;
import com.zy.acs.manager.core.service.MainService;
import com.zy.acs.manager.manager.controller.param.OpenBusSubmitParam;
import com.zy.acs.manager.manager.entity.*;
import com.zy.acs.manager.manager.enums.AgvModelType;
import com.zy.acs.manager.manager.enums.BusStsType;
import com.zy.acs.manager.manager.enums.LocStsType;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.*;
import com.zy.acs.manager.manager.service.impl.CodeServiceImpl;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
@Slf4j
@Component
public class ConveyorAutoRunScheduler {
    private static final AgvModelType DEFAULT_AGV_MODEL = AgvModelType.CTU_BOX_TRANSPORT_AGV;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Autowired
    private AgvService agvService;
    @Autowired
    private BusService busService;
    @Autowired
    private MainService mainService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private LocService locService;
    @Autowired
    private StaService staService;
    @Autowired
    private AgvModelService agvModelService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private AreaGovernService areaGovernService;
    @Autowired
    private CodeServiceImpl codeService;
    //    @Scheduled(fixedRate = 500) // å›ºå®šé¢‘率执行,不同步
    @Scheduled(fixedDelay = 1000) // å›ºå®šé¢‘率执行,同步
//    @Scheduled(cron = "0/1 * * * * ? ")
    private void execute() {
        //if (!configService.getVal("ConveyorTaskAssignMode", Boolean.class)) { return; }
        AgvModel agvModel = agvModelService.getOne(new LambdaQueryWrapper<AgvModel>().eq(AgvModel::getType, DEFAULT_AGV_MODEL.toString()));
        if (null == agvModel) { return; }
        //this.autoRun(agvModel);
    }
    private void autoRun(AgvModel agvModel) {
        int availableAgvCount = this.getAvailableAgvCount();
        if (0 == availableAgvCount) { return; }
//        List<String> staPreNos = getStaPrefixes(staGroupList);
        List<String> staPreNos = new ArrayList<>();
        String memo = "DEMO_STA_" + String.join("-", staPreNos);
        // æœ€å¤š ? ç»„bus运行
        if (1 <= busService.count(new LambdaQueryWrapper<Bus>()
                .in(Bus::getBusSts, BusStsType.RECEIVE.val(), BusStsType.PROGRESS.val())
                .in(Bus::getMemo, memo)
        )) { return; }
        // å‡ºåº“
        this.runLocToSta(agvModel, memo);
    }
    // å‡ºåº“
    private void runLocToSta(AgvModel agvModel, String memo) {
        // IDLE STA
        List<Sta> idleList = new ArrayList<>();
        idleList.add(staService.selectByStaNo("1001"));
        idleList.add(staService.selectByStaNo("1007"));
        if (Cools.isEmpty(idleList)) { return; }
        Collections.shuffle(idleList);
        OpenBusSubmitParam param = new OpenBusSubmitParam();
        param.setBatch(String.valueOf(snowflakeIdWorker.nextId()).substring(13, 19));
        for (int i = 0; i < agvModel.getBackpack() ; i++) {
            Sta idleSta = idleList.get(i);
            String staCode = codeService.getCacheById(idleSta.getCode()).getData();
            Loc stockLoc = null;
            // æ‰€åœ¨åŒºåŸŸçš„æ¡ç ï¼Œå¦‚果没有area绑定,就全地图
            List<String> codeList = areaGovernService.queryCodesByOneCode(staCode);
            if (Cools.isEmpty(codeList)) {
                stockLoc = locService.selectRandOneByLocSts(LocStsType.STOCK.val(), 1);
            } else {
                Collections.shuffle(codeList);
                for (String codeData : codeList) {
                    Code code = codeService.getCacheByData(codeData);
                    if (null == code) { break; }
                    List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                            .eq(Loc::getCode, code.getId()).eq(Loc::getLocSts, LocStsType.STOCK.val()));
                    if (Cools.isEmpty(locList)) {
                        break;
                    } else if (locList.size() == 1) {
                        stockLoc = locList.get(0);
                    } else {
                        Collections.shuffle(locList);
                        stockLoc = locList.get(0);
                    }
                    if (null != stockLoc) {
                        break;
                    }
                }
            }
            if (null == stockLoc) { break; }
            TaskDto taskDto = new TaskDto();
            taskDto.setOriLoc(stockLoc.getLocNo());
            taskDto.setDestSta(idleSta.getStaNo());
            taskDto.setPriority(100);
            taskDto.setSeqNum(String.valueOf(snowflakeIdWorker.nextId()).substring(15, 19));
            param.getTaskList().add(taskDto);
        }
        if (Cools.isEmpty(param.getTaskList())) { return; }
        mainService.generateBusAndTask(param, memo);
    }
    public static List<String> getStaPrefixes(List<String> staGroupList) {
        Set<String> rowSet = new HashSet<>();
        for (String s : staGroupList) {
            rowSet.add(s.split("-")[0]);
        }
        List<String> result = new ArrayList<>(rowSet);
        result.sort(Comparator.comparingInt(Integer::parseInt));
        return result;
    }
    private int getAvailableAgvCount() {
        int res = 0;
        List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val));
        if (Cools.isEmpty(agvList)) {
            return res;
        }
        for (Agv agv : agvList) {
            if (null == redis.getObject(RedisConstant.AGV_ONLINE_FLAG, agv.getUuid())) {
                continue;
            }
            if (!agv.getStatusBool()) {
                continue;
            }
            res++;
        }
        return res;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/KernelScheduler.java
@@ -71,7 +71,7 @@
    @Autowired
    private LocService locService;
    @Autowired
    private AgvModelService agvModelService;
    private TravelService travelService;
    @Autowired
    private TransferStationHandler transferStationHandler;
@@ -124,6 +124,8 @@
                    for (Segment segment : segments) {
                        if (transferStationHandler.hasDelayAtSta(segment)) {
                            continue;
                        } else {
                            travelService.clearRollerWaiting(segment.getTravelId());
                        }
                        try {
                            txTemplate.executeWithoutResult(status -> {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AllocateService.java
@@ -50,6 +50,8 @@
    private AgvAreaDispatcher agvAreaDispatcher;
    @Autowired
    private SegmentService segmentService;
    @Autowired
    private TravelService travelService;
    /**
     * get available agv list which is idle
@@ -62,7 +64,6 @@
        List<String> result = new ArrayList<>();
        for (Agv agv : agvList) {
            if (!hasRunning) {
                // 1. without running tasks
                if (0 < taskService.count(new LambdaQueryWrapper<Task>()
                        .eq(Task::getAgvId, agv.getId())
                        .and(i -> i
@@ -73,10 +74,13 @@
                )) {
                    continue;
                }
            }
            // 2. in idle status
            if (!agvService.judgeEnable(agv.getId(), true)) {
                if (!agvService.judgeEnable(agv.getId(), true, true)) {
                continue;
                }
            } else {
                if (!agvService.judgeEnable(agv.getId(), true, false)) {
                    continue;
                }
            }
            result.add(agv.getUuid());
@@ -221,15 +225,15 @@
//                continue;
//            }
            // in TransferStationHandler.hasDelayAtSta
            Segment currSeg = segmentService.getRollerWaiting(agvId, sta.getCode(), TaskPosDto.PosType.ORI_STA);
            if (null == currSeg) {
            Travel currTravelInRollerWaiting = travelService.findRollerWaitingTravel(agvId, currentCode.getId());
            if (null == currTravelInRollerWaiting) {
                continue;
            }
            // has enough backpack space to load
            Integer backpack = agvService.getBackpack(agvId);
            List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(null, agvId);
            if (usedBackpacks.size() >= backpack) {
            Integer backpackCap = agvService.getBackpack(agvId);
            List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currTravelInRollerWaiting.getId(), agvId);
            if (usedBackpacks.size() >= backpackCap) {
                continue;
            }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -4,13 +4,11 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.domain.AgvAction;
import com.zy.acs.common.domain.AgvActionItem;
import com.zy.acs.common.domain.AgvProtocol;
import com.zy.acs.common.domain.BaseResult;
import com.zy.acs.common.domain.*;
import com.zy.acs.common.domain.protocol.*;
import com.zy.acs.common.domain.protocol.action.*;
import com.zy.acs.common.enums.*;
import com.zy.acs.common.utils.Base62;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.common.utils.Utils;
@@ -251,33 +249,28 @@
                        , (task, agvNo, sta) -> {
                            Long agvId = agvService.getAgvId(agvNo);
//                            List<Travel> travelList = travelService.list(new LambdaQueryWrapper<Travel>()
//                                    .eq(Travel::getAgvId, agvId)
//                                    .eq(Travel::getState, TravelStateType.RUNNING.toString())
//                                    .orderByDesc(Travel::getCreateTime));
//                            if (Cools.isEmpty(travelList)) {
//                                throw new BusinessException("[Agv: " + agvNo + "]allocate inbound failed to find travel");
                            Travel travel = travelService.findRunningTravel(agvId);
                            if (null == travel) {
                                throw new CoolException("[Agv:" + agvNo + "] allocate inbound failed: no roller waiting travel");
                            }
                            // curr segment
                            Segment currSeg = segmentService.getCurrWaitingSeg(travel.getId(), agvId);
//                            if (null == currSeg) {
//                                currSeg = segmentService.getCurrRunningSeg(travel.getId(), agvId, null);
//                            }
//                            Travel travel = travelList.get(0);
//
//                            List<Segment> currSegments = segmentService.list(new LambdaQueryWrapper<Segment>()
//                                    .eq(Segment::getAgvId, agvId)
//                                    .eq(Segment::getTravelId, travel.getId())
//                            );
                            // load segment
                            Segment currSeg = segmentService.getRollerWaiting(agvId, sta.getCode(), TaskPosDto.PosType.ORI_STA);
                            if (null == currSeg) {
                                throw new BusinessException("[Agv:" + agvNo + "] allocate inbound failed: no roller waiting segment");
                                throw new CoolException("[Agv:" + agvNo + "] allocate inbound failed: no waiting segment");
                            }
                            // get backpack lev
                            int backpackLev = 0;
                            int backpack = agvService.getBackpack(agvId);
                            int backpackCap = agvService.getBackpack(agvId);
                            List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currSeg.getTravelId(), agvId);
                            if (usedBackpacks.size() >= backpack) {
                            if (usedBackpacks.size() >= backpackCap) {
                                throw new CoolException("[Agv:" + agvNo + "] allocate inbound segment failed: no idle backpack to use");
                            }
                            for (int lev = 1; lev <= backpack; lev++) {
                            for (int lev = 1; lev <= backpackCap; lev++) {
                                if (!usedBackpacks.contains(lev)) {
                                    backpackLev = lev;
                                    break;
@@ -363,7 +356,6 @@
                            // DEST-only sort
                            destPosList.sort((a, b) -> {
                                // ä¸»è½´
                                double aFirst = a.getFirstWeight(sameGroupXy);
                                double bFirst = b.getFirstWeight(sameGroupXy);
@@ -381,11 +373,10 @@
                            // get placeSeg serial
                            int placeSegSerial;
                            // query placeSeg idx
                            int idx = -1;
                            for (int i = 0; i < destPosList.size(); i++) {
                                if (Objects.equals(destPosList.get(i).getCodeId(), newDto.getCodeId())
                                        && Objects.equals(destPosList.get(i).getTaskId(), newDto.getTaskId())) {
                                if (Objects.equals(destPosList.get(i).getTaskId(), newDto.getTaskId())
                                 && Objects.equals(destPosList.get(i).getCodeId(), newDto.getCodeId())) {
                                    idx = i;
                                    break;
                                }
@@ -492,7 +483,7 @@
        try {
            // valid -----------------------------------------------
            Agv agv = agvService.getById(agvId);
            if (!agvService.judgeEnable(agv.getId(), false)) {
            if (!agvService.judgeEnable(agv.getId())) {
                return;
            }
            if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) {
@@ -512,9 +503,9 @@
                    return o2.getPriority() - o1.getPriority();
                }
            });
            Integer backpack = agvService.getBackpack(agvId);
            if (taskList.size() > backpack) {
                taskList = taskList.subList(0, backpack);
            Integer backpackCap = agvService.getBackpack(agvId);
            if (taskList.size() > backpackCap) {
                taskList = taskList.subList(0, backpackCap);
            }
            AgvDetail agvDetail = agvDetailService.selectByAgvId(agvId);
@@ -584,7 +575,7 @@
                }
                if (backpackLev > backpack) {
                if (backpackLev > backpackCap) {
                    throw new BusinessException("解析Task失败,AGV背篓已满......");
                }
@@ -788,7 +779,8 @@
            task.setAgvId(agvId);
            task.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
            List<Task> lastTasks = taskService.list(new LambdaQueryWrapper<Task>().orderByDesc(Task::getId));
            task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum()));
//            task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum()));
            task.setSeqNum(Base62.encode(snowflakeIdWorker.nextId()));
            task.setOriCode(agvDetail.getCode());
            task.setDestCode(endCode.getId());
            // lane
@@ -900,6 +892,8 @@
            long actionPrepareSts = ActionStsType.PREPARE.val();
//            JSONObject storeDirection = configService.getVal("storeDirection", JSONObject.class);
            int angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class);
            Double defaultShelfDepth = configService.getVal("defaultShelfDepth", Double.class);
            defaultShelfDepth = Optional.ofNullable(defaultShelfDepth).orElse((double) 0);
            String agvNo = agvService.getAgvNo(agvId);
//            if (!agvService.judgeEnable(agvId)) {
//                throw new CoolException("AGV[" + agvNo + "]当前不可用...");
@@ -1176,7 +1170,7 @@
                                ActionTypeType.ReadyTakeFromShelvesLoc.desc,    // åç§°
                                (double) agvDirectionType.val,    // å±žæ€§å€¼
                                lastCode.getData(),    // åœ°é¢ç 
                                String.valueOf(oriLoc.getOffset()),   // åŠ¨ä½œå‚æ•°
                                JSON.toJSONString(new HeightDepthDto(oriLoc.getOffset(), defaultShelfDepth)),   // åŠ¨ä½œå‚æ•°
                                ActionTypeType.ReadyTakeFromShelvesLoc.val(),    // åŠ¨ä½œç±»åž‹
                                actionPrepareSts,    // åŠ¨ä½œè¿›åº¦
                                agvId,    // AGV
@@ -1239,7 +1233,7 @@
                                ActionTypeType.ReadyReleaseToShelvesLoc.desc,    // åç§°
                                (double) agvDirectionType.val,    // å±žæ€§å€¼
                                lastCode.getData(),    // åœ°é¢ç 
                                String.valueOf(destLoc.getOffset()),   // åŠ¨ä½œå‚æ•°
                                JSON.toJSONString(new HeightDepthDto(destLoc.getOffset(), defaultShelfDepth)),   // åŠ¨ä½œå‚æ•°
                                ActionTypeType.ReadyReleaseToShelvesLoc.val(),    // åŠ¨ä½œç±»åž‹
                                actionPrepareSts,    // åŠ¨ä½œè¿›åº¦
                                agvId,    // AGV
@@ -1284,7 +1278,7 @@
                                ActionTypeType.ReadyTakeFromConveyorSta.desc,    // åç§°
                                staWorkDirection,    // å±žæ€§å€¼
                                lastCode.getData(),    // åœ°é¢ç 
                                String.valueOf(oriSta.getOffset()),   // åŠ¨ä½œå‚æ•°
                                JSON.toJSONString(new HeightDepthDto(oriSta.getHeight(), Optional.ofNullable(oriSta.getDepth()).orElse((double) 0))),   // åŠ¨ä½œå‚æ•°
                                ActionTypeType.ReadyTakeFromConveyorSta.val(),    // åŠ¨ä½œç±»åž‹
                                actionPrepareSts,    // åŠ¨ä½œè¿›åº¦
                                agvId,    // AGV
@@ -1367,7 +1361,7 @@
                                ActionTypeType.ReadyReleaseToConveyorSta.desc,    // åç§°
                                staWorkDirection,    // å±žæ€§å€¼
                                lastCode.getData(),    // åœ°é¢ç 
                                String.valueOf(destSta.getOffset()),   // åŠ¨ä½œå‚æ•°
                                JSON.toJSONString(new HeightDepthDto(destSta.getHeight(), Optional.ofNullable(destSta.getDepth()).orElse((double) 0))),   // åŠ¨ä½œå‚æ•°
                                ActionTypeType.ReadyReleaseToConveyorSta.val(),    // åŠ¨ä½œç±»åž‹
                                actionPrepareSts,    // åŠ¨ä½œè¿›åº¦
                                agvId,    // AGV
@@ -1640,14 +1634,22 @@
                        agvAction.add(new AgvActionItem<>(ReadyTakeFromShelvesLoc.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                                .bodySync((body) -> {
                                    HeightDepthDto heightDepthDto = JSON.parseObject(action.getParams(), HeightDepthDto.class);
                                    body.setHeight(heightDepthDto.getHeight());
                                    body.setDepth(heightDepthDto.getDepth());
                                })
                        );
                        break;
                    case ReadyTakeFromConveyorSta:
                        agvAction.add(new AgvActionItem<>(ReadyTakeFromConveyorSta.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                                .bodySync((body) -> {
                                    HeightDepthDto heightDepthDto = JSON.parseObject(action.getParams(), HeightDepthDto.class);
                                    body.setHeight(heightDepthDto.getHeight());
                                    body.setDepth(heightDepthDto.getDepth());
                                })
                        );
                        break;
                    case ReadyTakeFromAgvSite:
@@ -1661,21 +1663,22 @@
                        agvAction.add(new AgvActionItem<>(ReadyReleaseToShelvesLoc.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                        );
                        break;
                    case LoadPlatformLift:
                        agvAction.add(new AgvActionItem<>(LoadPlatformLift.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                                .bodySync((body) -> {
                                    HeightDepthDto heightDepthDto = JSON.parseObject(action.getParams(), HeightDepthDto.class);
                                    body.setHeight(heightDepthDto.getHeight());
                                    body.setDepth(heightDepthDto.getDepth());
                                })
                        );
                        break;
                    case ReadyReleaseToConveyorSta:
                        agvAction.add(new AgvActionItem<>(ReadyReleaseToConveyorSta.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                                .bodySync((body) -> {
                                    HeightDepthDto heightDepthDto = JSON.parseObject(action.getParams(), HeightDepthDto.class);
                                    body.setHeight(heightDepthDto.getHeight());
                                    body.setDepth(heightDepthDto.getDepth());
                                })
                        );
                        break;
                    case ReadyReleaseToAgvSite:
@@ -1683,6 +1686,13 @@
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setDepth((short) Double.parseDouble(action.getParams())))
                        );
                        break;
                    case LoadPlatformLift:
                        agvAction.add(new AgvActionItem<>(LoadPlatformLift.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                        );
                        break;
                    case FinishPath:
@@ -1835,7 +1845,7 @@
                Code code = codeService.getCacheByData(agv_06_up.getQrCode());
                // query current segment
                Segment currSeg = segmentService.getCurrRunningSeg(agv.getId(), code.getId());
                Segment currSeg = segmentService.getCurrRunningSeg(null, agv.getId(), code.getId());
                if (null == currSeg) {
                    log.error("failed to find curr segment [{}]", agv.getUuid());
                } else {
@@ -1868,6 +1878,7 @@
                                    staReserveService.rollbackWaitingToReserved(sta, currTask, StaReserveType.OUT);
                                    break;
                                }
                                log.info("AGV [{}] load permitted at conveyor station [{}]", protocol.getAgvNo(), sta.getStaNo());
                                success = true;
                                break;
                            case DEST_STA:
@@ -1883,10 +1894,11 @@
                                    staReserveService.rollbackWaitingToReserved(sta, currTask, StaReserveType.IN);
                                    break;
                                }
                                log.info("AGV [{}] unload permitted at conveyor station [{}]", protocol.getAgvNo(), sta.getStaNo());
                                success = true;
                                break;
                            default:
                                log.error("agv[{}] has wrong posType [{}], segment [{}]", protocol.getAgvNo(), posType.toString(), currSeg.getId());
                                log.error("AGV [{}] has wrong posType [{}], segment [{}]", protocol.getAgvNo(), posType.toString(), currSeg.getId());
                                break;
                        }
                    }
@@ -1899,8 +1911,7 @@
            AGV_06_DOWN agv_06_down = new AGV_06_DOWN();
            agv_06_down.setSerialNo(agv_06_up.getSerialNo());
            agv_06_down.setActionCode(agv_06_up.getActionCode());
            //agv_06_down.setResult(success ? 1 : 0);
            agv_06_down.setResult(1);
            agv_06_down.setResult(success ? 1 : 0);
            redis.push(RedisConstant.AGV_PATH_DOWN_FLAG, AgvProtocol.build(protocol.getAgvNo()).setMessageBody(agv_06_down));
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java
@@ -703,9 +703,12 @@
                continue;
            }
            // å½“前vehicle正在进行滚筒输送线等待
            if (segmentService.isRollerWaiting(agvId)) {
            if (travelService.hasRollerWaiting(agvId)) {
                continue;
            }
//            if (segmentService.isRollerWaiting(agvId)) {
//                continue;
//            }
            return blockVehicleDto.getVehicle();
        }
        return null;
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TransferStationHandler.java
@@ -12,13 +12,14 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Slf4j
@Service
public class TransferStationHandler {
    private static final long LOAD_DELAY_MS  = 15000L; // load ( inbound ) delay timeout
    private static final long PLACE_DELAY_MS  = 15000L; // place ( outbound ) delay timeout
    private static final int DEFAULT_LOAD_DELAY_MS  = 15000; // load ( inbound ) delay timeout
    private static final int DEFAULT_PLACE_DELAY_MS  = 1000; // place ( outbound ) delay timeout
    @Autowired
    private SegmentService segmentService;
@@ -30,6 +31,8 @@
    private CodeService codeService;
    @Autowired
    private StaService staService;
    @Autowired
    private TravelService travelService;
    /**
     * å–货(入库):在取完第一个货的时候,担心滚筒输送线会有下一个货物,所以建议AGV在原地等待一段时间
@@ -68,20 +71,21 @@
        if (prePosType.equals(TaskPosDto.PosType.ORI_STA)) {
            // èƒŒç¯“未满才等
            Integer backpack = agvService.getBackpack(agvId);
            Integer backpackCap = agvService.getBackpack(agvId);
            List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currSeg.getTravelId(), agvId);
            if (usedBackpacks.size() >= backpack) {
            if (usedBackpacks.size() >= backpackCap) {
                return false;
            }
            // sign waiting
            if (currSeg.getRollerWaiting() == 0) {
                currSeg.setRollerWaiting(1);
                segmentService.updateById(currSeg);
            }
            // mark roller waiting
            travelService.markRollerWaiting(currSeg.getTravelId(), currentCode.getId());
//            if (currSeg.getRollerWaiting() == 0) {
//                currSeg.setRollerWaiting(1);
//                segmentService.updateById(currSeg);
//            }
            // timeout
            return (now - preEndTime) < LOAD_DELAY_MS;
            return (now - preEndTime) < Optional.ofNullable(rollerSta.getInboundWait()).orElse(DEFAULT_LOAD_DELAY_MS);
        }
        // outbound
@@ -95,14 +99,15 @@
                return false;
            }
            // sign waiting
            if (currSeg.getRollerWaiting() == 0) {
                currSeg.setRollerWaiting(1);
                segmentService.updateById(currSeg);
            }
            // mark roller waiting
            travelService.markRollerWaiting(currSeg.getTravelId(), currentCode.getId());
//            if (currSeg.getRollerWaiting() == 0) {
//                currSeg.setRollerWaiting(1);
//                segmentService.updateById(currSeg);
//            }
            // timeout
            return (now - preEndTime) < PLACE_DELAY_MS;
            return (now - preEndTime) < Optional.ofNullable(rollerSta.getOutboundWait()).orElse(DEFAULT_PLACE_DELAY_MS);
        }
        return false;
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/StaController.java
@@ -12,6 +12,7 @@
import com.zy.acs.manager.common.utils.ExcelUtil;
import com.zy.acs.manager.manager.entity.Sta;
import com.zy.acs.manager.manager.entity.StaReserve;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.StaReserveService;
import com.zy.acs.manager.manager.service.StaService;
import com.zy.acs.manager.system.controller.BaseController;
@@ -72,6 +73,7 @@
        sta.setCreateTime(now);
        sta.setUpdateBy(loginUserId);
        sta.setUpdateTime(now);
        sta.setStatus(StatusType.ENABLE.val);
        if (!staService.save(sta)) {
            return R.error("Save Fail");
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Segment.java
@@ -8,7 +8,6 @@
import com.zy.acs.manager.manager.service.AgvService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.manager.service.TaskService;
import com.zy.acs.manager.manager.service.TravelService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -167,15 +166,6 @@
    private String memo;
    public Segment() {}
    public String getTravelId$(){
        TravelService service = SpringUtils.getBean(TravelService.class);
        Travel travel = service.getById(this.travelId);
        if (!Cools.isEmpty(travel)){
            return String.valueOf(travel.getUuid());
        }
        return null;
    }
    public String getTaskId$(){
        TaskService service = SpringUtils.getBean(TaskService.class);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Sta.java
@@ -6,6 +6,7 @@
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SpringUtils;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.manager.service.StaTypeService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -55,8 +56,20 @@
    @ApiModelProperty(value= "偏移量")
    private Double offset;
    @ApiModelProperty(value= "作业高度")
    private Double height;
    @ApiModelProperty(value= "作业深度")
    private Double depth;
    @ApiModelProperty(value= "作业角度")
    private String angle;
    @ApiModelProperty(value= "连续入库等待(ms)")
    private Integer inboundWait;
    @ApiModelProperty(value= "连续出库等待(ms)")
    private Integer outboundWait;
    @ApiModelProperty(value= "自动")
    private String autoing;
@@ -109,14 +122,14 @@
//        return null;
//    }
//
//    public String getStaType$(){
//        StaTypeService service = SpringUtils.getBean(StaTypeService.class);
//        StaType staType = service.getById(this.staType);
//        if (!Cools.isEmpty(staType)){
//            return String.valueOf(staType.getName());
//        }
//        return null;
//    }
    public String getStaType$(){
        StaTypeService service = SpringUtils.getBean(StaTypeService.class);
        StaType staType = service.getById(this.staType);
        if (!Cools.isEmpty(staType)){
            return String.valueOf(staType.getUuid());
        }
        return null;
    }
//
    public String getCode$(){
        CodeService service = SpringUtils.getBean(CodeService.class);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Travel.java
@@ -3,9 +3,6 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SpringUtils;
import com.zy.acs.manager.manager.service.AgvService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -62,6 +59,18 @@
    private String taskIds;
    /**
     * æ»šç­’线等待 1: æ˜¯  0: å¦
     */
    @ApiModelProperty(value= "滚筒线等待 1: æ˜¯  0: å¦  ")
    private Integer rollerWaiting;
    /**
     * æ»šç­’线等待地码
     */
    @ApiModelProperty(value= "滚筒线等待地码")
    private Long rollerWaitingCode;
    /**
     * è¿›åº¦
     */
    @ApiModelProperty(value= "进度")
@@ -115,65 +124,17 @@
    @ApiModelProperty(value= "备注")
    private String memo;
    public Travel() {}
    public Travel(String uuid,String travelId,Long agvId,Long currSeg,String taskContent,String taskIds,String state,Integer status,Integer deleted,Long tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.uuid = uuid;
        this.travelId = travelId;
        this.agvId = agvId;
        this.currSeg = currSeg;
        this.taskContent = taskContent;
        this.taskIds = taskIds;
        this.state = state;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Travel travel = new Travel(
//            null,    // ç¼–号
//            null,    // ç»„编号
//            null,    // AGV
//            null,    // å½“前节点
//            null,    // å†…容
//            null,    // ä»»åŠ¡åˆ—è¡¨
//            null,    // è¿›åº¦
//            null,    // çŠ¶æ€[非空]
//            null,    // æ˜¯å¦åˆ é™¤[非空]
//            null,    // ç§Ÿæˆ·
//            null,    // æ·»åŠ äººå‘˜
//            null,    // æ·»åŠ æ—¶é—´[非空]
//            null,    // ä¿®æ”¹äººå‘˜
//            null,    // ä¿®æ”¹æ—¶é—´
//            null    // å¤‡æ³¨
//    );
    public String getAgvId$(){
        AgvService service = SpringUtils.getBean(AgvService.class);
        Agv agv = service.getById(this.agvId);
        if (!Cools.isEmpty(agv)){
            return String.valueOf(agv.getUuid());
        }
    public Boolean getRollerWaitingBool(){
        if (null == this.rollerWaiting){ return null; }
        switch (this.rollerWaiting){
            case 1:
                return true;
            case 0:
                return false;
            default:
        return null;
    }
    public String getStatus$(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return "正常";
            case 0:
                return "冻结";
            default:
                return String.valueOf(this.status);
        }
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AgvService.java
@@ -32,7 +32,7 @@
    Boolean judgeEnable(Long agvId);
    Boolean judgeEnable(Long agvId, Boolean withBattery);
    Boolean judgeEnable(Long agvId, Boolean withBattery, Boolean idleStatus);
    Boolean judgeOnline(Long agvId);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/SegmentService.java
@@ -1,7 +1,6 @@
package com.zy.acs.manager.manager.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zy.acs.manager.core.domain.TaskPosDto;
import com.zy.acs.manager.manager.entity.Segment;
import com.zy.acs.manager.manager.enums.SegmentStateType;
@@ -27,11 +26,11 @@
    Boolean cancel(Long segmentId, Long userId);
    Segment getCurrRunningSeg(Long agvId, Long codeId);
    Segment getCurrWaitingSeg(Long travelId, Long agvId);
    Segment getCurrRunningSeg(Long travelId, Long agvId, Long codeId);
    List<Integer> selectUsedBackpacks(Long travelId, Long agvId);
    Segment getRollerWaiting(Long agvId, Long codeId, TaskPosDto.PosType posType);
    Boolean isRollerWaiting(Long agvId);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/StaService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.zy.acs.manager.manager.entity.Sta;
import com.zy.acs.manager.manager.entity.Task;
import com.zy.acs.manager.manager.enums.StaTypeType;
import java.util.List;
@@ -16,6 +17,8 @@
    List<Sta> queryAvailableInSta(Integer minAvailableQty);
    Task checkoutTask(Long staId);
    boolean isRoller(Long staId);
    Boolean hasWorkingAgv(Long staId);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/TravelService.java
@@ -9,4 +9,14 @@
    void finishAll(Long agvId);
    Travel findRunningTravel(Long agvId);
    Travel findRollerWaitingTravel(Long agvId, Long code);
    Boolean hasRollerWaiting(Long agvId);
    Boolean markRollerWaiting(Long travelId, Long codeId);
    Boolean clearRollerWaiting(Long travelId);
}
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java
@@ -190,19 +190,21 @@
    @Override
    public Boolean judgeEnable(Long agvId) {
        return this.judgeEnable(agvId, false);
        return this.judgeEnable(agvId, false, true);
    }
    @Override
    public Boolean judgeEnable(Long agvId, Boolean isLowBattery) {
    public Boolean judgeEnable(Long agvId, Boolean isLowBattery, Boolean idleStatus) {
        String agvNo = this.getAgvNo(agvId);
        AgvModel agvModel = agvModelService.getByAgvId(agvId);
        if (idleStatus) {
        if (0 < segmentService.count(new LambdaQueryWrapper<Segment>()
                        .eq(Segment::getAgvId, agvId)
                        .eq(Segment::getState, SegmentStateType.RUNNING.toString())
        )) {
//            log.warn("[{}]号Agv正在忙碌 - segment......", agvNo);
            return false;
            }
        }
        if (!this.judgeOnline(agvId)) {
//            log.warn("[{}]号Agv不是在线状态......", agvNo);
@@ -216,10 +218,12 @@
        if (null == agvDetail.getSoc() || agvDetail.getSoc() == 0) {
            return false;
        }
        if (idleStatus) {
        if (!agvDetail.getAgvStatus().equals(AgvStatusType.IDLE) && !agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
            log.warn("[{}]号Agv不是空闲状态......", agvNo);
            return false;
        }
        }
        if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
            if (agvDetail.getSoc() < agvModel.getQuaBattery()) {
                return false;
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/BusServiceImpl.java
@@ -8,11 +8,14 @@
import com.zy.acs.manager.common.domain.TaskDto;
import com.zy.acs.manager.manager.controller.param.OpenBusSubmitParam;
import com.zy.acs.manager.manager.entity.Bus;
import com.zy.acs.manager.manager.entity.Loc;
import com.zy.acs.manager.manager.entity.Task;
import com.zy.acs.manager.manager.enums.BusStsType;
import com.zy.acs.manager.manager.enums.LocStsType;
import com.zy.acs.manager.manager.enums.TaskStsType;
import com.zy.acs.manager.manager.mapper.BusMapper;
import com.zy.acs.manager.manager.service.BusService;
import com.zy.acs.manager.manager.service.LocService;
import com.zy.acs.manager.manager.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,10 +29,37 @@
    @Autowired
    private TaskService taskService;
    @Autowired
    private LocService locService;
    @Override
    public Bus selectByUuid(String uuid) {
        return this.getOne(new LambdaQueryWrapper<Bus>().eq(Bus::getUuid, uuid));
    }
    private void test(OpenBusSubmitParam param) {
        if (Cools.isEmpty(param)) {
            return;
        }
        List<TaskDto> taskList = param.getTaskList();
        if (Cools.isEmpty(taskList)) {
            return;
        }
        for (TaskDto dto : taskList) {
            if (dto.getPriority() == 9527) {
                if (Cools.isEmpty(dto.getDestLoc())) {
                    List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                            .ge(Loc::getRow, 31).eq(Loc::getLocSts, LocStsType.IDLE.val()));
                    if (Cools.isEmpty(locList)) {
                        log.error("there is no such idle loc");
                        break;
                    }
                    Collections.shuffle(locList);
                    Loc loc = locList.get(0);
                    dto.setDestLoc(loc.getLocNo());
                }
            }
        }
    }
    @Override
@@ -40,6 +70,7 @@
        if (Cools.isEmpty(param.getBatch())) {
            return "Batch cannot be empty!";
        }
        this.test(param);
        Set<String> oriStaNoSet = new HashSet<>();
        Set<String> oriLocNoSet = new HashSet<>();
        Set<String> destStaNoSet = new HashSet<>();
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/SegmentServiceImpl.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
import com.zy.acs.manager.core.domain.TaskPosDto;
import com.zy.acs.manager.manager.entity.Segment;
import com.zy.acs.manager.manager.entity.Task;
import com.zy.acs.manager.manager.enums.ActionStsType;
@@ -154,39 +153,42 @@
    }
    @Override
    public Segment getCurrRunningSeg(Long agvId, Long codeId) {
    public Segment getCurrWaitingSeg(Long travelId, Long agvId) {
        List<Segment> segments = this.list(new LambdaQueryWrapper<Segment>()
                .eq(Segment::getTravelId, travelId)
                .eq(Segment::getAgvId, agvId)
                .eq(Segment::getState, SegmentStateType.RUNNING.toString())
                .eq(Segment::getEndNode, codeId)
                .eq(Segment::getState, SegmentStateType.WAITING.toString())
                .orderByDesc(Segment::getId)
        );
        if (Cools.isEmpty(segments)) {
        }
        return segments.stream().findFirst().orElse(null);
    }
    @Override
    public Segment getCurrRunningSeg(Long travelId, Long agvId, Long codeId) {
        if (null == agvId) {
            return null;
        }
        LambdaQueryWrapper<Segment> wrapper = new LambdaQueryWrapper<Segment>()
                .eq(Segment::getAgvId, agvId)
                .eq(Segment::getState, SegmentStateType.RUNNING.toString());
        if (null != travelId) {
            wrapper.eq(Segment::getTravelId, travelId);
        }
        if (null != codeId) {
            wrapper.eq(Segment::getEndNode, codeId);
        }
        wrapper.orderByDesc(Segment::getId);
        List<Segment> segments = this.list(wrapper);
        if (Cools.isEmpty(segments)) {
        }
        return segments.stream().findFirst().orElse(null);
    }
    @Override
    public List<Integer> selectUsedBackpacks(Long travelId, Long agvId) {
        return this.baseMapper.selectUsedBackpacks(agvId, travelId);
    }
    @Override
    public Segment getRollerWaiting(Long agvId, Long codeId, TaskPosDto.PosType posType) {
        List<Segment> segments = this.list(new LambdaQueryWrapper<Segment>()
                .eq(Segment::getAgvId, agvId)
                .eq(Segment::getState, SegmentStateType.WAITING.toString())
                .eq(Segment::getEndNode, codeId)
                .eq(Segment::getPosType, posType.toString())
                .eq(Segment::getRollerWaiting, 1)
                .orderByDesc(Segment::getId)
        );
        if (Cools.isEmpty(segments)) {
            return null;
        }
        return segments.get(0);
        return this.baseMapper.selectUsedBackpacks(travelId, agvId);
    }
    @Override
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/StaServiceImpl.java
@@ -5,10 +5,7 @@
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.core.domain.TaskPosDto;
import com.zy.acs.manager.manager.entity.*;
import com.zy.acs.manager.manager.enums.SegmentStateType;
import com.zy.acs.manager.manager.enums.StaTypeType;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.enums.TravelStateType;
import com.zy.acs.manager.manager.enums.*;
import com.zy.acs.manager.manager.mapper.StaMapper;
import com.zy.acs.manager.manager.service.*;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,6 +25,10 @@
    private SegmentService segmentService;
    @Autowired
    private TravelService travelService;
    @Autowired
    private StaReserveService staReserveService;
    @Autowired
    private TaskService taskService;
    @Override
    public Sta selectByStaNo(String staNo) {
@@ -56,6 +57,22 @@
    }
    @Override
    public Task checkoutTask(Long staId) {
        StaReserve reserve = staReserveService.getOne(new LambdaQueryWrapper<StaReserve>()
                .eq(StaReserve::getStaId, staId)
                .eq(StaReserve::getState, StaReserveStateType.CONFIRMED.toString())
                .eq(StaReserve::getType, StaReserveType.IN.toString())
                .eq(StaReserve::getStatus, StatusType.ENABLE.val)
                .orderByDesc(StaReserve::getConfirmedAt)
                .last("limit 1")
        );
        if (null == reserve) {
            return null;
        }
        return taskService.getById(reserve.getTaskId());
    }
    @Override
    public boolean isRoller(Long staId) {
        if (staId == null) {
            return false;
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/TravelServiceImpl.java
@@ -1,7 +1,10 @@
package com.zy.acs.manager.manager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
import com.zy.acs.manager.manager.entity.Segment;
import com.zy.acs.manager.manager.entity.Travel;
import com.zy.acs.manager.manager.enums.SegmentStateType;
@@ -9,13 +12,13 @@
import com.zy.acs.manager.manager.mapper.TravelMapper;
import com.zy.acs.manager.manager.service.SegmentService;
import com.zy.acs.manager.manager.service.TravelService;
import com.zy.acs.framework.exception.CoolException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service("travelService")
@@ -60,4 +63,90 @@
        }
    }
    @Override
    public Travel findRunningTravel(Long agvId) {
        return this.getOne(new LambdaQueryWrapper<Travel>()
                .eq(Travel::getAgvId, agvId)
                .eq(Travel::getState, TravelStateType.RUNNING.toString())
                .orderByDesc(Travel::getCreateTime)
                .last("limit 1")
        );
    }
    @Override
    public Travel findRollerWaitingTravel(Long agvId, Long code) {
        return this.getOne(new LambdaQueryWrapper<Travel>()
                .eq(Travel::getAgvId, agvId)
                .eq(Travel::getState, TravelStateType.RUNNING.toString())
                .eq(Travel::getRollerWaiting, 1)
                .eq(Travel::getRollerWaitingCode, code)
                .orderByDesc(Travel::getCreateTime)
                .last("limit 1")
        );
    }
    @Override
    public Boolean hasRollerWaiting(Long agvId) {
        if (null == agvId) {
            return false;
        }
        return 0 < this.count(new LambdaQueryWrapper<Travel>()
                .eq(Travel::getAgvId, agvId)
                .eq(Travel::getState, TravelStateType.RUNNING.toString())
                .eq(Travel::getRollerWaiting, 1)
        );
    }
    @Override
    public Boolean markRollerWaiting(Long travelId, Long codeId) {
        if (Cools.isEmpty(travelId, codeId)) {
            return false;
        }
        Travel travel = this.getById(travelId);
        if (travel == null) {
            return false;
        }
        if (!TravelStateType.RUNNING.toString().equals(travel.getState())) {
            return false;
        }
        if (travel.getRollerWaiting() == 1
                && Objects.equals(travel.getRollerWaitingCode(), codeId)) {
            return true;
        }
        travel.setRollerWaiting(1);
        travel.setRollerWaitingCode(codeId);
        if (!this.updateById(travel)) {
            log.error("travel [{}] failed to mark roller waiting (code={})", travelId, codeId);
            return false;
        }
        return true;
    }
    @Override
    public Boolean clearRollerWaiting(Long travelId) {
        if (null == travelId) {
            return false;
        }
        Travel travel = this.getById(travelId);
        if (travel == null) {
            return false;
        }
//        if (!TravelStateType.RUNNING.toString().equals(travel.getState())) {
//            return false;
//        }
        if (travel.getRollerWaiting() == 0 && Cools.isEmpty(travel.getRollerWaitingCode())) {
            return true;
        }
        if (!this.update(
                new LambdaUpdateWrapper<Travel>()
                        .eq(Travel::getId, travelId)
                        .set(Travel::getRollerWaiting, 0)
                        .set(Travel::getRollerWaitingCode, null)
        )) {
            log.error("travel [{}] failed to clear roller waiting", travelId);
            return false;
        }
        return true;
    }
}
zy-acs-manager/src/main/resources/application.yml
@@ -51,7 +51,7 @@
  index: 8
convey-plc:
  host: 10.10.10.212
  host: 10.10.10.222
  port: 9090
floyd: