#
Junjie
2024-10-12 39a729e911ca4e5fb1c629fabf71cc3cf02dade8
#
4个文件已添加
7个文件已修改
572 ■■■■ 已修改文件
zy-asrs-flow/src/global.less 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-flow/src/pages/task/task/components/shuttleCommand.jsx 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-flow/src/pages/task/task/index.jsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/TaskController.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandRollbackParam.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandUpdateCompleteParam.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/DeviceTimer.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NyShuttleThread.java 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-flow/src/global.less
@@ -97,3 +97,7 @@
.centered-select .ant-select-selection-item {
  text-align: center;
}
.highlight-row {
  background-color: #00d9ff;
}
zy-asrs-flow/src/pages/task/task/components/shuttleCommand.jsx
New file
@@ -0,0 +1,169 @@
import React, { useState, useRef, useEffect } from 'react';
import { Form, Modal, Space, Table, Tag, Switch, message } from 'antd';
import { FormattedMessage, useIntl } from '@umijs/max';
import moment from 'moment';
import Http from '@/utils/http';
const ShuttleCommand = (props) => {
    const intl = useIntl();
    const [form] = Form.useForm();
    const { } = props;
    const [commandData, setCommandData] = useState([]);
    const getCommands = () => {
        Http.doPost('api/task/shuttleCommand', {
            taskNo: props.values.taskNo
        }).then(resp => {
            if (resp.data != null) {
                setCommandData(resp.data.records)
            }
        })
    }
    const toggle = async (record) => {
        const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '正在更新' }));
        try {
            const resp = await Http.doPost('api/task/shuttleCommand/completeSwitch', {
                taskNo: props.values.taskNo,
                index: record.index,
                complete: !record.complete
            });
            if (resp.code === 200) {
                getCommands()
                message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '更新成功' }));
                return true;
            } else {
                message.error(resp.msg);
                return false;
            }
        } catch (error) {
            message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '更新失败请重试!' }));
            return false;
        } finally {
            hide();
        }
    };
    const commandRollback = async (record) => {
        const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '正在更新' }));
        try {
            const resp = await Http.doPost('api/task/shuttleCommand/commandRollback', {
                taskNo: props.values.taskNo,
                index: record.index
            });
            if (resp.code === 200) {
                getCommands()
                message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '更新成功' }));
                return true;
            } else {
                message.error(resp.msg);
                return false;
            }
        } catch (error) {
            message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '更新失败请重试!' }));
            return false;
        } finally {
            hide();
        }
    }
    const highlightRow = (record, index) => {
        const isHighlight = record.commandStep === index;
        return isHighlight ? 'highlight-row' : '';
    };
    const columns = [
        {
            title: '命令类型',
            dataIndex: 'mode$',
            key: 'mode$',
        },
        {
            title: '起点',
            dataIndex: 'start',
            key: 'start',
        },
        {
            title: '终点',
            dataIndex: 'target',
            key: 'target',
        },
        {
            title: '命令报文',
            dataIndex: 'body',
            key: 'body',
            ellipsis: true,
        },
        {
            title: '穿梭车ID',
            dataIndex: 'shuttleNo',
            key: 'shuttleNo',
        },
        {
            title: '是否完成',
            key: 'complete',
            dataIndex: 'complete',
            render: (_, record) => (
                <>
                    <Switch checkedChildren="完成" unCheckedChildren="未完成" checked={record.complete} onClick={async () => {
                        toggle(record)
                    }} />
                </>
            ),
        },
        {
            title: '操作',
            key: 'action',
            render: (_, record) => (
                <Space size="middle">
                    <a onClick={async () => {
                        commandRollback(record)
                    }}>
                        回退命令
                    </a>
                </Space>
            ),
        },
    ];
    useEffect(() => {
        form.resetFields();
        form.setFieldsValue({
            ...props.values
        })
        getCommands()
    }, [form, props])
    const handleCancel = () => {
        props.onCancel();
    };
    const handleOk = () => {
        form.submit();
    }
    const handleFinish = async (values) => {
        props.onSubmit({ ...values });
    }
    return (
        <>
            <Modal
                title={
                    intl.formatMessage({ id: 'page.shuttleCommand', defaultMessage: '穿梭车指令' })
                }
                width={640}
                forceRender
                destroyOnClose
                open={props.open}
                onCancel={handleCancel}
                onOk={handleOk}
            >
                <Table columns={columns} dataSource={commandData} rowClassName={highlightRow} />
            </Modal>
        </>
    )
}
export default ShuttleCommand;
zy-asrs-flow/src/pages/task/task/index.jsx
@@ -11,6 +11,7 @@
import { PlusOutlined, ExportOutlined } from '@ant-design/icons';
import Http from '@/utils/http';
import Edit from './components/edit'
import ShuttleCommand from './components/shuttleCommand'
import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
import { statusMap } from '@/utils/enum-util'
import { repairBug } from '@/utils/common-util';
@@ -131,13 +132,13 @@
    }
};
const Main = () => {
    const intl = useIntl();
    const formTableRef = useRef();
    const actionRef = useRef();
    const [selectedRows, setSelectedRows] = useState([]);
    const [modalVisible, setModalVisible] = useState(false);
    const [shuttleCommandModalVisible, setShuttleCommandModalVisible] = useState(false);
    const [currentRow, setCurrentRow] = useState();
    const [searchParam, setSearchParam] = useState({});
@@ -525,7 +526,7 @@
        {
            title: '操作',
            dataIndex: 'option',
            width: 240,
            width: 300,
            valueType: 'option',
            render: (_, record) => [
                <Button
@@ -537,6 +538,16 @@
                    }}
                >
                    <FormattedMessage id='page.edit' defaultMessage='编辑' />
                </Button>,
                <Button
                    type="link"
                    key="shuttleCommand"
                    onClick={() => {
                        setShuttleCommandModalVisible(true);
                        setCurrentRow(record);
                    }}
                >
                    <FormattedMessage id='page.shuttleCommand' defaultMessage='穿梭车指令' />
                </Button>,
                // <Button
                //     type="link"
@@ -743,6 +754,33 @@
                    }
                }}
            />
            <ShuttleCommand
                open={shuttleCommandModalVisible}
                values={currentRow || {}}
                onCancel={
                    () => {
                        setShuttleCommandModalVisible(false);
                        setCurrentRow(undefined);
                    }
                }
                onSubmit={async (values) => {
                    let ok = false;
                    if (values.id) {
                        ok = await handleUpdate({ ...values }, intl)
                    } else {
                        ok = await handleSave({ ...values }, intl)
                    }
                    if (ok) {
                        setShuttleCommandModalVisible(false);
                        setCurrentRow(undefined);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                }}
            />
        </PageContainer>
    );
};
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
@@ -133,12 +133,14 @@
        int commandStep = redisCommand.getCommandStep();
        // 完结上一条命令
        boolean updateCommand = false;
        if (commandStep != 0) {
            ShuttleCommand command = commands.get(commandStep - 1);
            if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
                // 正常移动
                if (command.getTargetLocNo().equals(shuttleProtocol.getCurrentLocNo())) {
                    command.setComplete(true);
                    updateCommand = true;
                    //解锁锁定路径,上一条路径
                    List<NavigateNode> nodes = null;
                    try {
@@ -166,6 +168,7 @@
                //判断是否顶升到位
                if (shuttleProtocol.getHasLift()) {
                    command.setComplete(true);
                    updateCommand = true;
//                    //判断是否有物
//                    if (shuttleProtocol.getHasPallet()) {
//                        command.setComplete(true);
@@ -176,19 +179,24 @@
                // 判断是否下降到位
                if (!shuttleProtocol.getHasLift()) {
                    command.setComplete(true);
                    updateCommand = true;
                }
            } else if (command.getMode() == ShuttleCommandModeType.CHARGE_OPEN.id) {
                // 充电开
                //判断小车充电状态
                if (shuttleProtocol.getHasCharge()) {
                    command.setComplete(true);
                    updateCommand = true;
                }
            }else {
                command.setComplete(true);//其他命令默认认为完成
                updateCommand = true;
            }
            if(updateCommand) {
            // 更新redis数据
            redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + redisCommand.getTaskNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect));
            }
            if (!command.getComplete()) {
                return false;
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/TaskController.java
@@ -1,22 +1,39 @@
package com.zy.asrs.wcs.core.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zy.asrs.framework.common.Cools;
import com.zy.asrs.framework.common.R;
import com.zy.asrs.wcs.common.annotation.OperationLog;
import com.zy.asrs.wcs.common.domain.BaseParam;
import com.zy.asrs.wcs.common.domain.KeyValVo;
import com.zy.asrs.wcs.common.domain.PageParam;
import com.zy.asrs.wcs.core.domain.param.ShuttleCommandParam;
import com.zy.asrs.wcs.core.domain.param.ShuttleCommandRollbackParam;
import com.zy.asrs.wcs.core.domain.param.ShuttleCommandUpdateCompleteParam;
import com.zy.asrs.wcs.core.entity.Motion;
import com.zy.asrs.wcs.core.entity.MotionLog;
import com.zy.asrs.wcs.core.entity.Task;
import com.zy.asrs.wcs.core.entity.TaskLog;
import com.zy.asrs.wcs.core.model.NavigateNode;
import com.zy.asrs.wcs.core.model.command.ShuttleAssignCommand;
import com.zy.asrs.wcs.core.model.command.ShuttleCommand;
import com.zy.asrs.wcs.core.model.command.ShuttleRedisCommand;
import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType;
import com.zy.asrs.wcs.core.model.enums.TaskStsType;
import com.zy.asrs.wcs.core.service.MotionLogService;
import com.zy.asrs.wcs.core.service.MotionService;
import com.zy.asrs.wcs.core.service.TaskLogService;
import com.zy.asrs.wcs.core.service.TaskService;
import com.zy.asrs.wcs.core.utils.RedisUtil;
import com.zy.asrs.wcs.core.utils.Utils;
import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
import com.zy.asrs.wcs.system.controller.BaseController;
import com.zy.asrs.wcs.utils.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +56,10 @@
    private MotionService motionService;
    @Autowired
    private MotionLogService motionLogService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ObjectMapper objectMapper;
    @PreAuthorize("hasAuthority('core:task:list')")
    @PostMapping("/task/page")
@@ -190,4 +211,112 @@
        return R.ok("取消成功");
    }
    @PreAuthorize("hasAuthority('core:task:list')")
    @PostMapping("/task/shuttleCommand")
    public R shuttleCommand(@RequestBody ShuttleCommandParam param) {
        Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo());
        if (object == null) {
            return R.ok();
        }
        ShuttleRedisCommand redisCommand = null;
        try {
            redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if (redisCommand == null) {
            return R.ok();
        }
        HashMap<String, Object> hashMap = new HashMap<>();
        ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
        List<ShuttleCommand> commands = assignCommand.getCommands();
        Integer commandStep = redisCommand.getCommandStep();//当前步序
        ArrayList<JSONObject> list = new ArrayList<>();
        int index = 0;
        for (ShuttleCommand command : commands) {
            JSONObject data = JSON.parseObject(JSON.toJSONString(command));
            data.put("index", index++);
            data.put("commandStep", commandStep);
            ShuttleCommandModeType type = ShuttleCommandModeType.get(command.getMode());
            if (type == null) {
                data.put("mode$", command.getMode());
            }else {
                data.put("mode$", type.desc);
            }
            if (command.getNodes() != null) {
                List<NavigateNode> nodes = command.getNodes();
                NavigateNode start = nodes.get(0);
                NavigateNode target = nodes.get(nodes.size() - 1);
                data.put("start", Utils.getLocNo(start.getX(), start.getY(), start.getZ()));
                data.put("target", Utils.getLocNo(target.getX(), target.getY(), target.getZ()));
            }
            list.add(data);
        }
        hashMap.put("total", commands.size());
        hashMap.put("records", list);
        hashMap.put("commandStep", commandStep);
        return R.ok().add(hashMap);
    }
    @PreAuthorize("hasAuthority('core:task:list')")
    @PostMapping("/task/shuttleCommand/completeSwitch")
    public R shuttleCommandCompleteSwitch(@RequestBody ShuttleCommandUpdateCompleteParam param) {
        Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo());
        if (object == null) {
            return R.error("指令不存在");
        }
        ShuttleRedisCommand redisCommand = null;
        try {
            redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if (redisCommand == null) {
            return R.error("指令不存在");
        }
        ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
        List<ShuttleCommand> commands = assignCommand.getCommands();
        ShuttleCommand command = commands.get(param.getIndex());
        command.setComplete(param.getComplete());
        redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect));
        return R.ok();
    }
    @PreAuthorize("hasAuthority('core:task:list')")
    @PostMapping("/task/shuttleCommand/commandRollback")
    public R shuttleCommandRollback(@RequestBody ShuttleCommandRollbackParam param) {
        Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo());
        if (object == null) {
            return R.error("指令不存在");
        }
        ShuttleRedisCommand redisCommand = null;
        try {
            redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if (redisCommand == null) {
            return R.error("指令不存在");
        }
        redisCommand.setCommandStep(param.getIndex());
        redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect));
        return R.ok();
    }
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandParam.java
New file
@@ -0,0 +1,10 @@
package com.zy.asrs.wcs.core.domain.param;
import lombok.Data;
@Data
public class ShuttleCommandParam {
    private String taskNo;
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandRollbackParam.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.wcs.core.domain.param;
import lombok.Data;
@Data
public class ShuttleCommandRollbackParam {
    private String taskNo;
    private Integer index;
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/param/ShuttleCommandUpdateCompleteParam.java
New file
@@ -0,0 +1,14 @@
package com.zy.asrs.wcs.core.domain.param;
import lombok.Data;
@Data
public class ShuttleCommandUpdateCompleteParam {
    private String taskNo;
    private Integer index;
    private Boolean complete;
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/DeviceTimer.java
@@ -28,27 +28,15 @@
    @Autowired
    private LiftAction liftAction;
    @Scheduled(cron = "0/1 * * * * ? ")
    public synchronized void executeShuttle() {
        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
                .eq(Device::getStatus, 1)
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()));
        for (Device device : list) {
            //小车空闲且有跑库程序
            shuttleAction.moveLoc(device);
            Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_FLAG + device.getDeviceNo());
            if (object == null) {
                continue;
            }
            Integer taskNo = Integer.valueOf(String.valueOf(object));
            if (taskNo != 0) {
                //存在任务需要执行
                boolean result = shuttleAction.executeWork(device, taskNo);
            }
        }
    }
//    @Scheduled(cron = "0/1 * * * * ? ")
//    public synchronized void executeShuttle() {
//        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
//                .eq(Device::getStatus, 1)
//                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()));
//        for (Device device : list) {
//
//        }
//    }
    @Scheduled(cron = "0/1 * * * * ? ")
    public synchronized void executeLift() {
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
@@ -45,11 +45,12 @@
                .eq(Task::getStatus, 1)
                .in(Task::getTaskSts, taskSts));
        for (Task task : tasks) {
            if(task.getTaskSts().equals(TaskStsType.COMPLETE_INBOUND.sts) || task.getTaskSts().equals(TaskStsType.COMPLETE_OUTBOUND.sts)){
            boolean httpRequest = doHttpRequest(task, "127.0.0.1:8080", "/wms/open/asrs//wrkMast/finish/v1");
            if (!httpRequest) {
                return;
            }
            }
            //记录库存信息
            updateRecordLoc(task);
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NyShuttleThread.java
@@ -9,6 +9,7 @@
import com.zy.asrs.framework.common.SpringUtils;
import com.zy.asrs.framework.exception.CoolException;
import com.zy.asrs.wcs.common.ExecuteSupport;
import com.zy.asrs.wcs.core.action.ShuttleAction;
import com.zy.asrs.wcs.core.domain.param.ShuttleMoveLocParam;
import com.zy.asrs.wcs.core.entity.BasShuttle;
import com.zy.asrs.wcs.core.entity.Loc;
@@ -62,6 +63,9 @@
    private List<JSONObject> socketResults = new ArrayList<>();
    //原始设备数据
    private Object originDeviceData;
    public NyShuttleThread(Device device, RedisUtil redisUtil) {
        this.device = device;
        this.redisUtil = redisUtil;
@@ -75,18 +79,118 @@
        //监听消息并存储
        Thread innerThread = new Thread(() -> {
            while (true) {
                try {
                listenSocketMessage();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        innerThread.start();
        //设备读取
        Thread readThread = new Thread(() -> {
        while (true) {
            try {
                read();
                Thread.sleep(500);
                    Thread.sleep(50);
            } catch (Exception e) {
                log.error("ShuttleThread Fail", e);
            }
            }
        });
        readThread.start();
        //设备执行
        Thread executeThread = new Thread(() -> {
            while (true) {
                try {
                    ShuttleAction shuttleAction = SpringUtils.getBean(ShuttleAction.class);
                    if (shuttleAction == null) {
                        continue;
                    }
                    Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_FLAG + device.getDeviceNo());
                    if (object == null) {
                        continue;
                    }
                    Integer taskNo = Integer.valueOf(String.valueOf(object));
                    if (taskNo != 0) {
                        //存在任务需要执行
                        boolean result = shuttleAction.executeWork(device, taskNo);
                    }
                    //小车空闲且有跑库程序
                    shuttleAction.moveLoc(device);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        executeThread.start();
        //其他任务
        Thread otherThread = new Thread(() -> {
            while (true) {
                try {
                    listenInit();//监听初始化事件
                    saveLog();//保存数据
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        otherThread.start();
    }
    private void saveLog() {
        if (shuttleProtocol == null) {
            return;
        }
        if (System.currentTimeMillis() - shuttleProtocol.getDeviceDataLog() > 1000 * 5) {
            if (this.originDeviceData != null) {
                //采集时间超过5s,保存一次数据记录
                //保存数据记录
                DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
                DeviceDataLog deviceDataLog = new DeviceDataLog();
                deviceDataLog.setOriginData(JSON.toJSONString(this.originDeviceData));
                deviceDataLog.setWcsData(JSON.toJSONString(shuttleProtocol));
                deviceDataLog.setType(String.valueOf(SlaveType.Shuttle));
                deviceDataLog.setDeviceNo(String.valueOf(shuttleProtocol.getShuttleNo()));
                deviceDataLog.setCreateTime(new Date());
                deviceDataLog.setHostId(device.getHostId());
                deviceDataLogService.save(deviceDataLog);
                //更新采集时间
                shuttleProtocol.setDeviceDataLog(System.currentTimeMillis());
            }
        }
        //将四向穿梭车状态保存至数据库
        BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class);
        BasShuttle basShuttle = shuttleService.getOne(new LambdaQueryWrapper<BasShuttle>()
                .eq(BasShuttle::getShuttleNo, device.getDeviceNo())
                .eq(BasShuttle::getHostId, device.getHostId()));
        if (basShuttle == null) {
            basShuttle = new BasShuttle();
            //四向穿梭车号
            basShuttle.setShuttleNo(Integer.valueOf(device.getDeviceNo()));
            basShuttle.setStatus(1);
            basShuttle.setDeleted(0);
            basShuttle.setHostId(device.getHostId());
            basShuttle.setDeviceId(device.getId().intValue());
            shuttleService.save(basShuttle);
        }
        //任务号
        basShuttle.setTaskNo(shuttleProtocol.getTaskNo().intValue());
        //修改时间
        basShuttle.setUpdateTime(new Date());
        //设备状态
        basShuttle.setProtocol(JSON.toJSONString(shuttleProtocol));
        if (shuttleService.updateById(basShuttle)) {
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getDeviceNo()));
        }
    }
@@ -167,7 +271,6 @@
                this.connect();
            }
            readStatus();
            listenInit();//监听初始化事件
        } catch (Exception e) {
            e.printStackTrace();
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】读取四向穿梭车状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
@@ -246,47 +349,9 @@
                    shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE);
                }
                if (System.currentTimeMillis() - shuttleProtocol.getDeviceDataLog() > 1000 * 5) {
                    //采集时间超过5s,保存一次数据记录
                    //保存数据记录
                    DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
                    DeviceDataLog deviceDataLog = new DeviceDataLog();
                    deviceDataLog.setOriginData(JSON.toJSONString(data));
                    deviceDataLog.setWcsData(JSON.toJSONString(shuttleProtocol));
                    deviceDataLog.setType(String.valueOf(SlaveType.Shuttle));
                    deviceDataLog.setDeviceNo(String.valueOf(shuttleProtocol.getShuttleNo()));
                    deviceDataLog.setCreateTime(new Date());
                    deviceDataLog.setHostId(device.getHostId());
                    deviceDataLogService.save(deviceDataLog);
                this.originDeviceData = data;
                    //更新采集时间
                    shuttleProtocol.setDeviceDataLog(System.currentTimeMillis());
                }
                //将四向穿梭车状态保存至数据库
                BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class);
                BasShuttle basShuttle = shuttleService.getOne(new LambdaQueryWrapper<BasShuttle>()
                        .eq(BasShuttle::getShuttleNo, device.getDeviceNo())
                        .eq(BasShuttle::getHostId, device.getHostId()));
                if (basShuttle == null) {
                    basShuttle = new BasShuttle();
                    //四向穿梭车号
                    basShuttle.setShuttleNo(Integer.valueOf(device.getDeviceNo()));
                    basShuttle.setStatus(1);
                    basShuttle.setDeleted(0);
                    basShuttle.setHostId(device.getHostId());
                    basShuttle.setDeviceId(device.getId().intValue());
                    shuttleService.save(basShuttle);
                }
                //任务号
                basShuttle.setTaskNo(shuttleProtocol.getTaskNo().intValue());
                //修改时间
                basShuttle.setUpdateTime(new Date());
                //设备状态
                basShuttle.setProtocol(JSON.toJSONString(shuttleProtocol));
                if (shuttleService.updateById(basShuttle)) {
                    OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getDeviceNo()));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -323,7 +388,6 @@
                Integer requestId = resultHeader.getInteger("requestId");
                if (requestType.equals("init")) {
                    Integer code = resultBody.getInteger("code");
                    OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向车复位上报 ===>> [code:{1}] [ip:{2}] [port:{3}]", code, device.getId(), device.getIp(), device.getPort()));
                    //小车复位请求
                    ShuttleCommand initCommand = getInitCommand(requestId, code);
                    //发出请求
@@ -331,6 +395,9 @@
                    JSONObject requestResult = requestCommand(httpCommand);
                    removeIdx = i;//此数据已经处理,从结果集中剔除
                    log.info(MessageFormat.format("【{0}】四向车复位上报 ===>> [code:{1}] [ip:{2}] [port:{3}]", device.getId(), code, device.getIp(), device.getPort()));
                    OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向车复位上报 ===>> [code:{1}] [ip:{2}] [port:{3}]", device.getId(), code, device.getIp(), device.getPort()));
                    break;
                }
            }