package net.vtstar.zhongtong.avi.mqtt.handle;

import com.alibaba.fastjson.JSONObject;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import net.vtstar.scada.base.mqtt.utils.MqttConstants;
import net.vtstar.utils.CollecUtils;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopStation;
import net.vtstar.zhongtong.avi.equipment.mapper.PaintshopStationMapper;
import net.vtstar.zhongtong.avi.global.constant.Constant;
import net.vtstar.zhongtong.avi.monitoring.domain.Skid;
import net.vtstar.zhongtong.avi.monitoring.domain.Vehicle;
import net.vtstar.zhongtong.avi.monitoring.domain.bo.MQTTMessageBO;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.Direction;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.ProductionType;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.StationState;
import net.vtstar.zhongtong.avi.monitoring.service.StationPassInfoService;
import net.vtstar.zhongtong.avi.utils.EquipDataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Order(value = 99)
@Component
public class RfidMessageHandler extends AbstractTesterMessageHandler {

    public static MQTTMessageBO messageBO = new MQTTMessageBO();
    public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd");
    public static List<String> rfidList1 = Arrays.asList("rfid51", "rfid52", "rfid53", "rfid54");
    public static List<String> rfidList2 = Arrays.asList("rfid71", "rfid72", "rfid73", "rfid74");
    //电泳换撬平移车
    public static List<String> rfidList3 = Arrays.asList("rfid52", "rfid53", "rfid54");
    public static List<String> stationList1 = Arrays.asList("HDG1-30", "HDG1-53", "HDG1-55", "HDG1-57", "HDG1-58", "HDG1-75");
    //4车道换撬车道上撬
    public static List<String> rfidList4 = Arrays.asList("rfid59", "rfid60", "rfid61", "rfid62", "rfid63", "rfid64");
    public static List<String> stationList2 = Arrays.asList("HDG1-70", "HDG1-74", "HDG1-79", "HDG5-8", "HDG5-9");

    @Resource(name = "redisTemplate")
    private ListOperations listOperations;

    @Resource(name = "redisTemplate")
    private ValueOperations valueOperations;

    @Resource(name = "laneStationCache")
    private Cache laneStationCache;
    @Resource(name = "stationCache")
    private Cache stationCache;
    @Resource(name = "vehicleCache")
    private Cache vehicleCache;
    @Resource(name = "webStationCache")
    private Cache webStationCache;
    @Resource(name = "laneRfidStationCache")
    private Cache laneRfidStationCache;

    @Autowired
    private StationPassInfoService passInfoService;
    @Autowired
    private PaintshopStationMapper stationMapper;
    @Resource(name = "redisTemplate")
    protected ValueOperations testValueOperations;

    public RfidMessageHandler() {
        super("translation", "data/all");
    }

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {

        Date date = new Date();
        Object payload = message.getPayload();
        JSONObject json = JSONObject.parseObject(payload.toString());

        //平移车扫到滑撬ID
        String id = json.getString("TID");
        if (StringUtil.isNullOrEmpty(id)) {
            id = json.getString("ID");
        }
        String uId = json.getString("UID");
        if (null != id && id.length() == 20) {
            uId = id;
            id = null;
        }
        //平移车扫描车道ID
        Integer state = json.getIntValue("State");
        if (StringUtil.isNullOrEmpty(id) && StringUtil.isNullOrEmpty(uId)) {
            return;
        }
        MessageHeaders headers = message.getHeaders();
        String vehicleCode = headers.get(MqttConstants.MSG_HEADER_KEY_EQUIPMENTNUMBER, String.class);
        Vehicle vehicle = (Vehicle) valueOperations.get(Constant.VEHICLE_PREFIX + vehicleCode);
        if (null == vehicle) {
            vehicle = vehicleCache.get(vehicleCode, Vehicle.class);
        }
        if (!StringUtil.isNullOrEmpty(id)) {
            if (id.length() == 30) {
                id = id.substring(0, 29);
            }
            //针对电泳处有两个读写头的情况, 将两个读写头的情况都合并到小端的Vehicle上进行处理;
            String otherCode = getOtherVehicleCode(vehicleCode);
            if (rfidList2.contains(vehicleCode)) {
                vehicle = (Vehicle) valueOperations.get(Constant.VEHICLE_PREFIX + otherCode);
                if (null == vehicle) {
                    vehicle = vehicleCache.get(otherCode, Vehicle.class);
                }
            }
            String today = dateFormat.format(date);
            //存rfid log日志
            messageBO.setID(id);
            messageBO.setState(state);
            String currentDate = format.format(date);
            messageBO.setCreateDate(currentDate);

//            log.info(vehicleCode + "______" + json.toJSONString() + " code：" + vehicleCode);

            if (id.startsWith("A61A")) {
                log.error("过滤掉乱发信息！：{},平移车:{}", id, vehicleCode);
                return;
            }

            Skid skid = (Skid) valueOperations.get(Constant.SKID_PREFIX + id);
            //平移车下车信息, 记录此时的下车时间
            if (state == 0) {
                //在rfid51,rfid52,rfid53,rfid54端上撬
                if (rfidList1.contains(vehicleCode)) {
                    if (null == vehicle.getMqttCode()) {
                        //若state=0时, 还没有绑定上撬侧编号, 则说明上撬逻辑有问题
                        log.error("平移车: {}, state=0时, 没有绑定上撬侧编号", vehicleCode);
                        return;
                    } else if (vehicleCode.equals(vehicle.getMqttCode())) {
                        //若为上撬侧读写头发出的state=0, 全部屏蔽掉
                        return;
                    }
                }
                if (rfidList2.contains(vehicleCode)) {
                    if (null == vehicle.getMqttCode()) {
                        //若state=0时, 还没有绑定上撬侧编号, 则说明上撬逻辑有问题
                        log.error("平移车: {}, state=0时, 没有绑定上撬侧编号", vehicleCode);
                        return;
                    } else if (vehicleCode.equals(vehicle.getMqttCode())) {
                        //若为上撬侧读写头发出的state=0, 全部屏蔽掉
                        return;
                    } else {
                        //若为另一侧读写头发出的state=0, 则认为是下车信号;
                        vehicleCode = otherCode;
                    }
                }
                if (null == skid) {
                    //因上车必定会绑定一次skid, 所以若skid为null, 则记录为异常情况
//                    log.error("----------平移车: {}下车, 但是未查询到滑撬信息, ID为: {}---------------", vehicleCode, id);
                    return;
                }
                vehicle.setState(false);
                vehicle.setCurrentRfid(id);
                vehicle.setSkid(skid);
                vehicle.setDownTime(date);
                vehicle.setDownTimeMin(0);
                valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                return;
            }
            if (state != 1) {
                log.error("mqtt接收到的state不为0也不为1!!!");
                return;
            }
            listOperations.rightPush("rfid:testLog:before:" + vehicleCode + ":" + today, messageBO);

            String rfid = vehicle.getCurrentRfid();
            //若当前平移车上绑定了RFID, 并且与当前mqtt信息中的ID一致, 并且state=1, 则认为这是读写头的重发现象
            if (null != rfid && id.equals(rfid)) {
                Date occurTime = vehicle.getOccurTime();
                if (null != occurTime) {
                    long l = (date.getTime() - occurTime.getTime()) / 1000;
                    if (l < 600) {
                        //log.error("{} 平移车发生重发现象 ,滑撬id {}", vehicleCode, id);
                        vehicle.setOccurTime(date);
                        if (rfidList2.contains(vehicleCode)) {
                            valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
                        } else {
                            valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                        }
                        return;
                    }
                }
            }
            vehicle.setState(true);
            vehicle.setOccurTime(date);
            vehicle.setDownTime(null);
            vehicle.setDownTimeMin(0);
            vehicle.setCurrentRfid(id);
            vehicle.setSkid(skid);
            if (rfidList2.contains(vehicleCode)) {
                valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
            } else {
                valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
            }
            listOperations.rightPush("rfid:testLog:after:" + vehicleCode + ":" + today, messageBO);
            //判断是否为返修
            Object reWorkVehicle = valueOperations.get(Constant.VEHICLE_PREFIX_REWORK);
            if (null != reWorkVehicle && !"".equals(reWorkVehicle.toString())) {
                if (vehicleCode.equals(reWorkVehicle.toString())) {
                    //记录返修上车的信息
                    listOperations.rightPush("rfid:log:fanxiu:" + vehicleCode, messageBO);
                    String busNo = (String) valueOperations.get(Constant.VEHICLE_PREFIX_REWORK_BUSNO);
                    if (null == skid) {
                        skid = new Skid();
                        skid.setRfid(id);
                    }
                    skid.setBusNo(busNo);
                    skid.setWorkOrderNo(null);
                    skid.setBusType(ProductionType.OTHER);
                    valueOperations.set(Constant.SKID_PREFIX + id, skid);
                    valueOperations.set(Constant.VEHICLE_PREFIX_REWORK, "");
                    valueOperations.set(Constant.VEHICLE_PREFIX_REWORK_BUSNO, "");
                    passInfoService.createPassInfo(skid.getWorkOrderNo(), skid.getBusNo(), skid.getRfid(), "返修上线", "");
                    //todo:将返修数据纳入涂装进车数量
                    String areaKey = Constant.BUS_SIZE_IN + "0:" + format;
                    saveRfidInfo(areaKey, messageBO);
                    return;
                }
            }
            //若是焊装车间进车，绑定滑撬与车身关系
            if ((vehicleCode.equals(Constant.HANZHUANG_VEHICLE1_RFID) || vehicleCode.equals(Constant.HANZHUANG_VEHICLE2_RFID))) {
                String keyW = EquipDataUtil.getTestValueKey(Constant.ROTARY_ROLLER_BED_W);
                testValueOperations.set(keyW, null == testValueOperations.get(keyW) ? 0 : ((int) testValueOperations.get(keyW)) + 1);

                String busNo = (String) valueOperations.get(Constant.HANZHUANG_VEHICLE_BUSNO_KEY + vehicleCode);
                String workOrderNo = (String) valueOperations.get(Constant.HANZHUANG_VEHICLE_WORKNO_KEY + vehicleCode);
                if (StringUtil.isNullOrEmpty(busNo)) {
                    log.error("未录入PDA车身号！ ：" + vehicleCode);
                    return;
                }
                if (null == skid) {
                    skid = new Skid();
                    skid.setRfid(id);
                }
                skid.setBusNo(busNo);
                skid.setWorkOrderNo(workOrderNo);
                skid.setBusType(ProductionType.OWN);
                valueOperations.set(Constant.SKID_PREFIX + id, skid);

                valueOperations.set(Constant.HANZHUANG_VEHICLE_BUSNO_KEY + vehicleCode, "");
                valueOperations.set(Constant.HANZHUANG_VEHICLE_WORKNO_KEY + vehicleCode, "");
                passInfoService.createPassInfo(skid.getWorkOrderNo(), skid.getBusNo(), skid.getRfid(),"涂装上线", "HXG1-1");
                return;
            }
            //底盘读写头
            if (vehicleCode.equals(Constant.TUZHUANG_VEHICLE4_RFID)) {
                String keyW = EquipDataUtil.getTestValueKey(Constant.ROTARY_ROLLER_BED_C);
                testValueOperations.set(keyW, null == testValueOperations.get(keyW) ? 0 : ((int) testValueOperations.get(keyW)) + 1);
            }
            //判断是否为轻客上车
            if (vehicleCode.equals(Constant.TUZHUANG_VEHICLE2_RFID)) {
                //判断此时rfid51上是否绑定了滑撬, 若已绑定, 则说明是从电泳方向上车, 若未绑定, 则说明是属于轻客上车
                if (null != vehicle && null == vehicle.getMqttCode()) {
                    if (null == skid) {
                        skid = new Skid();
                        skid.setRfid(id);
                    }
                    skid.setBusType(ProductionType.OTHER);
                    valueOperations.set(Constant.SKID_PREFIX + id, skid);
                    passInfoService.createPassInfo(skid.getWorkOrderNo(), skid.getBusNo(), skid.getRfid(),"轻客上线", "");
                    listOperations.rightPush("rfid:log:qingke:" + vehicleCode, messageBO);
                }
                //此时为在电泳一侧上车, 并且停到了第二个读写头的位置, 和其他两个读写头的平移车相同处理方式
            }
            //若为涂装末工位, 记录出涂装交车数量
            if (vehicleCode.equals(Constant.TUZHUANG_VEHICLE3_RFID)) {
                String keyW = EquipDataUtil.getTestValueKey(Constant.ROTARY_ROLLER_BED_P2);
                testValueOperations.set(keyW, null == testValueOperations.get(keyW) ? 0 : ((int) testValueOperations.get(keyW)) + 1);
                String areaKey = Constant.BUS_SIZE_OUT + "0:" + today;
                Integer size = (Integer) valueOperations.get(areaKey);
                if (null == size) {
                    size = 1;
                } else {
                    size++;
                }
                valueOperations.set(areaKey, size);
                saveRfidInfo(areaKey, messageBO);
                if (null != skid) {
                    passInfoService.createPassInfo(skid.getWorkOrderNo(), skid.getBusNo(), skid.getRfid(),"涂装下线", "HXG2-1");
                    //todo: 校验工单是否存在漏扫的工序
                    passInfoService.checkPassInfo(skid.getWorkOrderNo(), skid.getBusNo(), skid.getRfid());
                }
                listOperations.rightPush("rfid:log:chuche:" + today, messageBO);
                return;
            }
            //todo: 因PDA未使用, 暂不做此逻辑判断
            if (null == skid) {
//                log.error("查询到未在Redis中的滑撬信息！vehicleCode: {}, ID: {} ：", vehicleCode, id);
                //todo:
//                return;
                skid = new Skid();
                skid.setRfid(id);
                skid.setBusNo("");
                skid.setWorkOrderNo("");
                skid.setBusType(ProductionType.OWN);
                valueOperations.set(Constant.SKID_PREFIX + id, skid);
            }
            log.error("扫描到滑撬：" + skid.getRfid() + "读写头: " + vehicleCode);
            //处理是否为2车道换撬
            if (rfidList3.contains(vehicleCode) && null == vehicle.getMqttCode()) {
                //若mqttCode为null, 则说明为小端上撬
                List<PaintshopStation> stations = laneRfidStationCache.get(vehicle.getLaneRfid(), ArrayList.class);
                if (CollecUtils.isEmpty(stations)) {
                    return;
                }
                for (PaintshopStation station : stations) {
                    //只判断换撬区的工位
                    if (stationList1.contains(station.getCode())) {
                        List<PaintshopStation> temStation = laneStationCache.get(station.getLaneId(), ArrayList.class);
                        temStation.sort((s1, s2) -> s2.getSequence().compareTo(s1.getSequence()));
                        for (PaintshopStation item : temStation) {
                            PaintshopStation s = (PaintshopStation) valueOperations.get(Constant.STATION_PREFIX + item.getCode());
                            if (null == s.getSkid() && null != s.getWorkOrderNo()) {
                                skid.setWorkOrderNo(s.getWorkOrderNo());
                                skid.setBusNo(s.getBusNo());
                                skid.setBusType(s.getBusType());
                                valueOperations.set(Constant.SKID_PREFIX + id, skid);
                                //将工位上的工单信息绑定到滑撬上, 再将滑撬绑定到工位上
                                s.setSkid(skid);
                                s.setWorkOrderNo(null);
                                s.setBusNo(null);
                                valueOperations.set(Constant.STATION_PREFIX + item.getCode(), s);
                                break;
                            }
                        }
                    }
                }
            }
            //处理是否为4车道换撬
            if (rfidList4.contains(vehicleCode)) {
                List<PaintshopStation> stations = laneRfidStationCache.get(vehicle.getLaneRfid(), ArrayList.class);
                if (CollecUtils.isEmpty(stations)) {
                    return;
                }
                for (PaintshopStation station : stations) {
                    //TODO: 上线时东侧工位有影响
                    if (Direction.WEST.equals(station.getDirection()) && stationList2.contains(station.getCode())) {
                        List<PaintshopStation> temStation = laneStationCache.get(station.getLaneId(), ArrayList.class);
                        temStation.sort(Comparator.comparing(v -> v.getSequence()));
                        for (PaintshopStation item : temStation) {
                            PaintshopStation s = (PaintshopStation) valueOperations.get(Constant.STATION_PREFIX + item.getCode());
                            if (null == s.getSkid() && null != s.getWorkOrderNo()) {
                                skid.setWorkOrderNo(s.getWorkOrderNo());
                                skid.setBusNo(s.getBusNo());
                                skid.setBusType(s.getBusType());
                                valueOperations.set(Constant.SKID_PREFIX + id, skid);
                                //将工位上的工单信息绑定到滑撬上, 再将滑撬绑定到工位上
                                s.setSkid(skid);
                                s.setWorkOrderNo(null);
                                s.setBusNo(null);
                                valueOperations.set(Constant.STATION_PREFIX + item.getCode(), s);
                                break;
                            }
                        }
                    }
                }
            }
            //在rfid51,rfid52,rfid53,rfid54端上撬
            if (rfidList1.contains(vehicleCode)) {
                if (null == vehicle.getMqttCode()) {
                    if (null != vehicle.getTurnR() && vehicle.getTurnR()) {
                        //若在小端扫rfid, 但是此时平移车正在反转, 说明此时平移车正在下车, 且上车时未扫到rfid
                        if (null == skid) {
                            return;
                        }
                        log.error("----------平移车: {}下车信号, 漏读下车, 滑撬信息ID为: {}---------------", vehicleCode, id);
                        vehicle.setState(false);
                        vehicle.setCurrentRfid(id);
                        vehicle.setSkid(skid);
                        vehicle.setDownTime(date);
                        vehicle.setDownTimeMin(0);
                        valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                        return;
                    }
                    //若没有绑定平移车在哪侧上撬, 说明此时平移车刚刚在此侧上撬, 除了绑定上撬侧之外, 和正常上撬没有区别;
                    vehicle.setMqttCode(vehicleCode);
                    log.error("------------平移车在小端上撬, 平移车:{}---------", vehicleCode);
                } else if (vehicleCode.equals(vehicle.getMqttCode())) {
                    //因为已经过滤过重发现象, 说明此时平移车上撬已经过去了10秒, 此时再有state=1的情况, 说明在此侧上车且在此侧下车;
                    if (null == skid) {
                        //因上车必定会绑定一次skid, 所以若skid为null, 则记录为异常情况
                        log.error("----------平移车: {}上车, 但是未查询到滑撬信息, ID为: {}---------------", vehicleCode, id);
                        return;
                    }
                    log.error("----------平移车: {}下车信号, 同侧下车, 滑撬信息ID为: {}---------------", vehicleCode, id);
                    vehicle.setState(false);
                    vehicle.setCurrentRfid(id);
                    vehicle.setSkid(skid);
                    vehicle.setDownTime(date);
                    vehicle.setDownTimeMin(0);
                    valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                    return;
                } else {
                    //上撬侧不为空, 且上撬侧不为小端, 则说明是在另外一侧上的车, 此时只改变平移车的上车时间
                    vehicle.setOccurTime(date);
                    valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                    return;
                }
            }
            //在rfid71,rfid72,rfid73,rfid74端上撬
            if (rfidList2.contains(vehicleCode)) {
                if (null == vehicle.getMqttCode()) {
                    if (null != vehicle.getTurnF() && vehicle.getTurnF()) {
                        //若在大端扫rfid, 但是此时平移车正在正转, 说明此时平移车正在下车, 且上车时未扫到rfid
                        if (null == skid) {
                            return;
                        }
                        log.error("----------平移车: {}下车信号, 漏读下车, 滑撬信息ID为: {}---------------", vehicleCode, id);
                        vehicle.setState(false);
                        vehicle.setCurrentRfid(id);
                        vehicle.setSkid(skid);
                        vehicle.setDownTime(date);
                        vehicle.setDownTimeMin(0);
                        valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
                        return;
                    }
                    //首先判断当前小端代表的平移车是否绑定了上撬端, 若没有, 则说明是在大端上撬, 此时将大端code绑定到平移车上, 并记录上车时间等到小端代表平移车上;
                    vehicle.setMqttCode(vehicleCode);
                    vehicleCode = otherCode;
                } else if (vehicleCode.equals(vehicle.getMqttCode())) {
                    //此时小端平移车上已绑定了上撬端, 并且是在大端上撬, 那么此时state=1的情况, 则需要判断上撬时间是否大于10秒, 若不大于则为重发现象, 若大于则代表在大端侧进行下车;
                    if (null == skid) {
                        //因上车必定会绑定一次skid, 所以若skid为null, 则记录为异常情况
                        log.error("----------平移车: {}上车, 但是未查询到滑撬信息, ID为: {}---------------", vehicleCode, id);
                        return;
                    }
                    vehicle.setState(false);
                    vehicle.setCurrentRfid(id);
                    vehicle.setSkid(skid);
                    vehicle.setDownTime(date);
                    vehicle.setDownTimeMin(0);
                    valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
                    return;
                } else {
                    //此时小端平移车已经绑定了滑撬, 并且在小端上撬, 那么此时state=1的情况, 则只改变平移车的上车时间
                    vehicle.setOccurTime(date);
                    valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
                    return;
                }
            }

            //平移车上车信息
            listOperations.rightPush("rfid:log:" + vehicleCode, messageBO);

            //平移车上车
            vehicle.setState(true);
            vehicle.setOccurTime(date);
            vehicle.setDownTime(null);
            vehicle.setDownTimeMin(0);
            vehicle.setCurrentRfid(id);
            vehicle.setSkid(skid);

            //若为涂装首工位上车, 且为焊装刚刚过来的, 此时无法从工位列表中找到滑撬信息, 所以单独处理
            if (vehicleCode.equals(Constant.TUZHUANG_VEHICLE1_RFID) && Constant.TUZHUANG_LANE1_RFID.equals(vehicle.getLaneRfid())) {
                String format = dateFormat.format(date);
                String areaKey = Constant.BUS_SIZE_IN + "0:" + format;
                Integer size = (Integer) valueOperations.get(areaKey);
                if (null == size) {
                    size = 1;
                } else {
                    size++;
                }
                valueOperations.set(areaKey, size);
                saveRfidInfo(areaKey, messageBO);

                valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                String keyW = EquipDataUtil.getTestValueKey(Constant.ROTARY_ROLLER_BED_P1);
                testValueOperations.set(keyW, null == testValueOperations.get(keyW) ? 0 : ((int) testValueOperations.get(keyW)) + 1);
                return;
            }

            //根据平移车所在车道RFID编号查询车道两边的工位
            List<PaintshopStation> stations = laneRfidStationCache.get(vehicle.getLaneRfid(), ArrayList.class);
            if (CollecUtils.isEmpty(stations)) {
                return;
            }
            boolean isFind = false;
            //首先在平移车所在车道两边工位查询
            for (PaintshopStation value : stations) {
                List<PaintshopStation> lands = new ArrayList<>();
                List<PaintshopStation> temStation = laneStationCache.get(value.getLaneId(), ArrayList.class);
                for (PaintshopStation land : temStation) {
                    PaintshopStation s = (PaintshopStation) valueOperations.get(Constant.STATION_PREFIX + land.getCode());
                    lands.add(s);
                }
                for (PaintshopStation land : lands) {
                    if (land.getSkid() != null && id.equals(land.getSkid().getRfid())) {
                        passInfoService.endPassInfo(land);
                        isFind = true;
                        land.setSkid(null);
                        land.setState(StationState.FREE);
                    }
                }

                if (isFind) {
                    //记录过站数量
                    String areaCode = value.getAreaId().toString();
                    String areaKey = Constant.BUS_SIZE_OUT + areaCode + ":" + today;
                    Integer size = (Integer) valueOperations.get(areaKey);
                    if (null == size) {
                        size = 1;
                    } else {
                        size++;
                    }
                    valueOperations.set(areaKey, size);
                    saveRfidInfo(areaKey, messageBO);
                    for (PaintshopStation land : lands) {
                        valueOperations.set(Constant.STATION_PREFIX + land.getCode(), land);
                    }
                    valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                }
            }
            //若在平移车两侧未找到此滑撬, 则在所有工位中查找
            List<PaintshopStation> stationByCache = stationCache.get("ALL", ArrayList.class);
            if (CollecUtils.isEmpty(stationByCache)) {
                return;
            }
            if (!isFind){
                for (PaintshopStation station : stationByCache) {
                    PaintshopStation land = (PaintshopStation) valueOperations.get(Constant.STATION_PREFIX + station.getCode());
                    if (null != land && null != land.getSkid() && id.equals(land.getSkid().getRfid())) {
                        passInfoService.endPassInfo(land);
                        land.setSkid(null);
                        land.setState(StationState.FREE);
                        isFind = true;
                        valueOperations.set(Constant.STATION_PREFIX + land.getCode(), land);
                        valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
                        //记录过站数量
                        String areaCode = land.getAreaId().toString();
                        String areaKey = Constant.BUS_SIZE_OUT + areaCode + ":" + today;
                        Integer size = (Integer) valueOperations.get(areaKey);
                        if (null == size) {
                            size = 1;
                        } else {
                            size++;
                        }
                        valueOperations.set(areaKey, size);
                        saveRfidInfo(areaKey, messageBO);
                    }
                }
            }
            if (isFind) {
                log.error("----------------查询到滑撬: {}, 上车到平移车: {}-------------------", id, vehicleCode);
            } else {
                log.error("----------------未查询到滑撬: {}所在位置, 平移车为: {}--------------------------", id, vehicleCode);
            }
        } else {
            //记录平移车车道位置
            if (state == 1) {
                String rfidLand = String.valueOf(uId.substring(17).trim());
                vehicle.setLaneRfid(rfidLand);
                String otherCode = getOtherVehicleCode(vehicleCode);
                if (rfidList2.contains(vehicleCode)) {
                    vehicle = (Vehicle) valueOperations.get(Constant.VEHICLE_PREFIX + otherCode);
                    if (null == vehicle) {
                        vehicle = vehicleCache.get(otherCode, Vehicle.class);
                    }
                    vehicle.setLaneRfid(rfidLand);
                    valueOperations.set(Constant.VEHICLE_PREFIX + otherCode, vehicle);
                    return;
                }
                valueOperations.set(Constant.VEHICLE_PREFIX + vehicleCode, vehicle);
//                log.error("------平移车: {} 当前位于车道: {}", vehicleCode, rfidLand);
            }
        }
    }

    private String getOtherVehicleCode(String vehicleCode) {
        String otherCode = "01";
        switch (vehicleCode) {
            case "rfid51":
                otherCode = "rfid72";
                break;
            case "rfid52":
                otherCode = "rfid71";
                break;
            case "rfid53":
                otherCode = "rfid73";
                break;
            case "rfid54":
                otherCode = "rfid74";
                break;
            case "rfid72":
                otherCode = "rfid51";
                break;
            case "rfid71":
                otherCode = "rfid52";
                break;
            case "rfid73":
                otherCode = "rfid53";
                break;
            case "rfid74":
                otherCode = "rfid54";
                break;
        }
        return otherCode;
    }

    private void saveRfidInfo(String areaKey, MQTTMessageBO messageBO){
        listOperations.rightPush("rfid:" + areaKey, messageBO);
    }

}
