vincentlu
8 天以前 583b31d46bb8abbee7410d29ca229120ee589cba
# version merge
12个文件已添加
31个文件已修改
996 ■■■■ 已修改文件
version/db/new.sql 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/UndockingChargeAction.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/enums/AgvActionCmdType.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/enums/error/AgvErrorType.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASREmptyFullBattery.svg 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASREmptyHalfBattery.svg 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASREmptyNoBattery.svg 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASRLoadedFullBattery.svg 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASRLoadedHalfBattery.svg 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/map/asr/ASRLoadedNoBattery.svg 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/model/asr/body.fbx 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/model/asr/fork.fbx 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/public/model/asr/loader.fbx 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/i18n/en.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/i18n/zh.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/insight/agv/AgvMain.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/insight/agv/AgvThree.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/tool.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/agvModel/AgvModelCreate.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/agvModel/AgvModelEdit.jsx 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/agvModel/AgvModelList.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/agvModel/AgvModelPanel.jsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/CodeCreate.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/CodeEdit.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/CodeList.jsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-gateway/src/main/java/com/zy/acs/gateway/constant/ProtocolPojoType.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-gateway/src/main/java/com/zy/acs/gateway/constant/ProtocolType.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-gateway/src/main/java/com/zy/acs/gateway/handler/AgvPackageServerHandler.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-gateway/src/main/java/com/zy/acs/gateway/listen/MessageListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MaintainScheduler.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/AgvModelController.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/AgvModel.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Code.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/enums/ActionTypeType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/enums/CodeSpinType.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvDetailServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/FuncStaServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/resources/mapper/manager/AgvDetailMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/db/new.sql
New file
@@ -0,0 +1,93 @@
code - spin
alter table man_agv_model
    add need_undocking int(1) default 0 null comment '断开充电{1:是,0:否}' after mqtt_topic;
alter table man_agv_model
    add backup_action int(1) default 0 null comment '背篓动作{1:是,0:否}' after need_undocking;
man_segment: start_time, end_time,
alter table man_segment
    add roller_waiting int(1) default 0 null comment '滚筒线等待' after end_time;
man_segment_log
alter table man_sta
    add capacity int null comment '槽位数' after angle;
alter table man_sta
    add occ_cnt int null comment '占用数' after capacity;
alter table man_sta
    add rsv_in_cnt int null comment '预约放货量' after occ_cnt;
alter table man_sta
    add rsv_out_cnt int null comment '预约取货量' after rsv_in_cnt;
-- auto-generated definition
create table man_sta_reserve_log
(
    id             bigint                              not null comment 'ID',
    uuid         varchar(255)                        null comment '标识',
    sta_id       bigint                              not null comment '站点[man_sta]',
    task_id      bigint                              not null comment '任务[man_task]',
    segment_id   bigint                              null comment '作业[man_segment]',
    agv_id       bigint                              not null comment 'AGV[man_agv]',
    name         varchar(255)                        null comment '名称(*)',
    type         varchar(255)                        not null comment '预约类型',
    qty          int                                 not null comment '预约数量',
    state        varchar(255)                        not null comment '预约状态',
    reason       varchar(255)                        null comment '原因',
    expire_time  timestamp                           null comment '过期时间',
    waiting_at   timestamp                           null comment '开始等待时间',
    confirmed_at timestamp                           null comment '确认完成时间',
    cancelled_at timestamp                           null comment '取消时间',
    uniq_key     varchar(255)                        null comment '幂等键',
    status       int(1)    default 1                 not null comment '状态{1:正常,0:冻结}',
    deleted      int(1)    default 0                 not null comment '是否删除{1:是,0:否}',
    tenant_id    int                                 null comment '租户[sys_tenant]',
    create_by    bigint                              null comment '添加人员[sys_user]',
    create_time  timestamp default CURRENT_TIMESTAMP not null comment '添加时间',
    update_by    bigint                              null comment '修改人员[sys_user]',
    update_time  timestamp default CURRENT_TIMESTAMP null comment '修改时间',
    memo         varchar(255)                        null comment '备注'
)
    charset = utf8;
-- auto-generated definition
create table man_sta_reserve_log
(
    id           bigint                              not null comment 'ID',
    uuid         varchar(255)                        null comment '标识',
    sta_id       bigint                              not null comment '站点[man_sta]',
    task_id      bigint                              not null comment '任务[man_task]',
    segment_id   bigint                              null comment '作业[man_segment]',
    agv_id       bigint                              not null comment 'AGV[man_agv]',
    name         varchar(255)                        null comment '名称(*)',
    type         varchar(255)                        not null comment '预约类型',
    qty          int                                 not null comment '预约数量',
    state        varchar(255)                        not null comment '预约状态',
    reason       varchar(255)                        null comment '原因',
    expire_time  timestamp                           null comment '过期时间',
    waiting_at   timestamp                           null comment '开始等待时间',
    confirmed_at timestamp                           null comment '确认完成时间',
    cancelled_at timestamp                           null comment '取消时间',
    uniq_key     varchar(255)                        null comment '幂等键',
    status       int(1)    default 1                 not null comment '状态{1:正常,0:冻结}',
    deleted      int(1)    default 0                 not null comment '是否删除{1:是,0:否}',
    tenant_id    int                                 null comment '租户[sys_tenant]',
    create_by    bigint                              null comment '添加人员[sys_user]',
    create_time  timestamp default CURRENT_TIMESTAMP not null comment '添加时间',
    update_by    bigint                              null comment '修改人员[sys_user]',
    update_time  timestamp default CURRENT_TIMESTAMP null comment '修改时间',
    memo         varchar(255)                        null comment '备注'
)
    charset = utf8;
-- menu
194,menu.staReserve,55,menu.equipment,55,menu.equipment,/manager/staReserve,staReserve,null,null,0,null,AccessTime,101,null,1,1,0,null,null,2025-12-26 10:56:42,2,null
195,Query StaReserve,194,null,null,null,null,null,null,null,1,manager:staReserve:list,null,0,null,1,1,0,null,null,null,null,null
196,Create StaReserve,194,null,null,null,null,null,null,null,1,manager:staReserve:save,null,1,null,1,1,0,null,null,null,null,null
197,Update StaReserve,194,null,null,null,null,null,null,null,1,manager:staReserve:update,null,2,null,1,1,0,null,null,null,null,null
    198,Delete StaReserve,194,null,null,null,null,null,null,null,1,manager:staReserve:remove,null,3,null,1,1,0,null,null,null,null,null
zy-acs-common/src/main/java/com/zy/acs/common/domain/protocol/action/UndockingChargeAction.java
New file
@@ -0,0 +1,33 @@
package com.zy.acs.common.domain.protocol.action;
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;
/**
 * 断开充电桩
 * Created by vincent on 2023/3/23
 */
@Data
public class UndockingChargeAction implements IActionBody, Serializable {
    private static final long serialVersionUID = -4740059102909409953L;
    private short temp;
    @Override
    public byte[] writeToBytes() {
        return Utils.reverse(RadixTools.shortToByte(this.temp));
    }
    @Override
    public void readFromBytes(byte[] messageBodyBytes) {
    }
}
zy-acs-common/src/main/java/com/zy/acs/common/enums/AgvActionCmdType.java
@@ -21,6 +21,8 @@
    DOCKING_CHARGE(0x30, "对接充电桩", DockingChargeAction.class),
    UNDOCKING_CHARGE(0x31, "断开充电桩", UndockingChargeAction.class),
    READY_TAKE_FROM_AGV_SITE(0x75, "准备从AGV暂存货位取货", ReadyTakeFromAgvSite.class),
    READY_RELEASE_FROM_AGV_SITE(0x76, "准备从AGV暂存货位放货", ReadyReleaseToAgvSite.class),
zy-acs-common/src/main/java/com/zy/acs/common/enums/error/AgvErrorType.java
@@ -67,6 +67,42 @@
    ERROR_0x9001("9001", "充电对接传感器异常"),
    ERROR_0x9002("9002", "充电对接超时"),
    ERROR_0x9003("9003", "对接后长时间未充电"),
    ERROR_0xA000("A000", "小车脱轨"),
    ERROR_0xA001("A001", "读码角度偏差过大"),
    ERROR_0xA002("A002", "里程计数据溢出"),
    ERROR_0xA003("A003", "IMU数据异常"),
    ERROR_0xA004("A004", "激光近距离急停"),
    ERROR_0xA005("A005", "驱动器报警"),
    ERROR_0xA008("A008", "轴0驱动器报警"),
    ERROR_0xA009("A009", "轴1驱动器报警"),
    ERROR_0xA00A("A00A", "急停信号触发"),
    ERROR_0xA00B("A00B", "货叉传感器检测异常"),
    ERROR_0xA00C("A00C", "支撑未到位"),
    ERROR_0xA00D("A00D", "松绳检测"),
    ERROR_0xA028("A028", "左取货货架无货"),
    ERROR_0xA029("A029", "左取货车内有货"),
    ERROR_0xA02A("A02A", "左放货货架有货"),
    ERROR_0xA02B("A02B", "左放货车内无货"),
    ERROR_0xA02C("A02C", "右取货货架无货"),
    ERROR_0xA02D("A02D", "右取货车内有货"),
    ERROR_0xA02E("A02E", "右放货货架有货"),
    ERROR_0xA02F("A02F", "右放货车内无货"),
    ERROR_0xA030("A030", "轮廓检测前异常"),
    ERROR_0xA031("A031", "轮廓检测后异常"),
    ERROR_0xA032("A032", "轮廓检测左异常"),
    ERROR_0xA033("A033", "轮廓检测右异常"),
    ERROR_0xA034("A034", "轮廓检测上异常"),
    ERROR_0xA03C("A03C", "从站1未就绪"),
    ERROR_0xA03D("A03D", "从站2未就绪"),
    ERROR_0xA03E("A03E", "从站3未就绪"),
    ERROR_0xA03F("A03F", "从站4未就绪"),
    ERROR_0xA040("A040", "从站5未就绪"),
    ERROR_0xA041("A041", "从站6未就绪");
    ;
    public String sign;
@@ -82,7 +118,7 @@
            return null;
        }
        for (AgvErrorType type : AgvErrorType.values()) {
            if (sign.equals(type.sign)) {
            if (sign.equalsIgnoreCase(type.sign)) {
                return type;
            }
        }
zy-acs-flow/public/map/asr/ASREmptyFullBattery.svg
New file
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.81 131.26">
  <defs>
    <style>
      .cls-1, .cls-2 {
        fill: #fff;
      }
      .cls-1, .cls-3 {
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-4 {
        fill: #4c4c4c;
      }
      .cls-5 {
        fill: #4ec5d6;
      }
      .cls-3 {
        fill: none;
        stroke-width: 2.5px;
      }
      .cls-6 {
        fill: #19a2ba;
      }
    </style>
  </defs>
  <path class="cls-4" d="M50.38,131.27H6.37c-3.45,0-6.25-2.81-6.25-6.28V6.97C.12,2.24,7.87.1,12.57.1h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-6" d="M1.81,85.56h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.74c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-6" d="M56.72,13.56H.02v-6.79C.02,2.43,7.84.12,12.23.12h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-6" x="1.54" y="81.7" width="53.67" height="3.7"/>
  <rect class="cls-3" x="4.28" y="16.13" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-5" x="2.75" y="66.84" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-1" x="8.75" y="101.98" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <polygon class="cls-2" points="47.99 115.78 45.26 117.27 45.26 108.09 47.99 109.59 47.99 115.78"/>
  </g>
</svg>
zy-acs-flow/public/map/asr/ASREmptyHalfBattery.svg
New file
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.93 131.17">
  <defs>
    <style>
      .cls-1 {
        fill: #fff;
      }
      .cls-2, .cls-3 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-4 {
        fill: #4c4c4c;
      }
      .cls-5 {
        fill: #4ec5d6;
      }
      .cls-3 {
        stroke-width: 2.5px;
      }
      .cls-6 {
        fill: #19a2ba;
      }
    </style>
  </defs>
  <path class="cls-4" d="M50.49,131.2H6.48c-3.45,0-6.25-2.81-6.25-6.28V6.9C.23,2.17,7.98.03,12.68.03h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-6" d="M1.92,85.49h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.85c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-6" d="M56.83,13.49H.14v-6.79C.14,2.36,7.95.05,12.34.05h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-6" x="1.65" y="81.62" width="53.67" height="3.7"/>
  <rect class="cls-3" x="4.39" y="16.05" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-5" x="2.87" y="66.77" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-2" x="8.86" y="101.91" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <path class="cls-1" d="M11.18,101.91h18.05v20.77H11.18c-1.28,0-2.32-1.04-2.32-2.32v-16.13c0-1.28,1.04-2.32,2.32-2.32Z"/>
    <polygon class="cls-1" points="48.11 115.39 45.38 116.89 45.38 107.71 48.11 109.2 48.11 115.39"/>
  </g>
</svg>
zy-acs-flow/public/map/asr/ASREmptyNoBattery.svg
New file
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.78 131.12">
  <defs>
    <style>
      .cls-1 {
        fill: #fff;
      }
      .cls-2, .cls-3 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-4 {
        fill: #4c4c4c;
      }
      .cls-5 {
        fill: #4ec5d6;
      }
      .cls-3 {
        stroke-width: 2.5px;
      }
      .cls-6 {
        fill: #19a2ba;
      }
      .cls-7 {
        fill: #ed2123;
      }
    </style>
  </defs>
  <path class="cls-4" d="M50.4,131.15H6.39c-3.45,0-6.25-2.81-6.25-6.28V6.85C.14,2.12,7.89-.02,12.59-.02h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-6" d="M1.83,85.45h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.76c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-6" d="M56.74,13.44H.05v-6.79C.05,2.32,7.86,0,12.25,0h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-6" x="1.56" y="81.58" width="53.67" height="3.7"/>
  <rect class="cls-3" x="4.3" y="16.01" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-5" x="2.78" y="66.72" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-2" x="8.77" y="101.87" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <path class="cls-7" d="M11.04,102.37h.87v19.75h-.87c-.98,0-1.78-.8-1.78-1.78v-16.19c0-.98.8-1.78,1.78-1.78Z"/>
    <polygon class="cls-1" points="48.01 115.35 45.28 116.84 45.28 107.66 48.01 109.16 48.01 115.35"/>
  </g>
</svg>
zy-acs-flow/public/map/asr/ASRLoadedFullBattery.svg
New file
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.75 131.28">
  <defs>
    <style>
      .cls-1 {
        fill: #cc9d5a;
      }
      .cls-2, .cls-3 {
        fill: #fff;
      }
      .cls-2, .cls-4 {
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-5 {
        fill: #4c4c4c;
      }
      .cls-6 {
        fill: #4ec5d6;
      }
      .cls-4 {
        fill: none;
        stroke-width: 2.5px;
      }
      .cls-7 {
        fill: #19a2ba;
      }
    </style>
  </defs>
  <path class="cls-5" d="M50.38,131.29H6.37c-3.45,0-6.25-2.81-6.25-6.28V6.99C.12,2.26,7.87.12,12.57.12h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-7" d="M1.81,85.58h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.74c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-7" d="M56.72,13.58H.03v-6.79C.03,2.45,7.85.14,12.23.14h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-7" x="1.54" y="81.72" width="53.67" height="3.7"/>
  <rect class="cls-4" x="4.28" y="16.15" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-6" x="2.76" y="66.86" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-2" x="8.76" y="102" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <polygon class="cls-3" points="48 115.8 45.27 117.29 45.27 108.11 48 109.61 48 115.8"/>
  </g>
  <rect class="cls-1" x="7.12" y="19.22" width="42.52" height="42.52"/>
</svg>
zy-acs-flow/public/map/asr/ASRLoadedHalfBattery.svg
New file
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.69 131.18">
  <defs>
    <style>
      .cls-1 {
        fill: #cc9d5a;
      }
      .cls-2 {
        fill: #fff;
      }
      .cls-3, .cls-4 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-5 {
        fill: #4c4c4c;
      }
      .cls-6 {
        fill: #4ec5d6;
      }
      .cls-4 {
        stroke-width: 2.5px;
      }
      .cls-7 {
        fill: #19a2ba;
      }
    </style>
  </defs>
  <path class="cls-5" d="M50.34,131.21H6.33c-3.45,0-6.25-2.81-6.25-6.28V6.91C.08,2.18,7.83.04,12.54.04h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-7" d="M1.78,85.51h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.71c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-7" d="M56.68,13.5H0v-6.79C0,2.38,7.81.06,12.19.06h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-7" x="1.5" y="81.64" width="53.67" height="3.7"/>
  <rect class="cls-4" x="4.24" y="16.07" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-6" x="2.72" y="66.78" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-3" x="8.72" y="101.93" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <path class="cls-2" d="M11.04,101.93h18.05v20.77H11.04c-1.28,0-2.32-1.04-2.32-2.32v-16.13c0-1.28,1.04-2.32,2.32-2.32Z"/>
    <polygon class="cls-2" points="47.96 115.41 45.23 116.9 45.23 107.72 47.96 109.21 47.96 115.41"/>
  </g>
  <rect class="cls-1" x="7.08" y="19.14" width="42.52" height="42.52"/>
</svg>
zy-acs-flow/public/map/asr/ASRLoadedNoBattery.svg
New file
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_圖層_1" data-name="圖層 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.71 131.19">
  <defs>
    <style>
      .cls-1 {
        fill: #cc9d5a;
      }
      .cls-2 {
        fill: #fff;
      }
      .cls-3, .cls-4 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }
      .cls-5 {
        fill: #4c4c4c;
      }
      .cls-6 {
        fill: #4ec5d6;
      }
      .cls-4 {
        stroke-width: 2.5px;
      }
      .cls-7 {
        fill: #19a2ba;
      }
      .cls-8 {
        fill: #ed2123;
      }
    </style>
  </defs>
  <path class="cls-5" d="M50.35,131.2H6.34c-3.45,0-6.25-2.81-6.25-6.28V6.9C.09,2.17,7.84.03,12.54.03h31.35c4.7,0,12.71,2.14,12.71,6.87v118.02c0,3.47-2.8,6.28-6.25,6.28Z"/>
  <path class="cls-7" d="M1.78,85.49h53.12c.38,0,.68.31.68.68v38.88c0,2.55-2.07,4.61-4.61,4.61H5.71c-2.55,0-4.61-2.07-4.61-4.61v-38.88c0-.38.31-.68.68-.68Z"/>
  <path class="cls-7" d="M56.69,13.49H0v-6.79C0,2.36,7.82.05,12.2.05h32.29c4.38,0,12.2,2.31,12.2,6.65v6.79Z"/>
  <rect class="cls-7" x="1.51" y="81.62" width="53.67" height="3.7"/>
  <rect class="cls-4" x="4.25" y="16.05" width="48.19" height="48.19" rx="1.63" ry="1.63"/>
  <rect class="cls-6" x="2.73" y="66.77" width="51.24" height="28.73" rx="2.56" ry="2.56"/>
  <g>
    <rect class="cls-3" x="8.73" y="101.91" width="35.03" height="20.77" rx="2.32" ry="2.32"/>
    <path class="cls-8" d="M11,102.42h.87v19.75h-.87c-.98,0-1.78-.8-1.78-1.78v-16.19c0-.98.8-1.78,1.78-1.78Z"/>
    <polygon class="cls-2" points="47.97 115.39 45.24 116.89 45.24 107.71 47.97 109.2 47.97 115.39"/>
  </g>
  <rect class="cls-1" x="7.09" y="19.12" width="42.52" height="42.52"/>
</svg>
zy-acs-flow/public/model/asr/body.fbx
Binary files differ
zy-acs-flow/public/model/asr/fork.fbx
Binary files differ
zy-acs-flow/public/model/asr/loader.fbx
Binary files differ
zy-acs-flow/src/i18n/en.js
@@ -273,6 +273,7 @@
                y: "y",
                corner: "corner",
                scale: "scale",
                spin: "spin",
            },
            sta: {
                uuid: "uuid",
@@ -364,6 +365,8 @@
                allDirection: "all direction",
                protocol: "protocol",
                mqttTopic: "mqtt topic",
                needUndocking: "need undocking",
                backupAction: "backup action",
            },
            agv: {
                uuid: "agv No.",
@@ -583,6 +586,15 @@
        }
    },
    page: {
        code: {
            enums: {
                spin: {
                    na: 'N/A',
                    cw: 'CW',
                    ccw: 'CCW',
                },
            },
        },
        loc: {
            init: 'INITIALIZE',
            start: {
zy-acs-flow/src/i18n/zh.js
@@ -273,6 +273,7 @@
                y: "y",
                corner: "拐角",
                scale: "比例",
                spin: "旋转",
            },
            sta: {
                uuid: "编号",
@@ -364,6 +365,8 @@
                allDirection: "全向",
                protocol: "协议",
                mqttTopic: "mqtt",
                needUndocking: "断充动作",
                backupAction: "背篓动作",
            },
            agv: {
                uuid: "车辆编号",
@@ -583,6 +586,15 @@
        }
    },
    page: {
        code: {
            enums: {
                spin: {
                    na: '全向',
                    cw: '顺时针',
                    ccw: '逆时针',
                },
            },
        },
        loc: {
            init: '初始化',
            start: {
zy-acs-flow/src/map/insight/agv/AgvMain.jsx
@@ -63,8 +63,12 @@
                    loadModel('model/agv/body.fbx'),
                    loadModel('model/agv/loader.fbx'),
                    loadModel('model/agv/fork.fbx'),
                    // loadModel('model/asr/body.fbx'),
                    // loadModel('model/asr/loader.fbx'),
                    // loadModel('model/asr/fork.fbx'),
                ]).then(([bodyMesh, loaderMesh, forkMesh]) => {
                    const scaleVal = 1;
                    // const scaleVal = 0.48;
                    bodyMesh.scale.set(scaleVal, scaleVal, scaleVal);
                    loaderMesh.scale.set(scaleVal, scaleVal, scaleVal);
                    forkMesh.scale.set(scaleVal, scaleVal, scaleVal);
@@ -72,6 +76,9 @@
                    bodyMesh.position.set(55, 0, 0);;
                    loaderMesh.position.set(55, 150, 0);;
                    forkMesh.position.set(55, 165, 0);;
                    // bodyMesh.position.set(55, 0, 0);;
                    // loaderMesh.position.set(55, 150, 0);;
                    // forkMesh.position.set(55, 165, 0);;
                    const agvGroup = new THREE.Group();
                    agvGroup.add(bodyMesh);
@@ -177,13 +184,13 @@
                            <Grid item xs={12}>
                                <KeyValuePair label={translate('common.field.status')} value={info?.agvStatus} />
                            </Grid>
                            <Grid item xs={12}>
                                <KeyValuePair label={translate('table.field.agvDetail.vol')} value={info?.vol} />
                            </Grid>
                            {/* <Grid item xs={12}>
                                <KeyValuePair label={translate('table.field.agvDetail.soc')} value={info?.soc} />
                                <KeyValuePair label={translate('table.field.agvDetail.vol')} value={info?.vol} />
                            </Grid> */}
                            <Grid item xs={12}>
                                <KeyValuePair label={translate('table.field.agvDetail.soc')} value={info?.soc} />
                            </Grid>
                            <Grid item xs={12}>
                                <KeyValuePair label={translate('table.field.agvDetail.agvAngle')} value={info?.direction} />
                            </Grid>
                            <Grid item xs={12}>
zy-acs-flow/src/map/insight/agv/AgvThree.js
@@ -121,6 +121,28 @@
        this.scene.add(dirLight1);
    }
    // initLight = () => {
    //     const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 8);
    //     hemiLight.color.setHSL(0.6, 1, 0.75);
    //     hemiLight.groundColor.setHSL(0.095, 1, 0.85);
    //     hemiLight.position.set(0, 1500, 0);
    //     this.scene.add(hemiLight);
    //     const dirLight = new THREE.DirectionalLight(0xffffff, 4);
    //     dirLight.color.setHSL(0.1, 1, 1.0);
    //     dirLight.position.set(-300, 300, 300);
    //     this.scene.add(dirLight);
    //     const dirLight1 = new THREE.DirectionalLight(0xffffff, 4);
    //     dirLight1.color.setHSL(0.1, 1, 1.0);
    //     dirLight1.position.set(300, 300, -300);
    //     dirLight1.position.multiplyScalar(30);
    //     this.scene.add(dirLight1);
    //     const ambient = new THREE.AmbientLight(0xffffff, 1.0);
    //     // this.scene.add(ambient);
    // }
    generateMesh = (fn) => {
        const loader = new FBXLoader();
zy-acs-flow/src/map/tool.js
@@ -29,6 +29,13 @@
import ctuLoadedNoBattery from '/map/agv/ctuLoadedNoBattery.svg';
import ctuLoadedHalfBattery from '/map/agv/ctuLoadedHalfBattery.svg';
import ctuLoadedFullBattery from '/map/agv/ctuLoadedFullBattery.svg';
// asr
import ASREmptyNoBattery from '/map/sca/ASREmptyNoBattery.svg';
import ASREmptyHalfBattery from '/map/sca/ASREmptyHalfBattery.svg';
import ASREmptyFullBattery from '/map/sca/ASREmptyFullBattery.svg';
import ASRLoadedNoBattery from '/map/sca/ASRLoadedNoBattery.svg';
import ASRLoadedHalfBattery from '/map/sca/ASRLoadedHalfBattery.svg';
import ASRLoadedFullBattery from '/map/sca/ASRLoadedFullBattery.svg';
let app, mapContainer, themeMode;
let selectedSprite, effectOverlay, effectTicker;
@@ -114,6 +121,11 @@
            sprite.width = 750;
            sprite.height = 1300;
            sprite.zIndex = DEVICE_Z_INDEX.AGV;
            // // sprite.width = 750;
            // // sprite.height = 1300;
            // sprite.zIndex = DEVICE_Z_INDEX.AGV;
            // sprite.scale.set(12, 10)
            break
        case DEVICE_TYPE.POINT:
            sprite = new PIXI.Sprite(PIXI.Texture.from(point, { resourceOptions: { scale: 1 } }));
@@ -706,6 +718,25 @@
    }
}
// export const generateAgvSpriteTexture = (agvStatusMode) => {
//     switch (agvStatusMode) {
//         case AGV_STATUS_MODE.EMPTY_NO_BATTERY:
//             return ASREmptyNoBattery;
//         case AGV_STATUS_MODE.EMPTY_HALF_BATTERY:
//             return ASREmptyHalfBattery;
//         case AGV_STATUS_MODE.EMPTY_FULL_BATTERY:
//             return ASREmptyFullBattery;
//         case AGV_STATUS_MODE.LOADED_NO_BATTERY:
//             return ASRLoadedNoBattery;
//         case AGV_STATUS_MODE.LOADED_HALF_BATTERY:
//             return ASRLoadedHalfBattery;
//         case AGV_STATUS_MODE.LOADED_FULL_BATTERY:
//             return ASRLoadedFullBattery;
//         default:
//             return;
//     }
// }
export function createAgvJobPanel(parentContainer, text) {
    const panelScale = 4;
@@ -800,12 +831,14 @@
        });
        agvText.anchor.set(0.5, 0.5);
        agvText.position.set(0, 8);
        // agvText.position.set(0, 18);
        agvText.scale.set(MAP_MIRROR ? -1 : 1, 1)
        agvSprite.addChild(agvText);
        agvSprite.updateTextRotation = () => {
            if (agvText && agvSprite) {
                agvText.rotation = -agvSprite.rotation - rotationParseNum(MAP_DEFAULT_ROTATION);
                // agvText.rotation = -agvSprite.rotation - rotationParseNum(MAP_DEFAULT_ROTATION + 180);
            }
        };
        agvSprite.updateTextRotation();
zy-acs-flow/src/page/agvModel/AgvModelCreate.jsx
@@ -108,19 +108,19 @@
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                <Grid item xs={4} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.agvModel.length"
                                        source="length"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                <Grid item xs={4} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.agvModel.width"
                                        source="width"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                <Grid item xs={4} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.agvModel.height"
                                        source="height"
@@ -183,8 +183,8 @@
                                        label="table.field.agvModel.allDirection"
                                        source="allDirection"
                                        choices={[
                                            { id: 0, name: '否' },
                                            { id: 1, name: '是' },
                                            { id: 0, name: 'common.enums.false' },
                                            { id: 1, name: 'common.enums.true' },
                                        ]}
                                        validate={required()}
                                    />
@@ -196,12 +196,34 @@
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.agvModel.mqttTopic"
                                        source="mqttTopic"
                                        parse={v => v}
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.agvModel.needUndocking"
                                        source="needUndocking"
                                        choices={[
                                            { id: 0, name: 'common.enums.false' },
                                            { id: 1, name: 'common.enums.true' },
                                        ]}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.agvModel.backupAction"
                                        source="backupAction"
                                        choices={[
                                            { id: 0, name: 'common.enums.false' },
                                            { id: 1, name: 'common.enums.true' },
                                        ]}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
zy-acs-flow/src/page/agvModel/AgvModelEdit.jsx
@@ -85,15 +85,9 @@
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.agvModel.backpack"
                                source="backpack"
                            />
                            <NumberInput
                                label="table.field.agvModel.length"
                                source="length"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.agvModel.width"
                                source="width"
@@ -111,6 +105,17 @@
                            <NumberInput
                                label="table.field.agvModel.diameter"
                                source="diameter"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.agvModel.password"
                                source="password"
                                parse={v => v}
                            />
                            <NumberInput
                                label="table.field.agvModel.backpack"
                                source="backpack"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
@@ -139,11 +144,15 @@
                                source="protocol"
                                parse={v => v}
                            />
                            <TextInput
                            {/* <TextInput
                                label="table.field.agvModel.mqttTopic"
                                source="mqttTopic"
                                parse={v => v}
                            />
                            /> */}
                        </Stack>
                        <Stack direction='row' gap={2}>
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
@@ -154,14 +163,27 @@
                            label="table.field.agvModel.allDirection"
                            source="allDirection"
                            choices={[
                                { id: 0, name: '否' },
                                { id: 1, name: '是' },
                                { id: 0, name: 'common.enums.false' },
                                { id: 1, name: 'common.enums.true' },
                            ]}
                        />
                        <TextInput
                            label="table.field.agvModel.password"
                            source="password"
                            parse={v => v}
                        <SelectInput
                            label="table.field.agvModel.needUndocking"
                            source="needUndocking"
                            choices={[
                                { id: 0, name: 'common.enums.false' },
                                { id: 1, name: 'common.enums.true' },
                            ]}
                            validate={required()}
                        />
                        <SelectInput
                            label="table.field.agvModel.backupAction"
                            source="backupAction"
                            choices={[
                                { id: 0, name: 'common.enums.false' },
                                { id: 1, name: 'common.enums.true' },
                            ]}
                            validate={required()}
                        />
                        <StatusSelectInput />
                        <Box mt="2em" />
zy-acs-flow/src/page/agvModel/AgvModelList.jsx
@@ -153,6 +153,8 @@
                    <BooleanField source="allDirectionBool" label="table.field.agvModel.allDirection" sortable={false} />
                    <TextField source="protocol" label="table.field.agvModel.protocol" />
                    <TextField source="mqttTopic" label="table.field.agvModel.mqttTopic" />
                    <BooleanField source="needUndockingBool" label="table.field.agvModel.needUndocking" sortable={false} />
                    <BooleanField source="backupActionBool" label="table.field.agvModel.backupAction" sortable={false} />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
zy-acs-flow/src/page/agvModel/AgvModelPanel.jsx
@@ -42,107 +42,118 @@
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.uuid"
                                title="table.field.agvModel.uuid"
                                property={record.uuid}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.type"
                                title="table.field.agvModel.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.name"
                                title="table.field.agvModel.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.length"
                                title="table.field.agvModel.length"
                                property={record.length}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.width"
                                title="table.field.agvModel.width"
                                property={record.width}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.height"
                                title="table.field.agvModel.height"
                                property={record.height}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.liftHeight"
                                title="table.field.agvModel.liftHeight"
                                property={record.liftHeight}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.diameter"
                                title="table.field.agvModel.diameter"
                                property={record.diameter}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.password"
                                title="table.field.agvModel.password"
                                property={record.password}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.backpack"
                                title="table.field.agvModel.backpack"
                                property={record.backpack}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.lowBattery"
                                title="table.field.agvModel.lowBattery"
                                property={record.lowBattery}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.quaBattery"
                                title="table.field.agvModel.quaBattery"
                                property={record.quaBattery}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.travelSpeed"
                                title="table.field.agvModel.travelSpeed"
                                property={record.travelSpeed}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.workDirection"
                                title="table.field.agvModel.workDirection"
                                property={record.workDirection}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.allDirection"
                                property={record.allDirection$}
                                title="table.field.agvModel.allDirection"
                                property={record.allDirection ? translate('common.enums.true') : translate('common.enums.false')}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.protocol"
                                title="table.field.agvModel.protocol"
                                property={record.protocol}
                            />
                        </Grid>
                        <Grid item xs={6}>
                        {/* <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.mqttTopic"
                                title="table.field.agvModel.mqttTopic"
                                property={record.mqttTopic}
                            />
                        </Grid> */}
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.needUndocking"
                                property={record.needUndockingBool ? translate('common.enums.true') : translate('common.enums.false')}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.agvModel.backupAction"
                                property={record.backupAction ? translate('common.enums.true') : translate('common.enums.false')}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
zy-acs-flow/src/page/code/CodeCreate.jsx
@@ -110,9 +110,10 @@
                                        label="table.field.code.corner"
                                        source="corner"
                                        choices={[
                                            { id: 1, name: '是' },
                                            { id: 0, name: '否' },
                                            { id: 0, name: 'common.enums.false' },
                                            { id: 1, name: 'common.enums.true' },
                                        ]}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
@@ -127,12 +128,24 @@
                                        source="y"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.code.scale"
                                        source="scale"
                                        parse={v => v}
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.code.spin"
                                        source="spin"
                                        choices={[
                                            { id: 0, name: 'page.code.enums.spin.na' },
                                            { id: 1, name: 'page.code.enums.spin.cw' },
                                            { id: 2, name: 'page.code.enums.spin.ccw' },
                                        ]}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
zy-acs-flow/src/page/code/CodeEdit.jsx
@@ -99,6 +99,16 @@
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <SelectInput
                                label="table.field.code.spin"
                                source="spin"
                                choices={[
                                    { id: 0, name: 'page.code.enums.spin.na' },
                                    { id: 1, name: 'page.code.enums.spin.cw' },
                                    { id: 2, name: 'page.code.enums.spin.ccw' },
                                ]}
                                validate={required()}
                            />
                            <TextInput
                                label="table.field.code.scale"
                                source="scale"
zy-acs-flow/src/page/code/CodeList.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';
@@ -76,9 +77,18 @@
            { id: '1', name: 'common.enums.true' },
            { id: '0', name: 'common.enums.false' },
        ]}
        alwaysOn
    />,
    <TextInput source="scale" label="table.field.code.scale" />,
    // <TextInput source="scale" label="table.field.code.scale" />,
    <SelectInput source="spin" label="table.field.code.spin"
        choices={[
            { id: 0, name: 'page.code.enums.spin.na' },
            { id: 1, name: 'page.code.enums.spin.cw' },
            { id: 2, name: 'page.code.enums.spin.ccw' },
        ]}
    // alwaysOn
    // emptyText={false}
    />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
@@ -128,7 +138,7 @@
                    rowClick={(id, resource, record) => false}
                    expand={() => <CodePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                    omit={['id', 'scale', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="uuid" label="table.field.code.uuid" />
@@ -137,7 +147,22 @@
                    <NumberField source="y" label="table.field.code.y" />
                    <BooleanField source="cornerBool" label="table.field.code.corner" sortable={false} />
                    <TextField source="scale" label="table.field.code.scale" />
                    <FunctionField
                        label="table.field.code.spin"
                        sortable={false}
                        render={(record) => {
                            switch (record.spin) {
                                case 0:
                                    return translate('page.code.enums.spin.na');
                                case 1:
                                    return translate('page.code.enums.spin.cw');
                                case 2:
                                    return translate('page.code.enums.spin.ccw');
                                default:
                                    return 'N/A';
                            }
                        }}
                    />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
zy-acs-gateway/src/main/java/com/zy/acs/gateway/constant/ProtocolPojoType.java
@@ -22,6 +22,8 @@
    PATH_ACK_COMMAND(ProtocolType.PATH_ACK_RESPONSE, AGV_B1_DOWN.class),
    PICK_PLACE_ACK(ProtocolType.PICK_PLACE_ACK, AGV_06_DOWN.class),
    ;
zy-acs-gateway/src/main/java/com/zy/acs/gateway/constant/ProtocolType.java
@@ -10,6 +10,8 @@
    PATH_COMMAND(0x01, "路径数据包", DirectionType.DOWN),
    PICK_PLACE_ACK(0x06, "取放货应答包", DirectionType.DOWN),
    ACTION_COMMAND(0x02, "动作命令包", DirectionType.DOWN),
    HEARTBEAT_COMMAND(0x03, "心跳包", DirectionType.DOWN),
@@ -30,6 +32,8 @@
    PATH_ACK(0x01, "路径应答包", DirectionType.UP),
    PICK_PLACE_REQUEST(0x06, "取放货请求包", DirectionType.UP),
    COMMAND_ACK(0x02, "命令应答包", DirectionType.UP),
    ACTION_COMPLETE(0x11, "动作完成包", DirectionType.UP),
zy-acs-gateway/src/main/java/com/zy/acs/gateway/handler/AgvPackageServerHandler.java
@@ -57,6 +57,13 @@
                break label;
            case PICK_PLACE_REQUEST:   // 取放货请求包
                AGV_06_UP agv_06_up = (AGV_06_UP) pac.getBody().getMessageBody();
                redis.push(RedisConstant.AGV_COMPLETE_FLAG, AgvProtocol.build(uniqueNo).setMessageBody(agv_06_up));
                break label;
            case COMMAND_ACK:   // 命令包 ack
                AGV_02_UP agv_02_up = (AGV_02_UP) pac.getBody().getMessageBody();
zy-acs-gateway/src/main/java/com/zy/acs/gateway/listen/MessageListener.java
@@ -48,7 +48,7 @@
                }
                // 间隔
                try {
                    Thread.sleep(500);
                    Thread.sleep(300);
                } catch (Exception ignore) {}
            }
        });
zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java
@@ -156,6 +156,7 @@
            agvDetail.setStatus(AgvStatusType.IDLE.val);
            agvDetail.setAgvAngle(workDirection);
            agvDetail.setVol(5000);
            agvDetail.setSoc(80);
            agvDetailService.updateById(agvDetail);
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MaintainScheduler.java
@@ -54,7 +54,7 @@
        for (Agv agv : agvList) {
            AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
            AgvModel agvModel = agvModelService.getByAgvId(agv.getId());
            if (null == agvDetail || null == agvDetail.getVol() || null == agvDetail.getAgvStatus()) {
            if (null == agvDetail || null == agvDetail.getSoc() || null == agvDetail.getAgvStatus()) {
                continue;
            }
            if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
@@ -96,7 +96,7 @@
        for (Agv agv : agvList) {
            AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
            AgvModel agvModel = agvModelService.getByAgvId(agv.getId());
            if (null == agvDetail || null == agvDetail.getVol() || null == agvDetail.getAgvStatus() || null == agvDetail.getRecentCode()) {
            if (null == agvDetail || null == agvDetail.getSoc() || null == agvDetail.getAgvStatus() || null == agvDetail.getRecentCode()) {
                continue;
            }
            // low battery status, that need to go to charge
@@ -105,7 +105,7 @@
//            }
            // is charging ?
            if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
                if (agvDetail.getVol() < agvModel.getQuaBattery()) {
                if (agvDetail.getSoc() < agvModel.getQuaBattery()) {
                    continue;
                }
            }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java
@@ -134,13 +134,13 @@
            // detail
            String errorMSg = errorType != null ? errorType.getMsg() : agv_04_up.getHexFaultId();
            detail.setError(errorMSg);
            detail.setErrorTime(new Date());
            detail.setErrorTime(now);
        }
        // 故障复位
        if (!Cools.isEmpty(detail.realError())) {
            assert detail.getErrorTime() != null;
            if (DateUtils.diffToSeconds(detail.getErrorTime(), new Date()) > 20) {
            if (DateUtils.diffToSeconds(detail.getErrorTime(), now) > 10) {
                detail.setError(MapDataConstant.EMPTY_OF_ERROR);
            }
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -10,10 +10,7 @@
import com.zy.acs.common.domain.BaseResult;
import com.zy.acs.common.domain.protocol.*;
import com.zy.acs.common.domain.protocol.action.*;
import com.zy.acs.common.enums.AgvBackpackType;
import com.zy.acs.common.enums.AgvCompleteType;
import com.zy.acs.common.enums.AgvDirectionType;
import com.zy.acs.common.enums.AgvSpeedType;
import com.zy.acs.common.enums.*;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.common.utils.Utils;
@@ -950,7 +947,7 @@
                        if (!lastCode.getCornerBool()) {
                            // 如果是作业方向,但是小车在巷道内方向错误,则停止
                            if (reverse && !lastDirection.equals(nextDirection)) {
//                                throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整");
                                throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整");
                            }
                            // 如果不是作业方向,判断是否相反方向,如果反方向则倒退行走
                            if (nextDirection.equals((lastDirection + 180) % 360)) {
@@ -972,7 +969,7 @@
                                            null,    // 动作号
                                            null,    // 优先级
                                            ActionTypeType.TurnCorner.desc,    // 名称
                                            mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                            (double) mapService.spinDirection(lastCode).val,     // 属性值
                                            lastCode.getData(),    // 地面码
                                            String.valueOf(nextDirection),   // 动作参数
                                            ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -996,7 +993,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    (double) mapService.spinDirection(lastCode).val,    // 属性值
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(nextDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1047,7 +1044,7 @@
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.TurnCorner.desc,    // 名称
                                mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                (double) mapService.spinDirection(lastCode).val,    // 属性值
                                lastCode.getData(),    // 地面码
                                String.valueOf(workDirection),   // 动作参数
                                ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1066,6 +1063,7 @@
                AgvDirectionType agvDirectionType;
                Double staWorkDirection;
                AgvBackpackType backpackType = AgvBackpackType.query(segment.getBackpack());
                // todo agvModel backpackAction ?
                switch (Objects.requireNonNull(TaskPosDto.queryPosType(segment.getPosType()))) {
                    case ORI_LOC:
                        assert backpackType != null;
@@ -1169,7 +1167,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    (double) mapService.spinDirection(lastCode).val,   // 属性值
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(oriStaWorkDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1231,7 +1229,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    (double) mapService.spinDirection(lastCode).val,    // 属性值
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(destStaWorkDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1288,7 +1286,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    (double) mapService.spinDirection(lastCode).val,    // 属性值
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(chargeDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1363,6 +1361,28 @@
            }
            // 如果充电中,则先断开充电
            // todo agvModel backpackAction ?
            if (agvModel.getNeedUndockingBool() && agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
                String undockingCode = Cools.isEmpty(actionList) ? lastCode.getData() : actionList.get(0).getCode();
                // undocking charge
                actionList.add(0, new Action(
                        null,    // 编号
                        null,    // 总线
                        null,    // 任务
                        null,    // 动作号
                        null,    // 优先级
                        ActionTypeType.UndockingCharge.desc,    // 名称
                        null,    // 属性值
                        undockingCode,    // 地面码
                        null,   // 动作参数
                        ActionTypeType.UndockingCharge.val(),    // 动作类型
                        actionPrepareSts,    // 动作进度
                        agvId,    // AGV
                        now    // 工作时间
                ));
            }
            // finish
            actionList.add(new Action(
                    null,    // 编号
@@ -1380,6 +1400,7 @@
                    now    // 工作时间
            ));
            // todo asr need optimize sort ?
            List<Action> newActionList = actionSorter.optimizeSort(actionList);
            String groupId = String.valueOf(snowflakeIdWorker.nextId()).substring(3);
@@ -1574,6 +1595,11 @@
                                .setQrCode(action.getCode())
                        );
                        break;
                    case UndockingCharge:
                        agvAction.add(new AgvActionItem<>(UndockingChargeAction.class)
                                .setQrCode(action.getCode())
                        );
                        break;
                    default:
                        break;
                }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
@@ -13,6 +13,7 @@
import com.zy.acs.manager.manager.entity.Loc;
import com.zy.acs.manager.manager.entity.Segment;
import com.zy.acs.manager.manager.entity.Sta;
import com.zy.acs.manager.manager.enums.CodeSpinType;
import com.zy.acs.manager.manager.service.ActionService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.system.service.ConfigService;
@@ -430,6 +431,13 @@
        return turnMatrixNode == TurnNodeType.TURN.val;
    }
    public CodeSpinType spinDirection(Code code) {
        if (Cools.isEmpty(code)) {
            return CodeSpinType.NA;
        }
        return CodeSpinType.of(code.getSpin());
    }
    /**
     * That vehicle is walking if the dynamic node count > 1
     */
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/AgvModelController.java
@@ -11,6 +11,7 @@
import com.zy.acs.manager.common.domain.PageParam;
import com.zy.acs.manager.common.utils.ExcelUtil;
import com.zy.acs.manager.manager.entity.AgvModel;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.AgvModelService;
import com.zy.acs.manager.manager.service.impl.AgvModelServiceImpl;
import com.zy.acs.manager.system.controller.BaseController;
@@ -71,11 +72,14 @@
                    .eq(AgvModel::getType, agvModel.getType())) > 0) {
                return R.error("this model type has already exist !");
            }
        }        agvModel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
        }
        Date now = new Date();
        agvModel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
        agvModel.setStatus(StatusType.ENABLE.val);
        agvModel.setCreateBy(getLoginUserId());
        agvModel.setCreateTime(new Date());
        agvModel.setCreateTime(now);
        agvModel.setUpdateBy(getLoginUserId());
        agvModel.setUpdateTime(new Date());
        agvModel.setUpdateTime(now);
        if (!agvModelService.save(agvModel)) {
            return R.error("Save Fail");
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/AgvModel.java
@@ -125,6 +125,18 @@
    private String mqttTopic;
    /**
     * 断开充电{1:是,0:否}
     */
    @ApiModelProperty(value= "断充动作 1: 是  0: 否  ")
    private Integer needUndocking;
    /**
     * 背篓动作 {1:是,0:否}
     */
    @ApiModelProperty(value= "背篓动作 1: 是  0: 否  ")
    private Integer backupAction;
    /**
     * 状态 1: 正常  0: 禁用  
     */
    @ApiModelProperty(value= "状态 1: 正常  0: 禁用  ")
@@ -172,63 +184,29 @@
    @ApiModelProperty(value= "备注")
    private String memo;
    public AgvModel() {}
    public AgvModel(String uuid,String type,String name,Integer length,Integer width,Integer height,Integer liftHeight,Integer diameter,String password,Integer backpack,Integer lowBattery,Integer quaBattery,Integer travelSpeed,Double workDirection,Integer allDirection,String protocol,String mqttTopic,Integer status,Integer deleted,Long tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.uuid = uuid;
        this.type = type;
        this.name = name;
        this.length = length;
        this.width = width;
        this.height = height;
        this.liftHeight = liftHeight;
        this.diameter = diameter;
        this.password = password;
        this.backpack = backpack;
        this.lowBattery = lowBattery;
        this.quaBattery = quaBattery;
        this.travelSpeed = travelSpeed;
        this.workDirection = workDirection;
        this.allDirection = allDirection;
        this.protocol = protocol;
        this.mqttTopic = mqttTopic;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    public Boolean getNeedUndockingBool(){
        if (null == this.needUndocking){ return null; }
        switch (this.needUndocking){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
//    AgvModel agvModel = new AgvModel(
//            null,    // 编号
//            null,    // 类型
//            null,    // 名称
//            null,    // 长度
//            null,    // 宽度
//            null,    // 高度
//            null,    // 举升高度
//            null,    // 旋转直径
//            null,    // 设备密码
//            null,    // 背篓
//            null,    // 最低电量
//            null,    // 额定电量
//            null,    // 走行速度
//            null,    // 作业方向
//            null,    // 全向
//            null,    // 协议
//            null,    // mqtt主题
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间
//            null    // 备注
//    );
    public Boolean getBackupActionBool(){
        if (null == this.backupAction){ return null; }
        switch (this.backupAction){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
    public Boolean getAllDirectionBool(){
        if (null == this.allDirection){ return null; }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Code.java
@@ -59,6 +59,12 @@
    private String scale;
    /**
     * 旋转方向 0: N/A 1: 顺时针  2: 逆时针
     */
    @ApiModelProperty(value= "旋转方向 0: N/A 1: 顺时针  2: 逆时针  ")
    private Integer spin;
    /**
     * 状态 1: 正常  0: 冻结  
     */
    @ApiModelProperty(value= "状态 1: 正常  0: 冻结  ")
@@ -105,40 +111,6 @@
     */
    @ApiModelProperty(value= "备注")
    private String memo;
    public Code() {}
    public Code(String uuid,String data,Double x,Double y,Integer corner,Integer status,Integer deleted,Long tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.uuid = uuid;
        this.data = data;
        this.x = x;
        this.y = y;
        this.corner = corner;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Code code = new Code(
//            null,    // 编号
//            null,    // 条码[非空]
//            null,    // x坐标
//            null,    // y坐标
//            null,    // 转角[非空]
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间
//            null    // 备注
//    );
    public Boolean getCornerBool(){
        if (null == this.corner){ return null; }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/enums/ActionTypeType.java
@@ -24,6 +24,7 @@
    LoadPlatformLift("载货台升降"), // 载货台升降
    FinishPath("整个路径结束"), //     整个路径结束
    DockingCharge("对接充电桩"), //     对接充电桩
    UndockingCharge("断开充电桩"), //     断开充电桩
    ;
    ActionTypeType(String desc) {
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/enums/CodeSpinType.java
New file
@@ -0,0 +1,25 @@
package com.zy.acs.manager.manager.enums;
public enum CodeSpinType {
    NA(0),
    CW(1),
    CCW(2),
    ;
    public int val;
    CodeSpinType(int val) {
        this.val = val;
    }
    public static CodeSpinType of(int val) {
        for (CodeSpinType type : CodeSpinType.values()) {
            if (type.val == val) {
                return type;
            }
        }
        return NA;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvDetailServiceImpl.java
@@ -73,9 +73,9 @@
            agvModel = agvModelService.getByAgvId(agv.getId());
        }
        if (null == agv.getChargeLine()) {
            return agvDetail.getVol() < agvModel.getLowBattery();
            return agvDetail.getSoc() < agvModel.getLowBattery();
        } else {
            return agvDetail.getVol() < Math.max(agv.getChargeLine(), agvModel.getLowBattery());
            return agvDetail.getSoc() < Math.max(agv.getChargeLine(), agvModel.getLowBattery());
        }
    }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AgvServiceImpl.java
@@ -206,7 +206,7 @@
            log.warn("[{}]号Agv未收到状态包......", agvNo);
            return false;
        }
        if (agvDetail.getVol() == 0) {
        if (null == agvDetail.getSoc() || agvDetail.getSoc() == 0) {
            return false;
        }
        if (!agvDetail.getAgvStatus().equals(AgvStatusType.IDLE) && !agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
@@ -214,7 +214,7 @@
            return false;
        }
        if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
            if (agvDetail.getVol() < agvModel.getQuaBattery()) {
            if (agvDetail.getSoc() < agvModel.getQuaBattery()) {
                return false;
            }
        }
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/FuncStaServiceImpl.java
@@ -94,7 +94,7 @@
                    AgvModel agvModel = agvModelService.getByAgvId(agv.getId());
                    AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
                    if (agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
                        if (agvDetail.getVol() < agvModel.getQuaBattery()) {
                        if (agvDetail.getSoc() < agvModel.getQuaBattery()) {
                            return false;
                        }
                    } else {
zy-acs-manager/src/main/resources/mapper/manager/AgvDetailMapper.xml
@@ -27,7 +27,7 @@
    </sql>
    <select id="selectMajorByAgvId" resultType="com.zy.acs.manager.manager.entity.AgvDetail">
        SELECT id, agv_id, pos, code, last_code, agv_angle, vol, backpack, status, deleted
        SELECT id, agv_id, pos, code, last_code, agv_angle, vol, soc, backpack, status, deleted
        FROM man_agv_detail
        WHERE agv_id = #{agvId}
        LIMIT 1