package com.zd.laboratory.service.impl;

import cn.hutool.core.util.StrUtil;
import com.zd.common.core.constant.CacheConstants;
import com.zd.common.core.domain.R;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.enums.HardwareOperate;
import com.zd.common.core.enums.HardwareTypeEnum;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.core.web.page.TableDataInfo;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.redis.service.RedisService;
import com.zd.common.security.utils.SaveUtil;
import com.zd.laboratory.config.HardwareFunctionStatusConfig;
import com.zd.laboratory.domain.LabHardware;
import com.zd.laboratory.domain.LabSubject;
import com.zd.laboratory.domain.LabSubjectHardwarePosition;
import com.zd.laboratory.domain.SubDiyVO;
import com.zd.laboratory.domain.vo.HxpSmartTerminalByExcel;
import com.zd.laboratory.domain.vo.LabCheckOptionStatisticsVo;
import com.zd.laboratory.domain.vo.LabHardwareVO;
import com.zd.laboratory.mapper.LabExitLightMapper;
import com.zd.laboratory.mapper.LabHardwareMapper;
import com.zd.laboratory.mapper.LabSparseHardwareMapper;
import com.zd.laboratory.mapper.LabSubjectHardwarePositionMapper;
import com.zd.laboratory.mqtt.entiy.EquipmentStatus;
import com.zd.laboratory.service.ILabHardwareService;
import com.zd.laboratory.socket.service.SocketService;
import com.zd.system.api.chemical.RemoteCabinetService;
import com.zd.system.api.domain.SubQueryConfig;
import com.zd.system.api.domain.SysFile;
import com.zd.system.api.laboratory.domain.Control;
import com.zd.system.api.laboratory.domain.FunctionStatus;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 硬件Service业务层处理
 *
 * @author zd
 * @date 2021-08-30
 */
@Service
public class LabHardwareServiceImpl implements ILabHardwareService {
    @Autowired
    private LabHardwareMapper labHardwareMapper;
    @Autowired
    private LabExitLightMapper labExitLightMapper;
    @Autowired
    private LabSparseHardwareMapper labSparseHardwareMapper;

    @Autowired
    private LabSubjectHardwarePositionMapper labSubjectHardwarePostionMapper;

    @Autowired
    public HardwareFunctionStatusConfig hardwareFunctionStatusConfig;
    @Autowired
    private SocketService socketService;

    @Autowired
    private RedisService redisService;

    @Autowired
    SubQueryManager subQueryManager;

    @Autowired
    private ILabHardwareService iLabHardwareService;

    @Autowired
    private RemoteCabinetService remoteCabinetService;

    /**
     * 查询硬件
     *
     * @param id 硬件主键
     * @return 硬件
     */
    @Override
    public LabHardwareVO selectLabHardwareById(Long id) {
        LabHardwareVO hardwareVO = labHardwareMapper.selectLabHardwareById(id);
            LabSubjectHardwarePosition position = new LabSubjectHardwarePosition();
            position.setHardId(hardwareVO.getId());
            List<LabSubjectHardwarePosition> hardwarePositionList = labSubjectHardwarePostionMapper.selectLabSubjectHardwarePositionList(position);
            hardwareVO.setSubjectHardPosiList(hardwarePositionList);
        return hardwareVO;
    }

    /**
     * 通过硬件编码获取实验id
     * @param num 硬件编码
     * @return
     */
    @Override
    public Long querySubIdByNum(String num)
    {

        if(StrUtil.isBlank(num))return null;

        LabHardware hardware = new LabHardware();
        hardware.setHardwareNum(num);
        List<LabHardwareVO> labHardwareVOS = labHardwareMapper.selectLabHardwareList(hardware);
        return Optional.ofNullable(labHardwareVOS)
                .filter(a->a.size()>0)
                .map(a->a.get(0).getSubjectId())
                .orElse(null);


    }

    /**
     * 查询硬件详细信息，包涵实验室下的所有硬件
     *
     * @param labHardware 硬件
     * @return 硬件
     */
    @Override
    public LabHardwareVO getHardwareDetail(LabHardware labHardware) {
        LabHardwareVO hardwareVO = labHardwareMapper.selectLabHardwareById(labHardware.getId());
        LabSubjectHardwarePosition position = new LabSubjectHardwarePosition();
        position.setLabSubjectId(labHardware.getSubjectId());
        List<LabSubjectHardwarePosition> hardwarePositionList = labSubjectHardwarePostionMapper.selectLabSubjectHardwarePositionList(position);
        List<LabSubjectHardwarePosition> newHardwarePositionList = new ArrayList<>();
        if (hardwareVO == null) {
            hardwareVO = new LabHardwareVO();
            hardwareVO.setId(labHardware.getId());
        }
        for (LabSubjectHardwarePosition posi : hardwarePositionList) {
            if (posi.getHardId().equals(hardwareVO.getId())) {
                newHardwarePositionList.add(posi);
            }
        }
        for (LabSubjectHardwarePosition posi : hardwarePositionList) {
            if (!posi.getHardId().equals(hardwareVO.getId())) {
                newHardwarePositionList.add(posi);
            }
        }
        hardwareVO.setSubjectHardPosiList(newHardwarePositionList);
        return hardwareVO;
    }

    /**
     * 查询硬件列表
     *
     * @param labHardware 硬件
     * @return 硬件
     */
    @Override
    @DataScope(deptAlias = "xx" , userAlias = "xx", permi = PerPrefix.LABORATORY_HARDWARE)
    public List<LabHardwareVO> selectLabHardwareList(LabHardware labHardware) {
        List<LabHardwareVO> list = labHardwareMapper.selectLabHardwareList(labHardware);

        /*Map<String, Object> map;
        for (LabHardwareVO labHardwareVO : list) {
            map = socketService.getRelayData(labHardwareVO.getRelayCode());
            if(map != null && labHardwareVO.getBit() != null){
                int status = Integer.parseInt(map.get("reverseBit").toString().substring(labHardwareVO.getBit() -1, labHardwareVO.getBit()));
                labHardwareVO.setStatus(status);
            }
        }*/
        for (LabHardwareVO labHardwareVO : list) {
            if(labHardwareVO.getHardwareType()==2){
                Integer code=redisService.getCacheObject(CacheConstants.RELAY_STATUS_KEY+labHardwareVO.getId());
                if(null!=code){
                    labHardwareVO.setStatus(code);
                }else{
                    if(labHardwareVO.getOperate() != null){
                        labHardwareVO.setStatus(labHardwareVO.getOperate().getCode());
                    }else {
                        labHardwareVO.setStatus(HardwareOperate.OFFLINE.getCode());
                    }
                }
            }else{
                if(labHardwareVO.getOperate() != null){
                    labHardwareVO.setStatus(labHardwareVO.getOperate().getCode());
                }else {
                    labHardwareVO.setStatus(HardwareOperate.OFFLINE.getCode());
                }
            }
        }
        return list;
    }

    /**
     * 新增硬件
     *
     * @param labHardware 硬件
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertLabHardware(LabHardware labHardware) {
        try {
            if(labHardware.getBit()==null)labHardware.setBit(-1);
            //初始化开关状态 (开关类型)
            if((HardwareTypeEnum.SWITCH.equals(labHardware.getType()) || (HardwareTypeEnum.AI_VENTILATION.equals(labHardware.getType()))&&StrUtil.isNotBlank(labHardware.getRelayCode())&&!labHardware.getBit().equals(Integer.parseInt("-1"))))
            {
                Map<Integer, Control.SwitchEnums> switchEnums = socketService.getSwitchEnums(labHardware.getRelayCode());
                if(switchEnums!=null)
                {
                    Control.SwitchEnums switchEnums1 = switchEnums.get(labHardware.getBit());
                    //这里直接更新状态，因为抛出去如果当前事务没结束，就查询不到该数据进行修改
                    HardwareOperate hardwareOperate = Control.SwitchEnums.ON.equals(switchEnums1)?HardwareOperate.OPEN:HardwareOperate.CLOSE;
                    labHardware.setOperate(hardwareOperate);
                }
            }
            //视频 目前每次推送事件都会修改，没有缓存，所以这里不用管

            //更新一体机
            if(HardwareTypeEnum.ONE_MACHINE.equals(labHardware.getType()) &&StrUtil.isNotBlank(labHardware.getHardwareNum()))
            {
                Object cacheObject = redisService.getCacheObject(CacheConstants.HEARTBEAT + labHardware.getHardwareNum());
                HardwareOperate hardwareOperate = cacheObject==null?HardwareOperate.OFFLINE:HardwareOperate.ONLINE;
                labHardware.setOperate(hardwareOperate);
            }

            SaveUtil.setCommonAttr(labHardware);
            if(labHardware.getOperate() == null){
                labHardware.setOperate(HardwareOperate.OFFLINE);
            }
            LabHardware labHardware2 = new LabHardware();
            labHardware2.setHardwareNum(labHardware.getHardwareNum());
            Predicate<List<LabHardwareVO>> p = x->x.size()>0;
            if(org.apache.commons.lang.StringUtils.isNotBlank(labHardware2.getHardwareNum())){
                if(p.test(labHardwareMapper.selectLabHardwareList(labHardware2))){
                    throw new ServiceException("设备编号重复，请重新输入。");
                }
            }
            int id;
            try{
                id = labHardwareMapper.insertLabHardware(labHardware);
            }catch (DuplicateKeyException e){
                throw new ServiceException("继电器编号位置重复，请重新输入。");
            }

            LabSubjectHardwarePosition hardwarePosition = labHardware.getHardwarePosition();
            if (null != hardwarePosition) {
                hardwarePosition.setLabSubjectId(labHardware.getSubjectId());
                hardwarePosition.setHardId(labHardware.getId());
                hardwarePosition.setHardName(labHardware.getName());
                hardwarePosition.setCreateTime(new Date());
                return labSubjectHardwarePostionMapper.insertLabSubjectHardwarePosition(hardwarePosition);
            }
            return id;
        }catch (DuplicateKeyException e){
            throw new ServiceException("该硬件绑定的传感器位置已被使用，请选择其他位置！");
        }

    }

    /**
     * 修改硬件
     *
     * @param labHardware 硬件
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateLabHardware(LabHardware labHardware) {
        int id=0;
        //类型不允许修改！！
        labHardware.setType(null);

        LabHardwareVO old = selectLabHardwareById(labHardware.getId());

        labHardware.setUpdateTime(DateUtils.getNowDate());
        //更新状态 (开关类型)
        if(HardwareTypeEnum.SWITCH.equals(old.getType()) || HardwareTypeEnum.AI_VENTILATION.equals(old.getType()))
        {
            //如果没有配置这两项则为离线
            if(StrUtil.isBlank(labHardware.getRelayCode())||labHardware.getBit()==null||labHardware.getBit().equals(Integer.parseInt("-1")))
            {
                labHardware.setOperate(HardwareOperate.OFFLINE);
            }else
            {
                //否则如果和之前配置不一样,一样则不管
                if(!labHardware.getRelayCode().equals(old.getRelayCode())||!labHardware.getBit().equals(old.getBit()))
                {
                    Map<Integer, Control.SwitchEnums> switchEnums = socketService.getSwitchEnums(labHardware.getRelayCode());
                    if(switchEnums!=null)
                    {
                        Control.SwitchEnums switchEnums1 = switchEnums.get(labHardware.getBit());
                        //这里直接更新状态，因为抛出去如果当前事务没结束，就查询不到该数据进行修改
                        HardwareOperate hardwareOperate = Control.SwitchEnums.ON.equals(switchEnums1)?HardwareOperate.OPEN:HardwareOperate.CLOSE;
                        labHardware.setOperate(hardwareOperate);
                    }else
                    {
                        labHardware.setOperate(HardwareOperate.OFFLINE);
                    }
                }
            }
        }
        //视频 目前每次推送事件都会修改，没有缓存，所以这里不用管

        //更新一体机
        else if(HardwareTypeEnum.ONE_MACHINE.equals(old.getType()) )
        {
            if(StrUtil.isBlank(labHardware.getHardwareNum()))
            {
                labHardware.setOperate(HardwareOperate.OFFLINE);

            }else if(!labHardware.getHardwareNum().equals(old.getHardwareNum()))
            {
                Object cacheObject = redisService.getCacheObject(CacheConstants.HEARTBEAT + labHardware.getHardwareNum());
                HardwareOperate hardwareOperate = cacheObject==null?HardwareOperate.OFFLINE:HardwareOperate.ONLINE;
                labHardware.setOperate(hardwareOperate);
            }
        }
        try {
            LabHardware labHardware2 = new LabHardware();
            labHardware2.setHardwareNum(labHardware.getHardwareNum());
            if(org.apache.commons.lang.StringUtils.isNotBlank(labHardware2.getHardwareNum())){
                List<LabHardwareVO> hardwareVOList = labHardwareMapper.selectLabHardwareList(labHardware2);
                Optional.ofNullable(hardwareVOList).orElseGet(Collections::emptyList).stream().filter(a->a.getId()!=labHardware.getId())
                        .forEach(a->{
                            throw new ServiceException("设备编号重复，请重新输入。");
                        });

            }
            try{
                id=labHardwareMapper.updateLabHardware(labHardware);
            }catch (DuplicateKeyException e){
                throw new ServiceException("继电器编号位置重复，请重新输入。");
            }
            //初始化开关状态 (开关类型)

            labSubjectHardwarePostionMapper.deleteLabSubjectHardwarePositionByHardId(labHardware.getId());
            LabSubjectHardwarePosition hardwarePosition = labHardware.getHardwarePosition();
            if (null != hardwarePosition) {
                hardwarePosition.setLabSubjectId(labHardware.getSubjectId());
                hardwarePosition.setHardId(labHardware.getId());
                hardwarePosition.setHardName(labHardware.getName());
                hardwarePosition.setCreateTime(new Date());
                return labSubjectHardwarePostionMapper.insertLabSubjectHardwarePosition(hardwarePosition);
            }
        }catch (DuplicateKeyException e){
            throw new ServiceException("该硬件绑定的传感器位置已被使用，绑定失败");
        }

        return id;
    }


    /**
     * 启/停用
     *
     * @param labHardware 硬件
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int startOrStop(LabHardware labHardware) {
        int id=0;
        //类型不允许修改！！
        labHardware.setType(null);

        LabHardwareVO old = selectLabHardwareById(labHardware.getId());

        labHardware.setUpdateTime(DateUtils.getNowDate());
        //更新状态 (开关类型)
        if(HardwareTypeEnum.SWITCH.equals(old.getType()) || HardwareTypeEnum.AI_VENTILATION.equals(old.getType()))
        {
            //如果没有配置这两项则为离线
            if(StrUtil.isBlank(labHardware.getRelayCode())||labHardware.getBit()==null||labHardware.getBit().equals(Integer.parseInt("-1")))
            {
                labHardware.setOperate(HardwareOperate.OFFLINE);
            }else
            {
                //否则如果和之前配置不一样,一样则不管
                if(!labHardware.getRelayCode().equals(old.getRelayCode())||!labHardware.getBit().equals(old.getBit()))
                {
                    Map<Integer, Control.SwitchEnums> switchEnums = socketService.getSwitchEnums(labHardware.getRelayCode());
                    if(switchEnums!=null)
                    {
                        Control.SwitchEnums switchEnums1 = switchEnums.get(labHardware.getBit());
                        //这里直接更新状态，因为抛出去如果当前事务没结束，就查询不到该数据进行修改
                        HardwareOperate hardwareOperate = Control.SwitchEnums.ON.equals(switchEnums1)?HardwareOperate.OPEN:HardwareOperate.CLOSE;
                        labHardware.setOperate(hardwareOperate);
                    }else
                    {
                        labHardware.setOperate(HardwareOperate.OFFLINE);
                    }
                }
            }
        }
        //视频 目前每次推送事件都会修改，没有缓存，所以这里不用管

        //更新一体机
        else if(HardwareTypeEnum.ONE_MACHINE.equals(old.getType()) )
        {
            if(StrUtil.isBlank(labHardware.getHardwareNum()))
            {
                labHardware.setOperate(HardwareOperate.OFFLINE);

            }else if(!labHardware.getHardwareNum().equals(old.getHardwareNum()))
            {
                Object cacheObject = redisService.getCacheObject(CacheConstants.HEARTBEAT + labHardware.getHardwareNum());
                HardwareOperate hardwareOperate = cacheObject==null?HardwareOperate.OFFLINE:HardwareOperate.ONLINE;
                labHardware.setOperate(hardwareOperate);
            }
        }
        try {

            try{
                id=labHardwareMapper.updateLabHardware(labHardware);
            }catch (DuplicateKeyException e){
                throw new ServiceException("继电器编号位置重复，请重新输入。");
            }
            //初始化开关状态 (开关类型)

            labSubjectHardwarePostionMapper.deleteLabSubjectHardwarePositionByHardId(labHardware.getId());
            LabSubjectHardwarePosition hardwarePosition = labHardware.getHardwarePosition();
            if (null != hardwarePosition) {
                hardwarePosition.setLabSubjectId(labHardware.getSubjectId());
                hardwarePosition.setHardId(labHardware.getId());
                hardwarePosition.setHardName(labHardware.getName());
                hardwarePosition.setCreateTime(new Date());
                return labSubjectHardwarePostionMapper.insertLabSubjectHardwarePosition(hardwarePosition);
            }
        }catch (DuplicateKeyException e){
            throw new ServiceException("该硬件绑定的传感器位置已被使用，绑定失败");
        }

        return id;
    }

    /**
     * 设置柜锁时间
     *
     * @param labHardwareVO 需要设置柜锁时间主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int setLock(LabHardwareVO labHardwareVO) {
        int flag = labHardwareMapper.setLock(labHardwareVO);
        return flag;
    }

    /**
     * 批量删除硬件
     *
     * @param ids 需要删除的硬件主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteLabHardwareByIds(Long[] ids) {
        labSubjectHardwarePostionMapper.deleteLabSubjectHardwarePositionByHardId(ids[0]);
        int flag = labHardwareMapper.deleteLabHardwareByIds(ids);
        return flag;
    }

    /**
     * 删除硬件信息
     *
     * @param id 硬件主键
     * @return 结果
     */
    @Override
    public int deleteLabHardwareById(Long id) {
        return labHardwareMapper.deleteLabHardwareById(id);
    }


    /**
     * 查询硬件功能列表
     *
     * @return 硬件
     */
    @Override
    public Map <HardwareTypeEnum, List<FunctionStatus>> getFunList() {
        return hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
    }

    /**
     * 更新继电器状态
     * 现在更新起来很麻烦， 需要通过继电器找到继电器下的设备，修改所有关联设备的状态
     */
    @Override
    public int updateRelayStatus(EquipmentStatus equipmentStatus)
    {
        //todo  现在更新起来很麻烦， 需要通过继电器找到继电器下的设备，修改所有关联设备的状态,
        //todo  建议 维护继电器数据，关联继电器硬件数据直接取继电器状态

        if(HardwareOperate.OFFLINE.equals(equipmentStatus.getHardwareOperate()))
        {
            //如果是下线
            LabHardware labHardware = new LabHardware();
            labHardware.setOperate(equipmentStatus.getHardwareOperate());
            labHardware.setRelayCode(equipmentStatus.getNum());
            int count = labHardwareMapper.updateLabHardwareRelayCodeStatus(labHardware);

            // 疏散指示灯状态更新
            if(count == 0){
                labExitLightMapper.updateStatus(labHardware);
            }

            return count;
        }
        else
        {
            //如果是上线
            LabHardware labHardware = new LabHardware();
            labHardware.setRelayCode(equipmentStatus.getNum());
            Map<Integer, Control.SwitchEnums> switchEnums = socketService.getSwitchEnums(equipmentStatus.getNum());
            if(switchEnums!=null)
            {
                switchEnums.forEach((k,v)->{
                    labHardware.setOperate(v==Control.SwitchEnums.ON?HardwareOperate.OPEN:HardwareOperate.CLOSE);
                    labHardware.setBit(k);
                    if(labHardwareMapper.updateLabHardwareRelayCodeStatus(labHardware) == 0){
                        // 疏散指示灯状态更新
                        labExitLightMapper.updateStatus(labHardware);
                    }
                });
                return 1;

            }
            return 0;
        }


    }
    /**
     * 更新视频状态
     *
     * @param equipmentStatus
     */
    @Override
    public int updateStatus(EquipmentStatus equipmentStatus) {
        LabHardware labHardware = new LabHardware();
        labHardware.setOperate(equipmentStatus.getHardwareOperate());
        labHardware.setHardwareNum(equipmentStatus.getNum());
        int count = labHardwareMapper.updateLabHardwareStatus(labHardware);
        if(count == 0){
            // 更新疏散硬件状态- 喇叭 摄像头
            labSparseHardwareMapper.updateStatus(labHardware);
        }
        return count;
    }

    /****
     * 根据设备类型查询
     * @param labHardwareVO
     * @return
     */
    @Override
    public List<LabHardware> selectNewLabHardwareByTypes(LabHardwareVO labHardwareVO) {
        return labHardwareMapper.selectNewLabHardwareByTypes(labHardwareVO);
    }

    @Override
    @DataScope(deptAlias = "s", userAlias = "h", permi = PerPrefix.LABORATORY_HARDWARE)
    public Map<String, Object> selectStatistics(LabHardware labHardware) {
        List<Map<String, Object>> data = labHardwareMapper.selectStatistics(labHardware);

        Map<String, Object> map = new HashMap<>();
        int videoOnline = 0, videoOffline = 0,
            powerSupplyOnline = 0, powerSupplyOffline = 0, powerSupplyPowerUps = 0,
            ventilationOnline = 0, ventilationOffline = 0, ventilationPowerUps = 0,
            smartMachineOnline = 0, smartMachineOffline = 0;
        if(CollectionUtils.isNotEmpty(data)){
            for (Map<String, Object> datum : data) {
                int type = (int) datum.get("type");
                int operate = Optional.ofNullable((Integer)datum.get("operate")).orElse(0);
                int count = Integer.parseInt(datum.get("count") + "");
                if(type == 4){
                    switch (operate){
                        case 0:
                            videoOffline = count;
                            break;
                        case 2:
                            videoOnline = count;
                            break;
                    }
                }else if(type == 1){
                    switch (operate){
                        case 0:
                            powerSupplyOffline = count;
                            break;
                        case 3:
                            powerSupplyOnline = count;
                            break;
                        case 4:
                            powerSupplyPowerUps = count;
                            break;
                    }
                }else if(type == 2){
                    switch (operate){
                        case 0:
                            ventilationOffline = count;
                            break;
                        case 3:
                            ventilationOnline = count;
                            break;
                        case 4:
                            ventilationPowerUps = count;
                            break;
                    }
                }else if(type == 0){
                    switch (operate){
                        case 0:
                            smartMachineOffline = count;
                            break;
                        case 2:
                            smartMachineOnline = count;
                            break;
                    }
                }
            }
        }
        // 视频监控
        map.put("videoOnline", videoOnline);
        map.put("videoOffline", videoOffline);

        // 电源控制
        map.put("powerSupplyOnline", powerSupplyOnline);
        map.put("powerSupplyOffline", powerSupplyOffline);
        map.put("powerSupplyPowerUps", powerSupplyPowerUps);

        // 智能通风
        map.put("ventilationOnline", ventilationOnline);
        map.put("ventilationOffline", ventilationOffline);
        map.put("ventilationPowerUps", ventilationPowerUps);

        // 智能一体机
        map.put("smartMachineOnline", smartMachineOnline);
        map.put("smartMachineOffline", smartMachineOffline);
        return map;
    }

    @Override
    public List <HxpSmartTerminalByExcel> importSmartTerminal(List <HxpSmartTerminalByExcel> smartTerminalList, String operName, HxpSmartTerminalByExcel hxpSmartTerminalByExcel) {
        if (StringUtils.isNull(smartTerminalList) || smartTerminalList.size() == 0) {
            throw new ServiceException("导入智能设备数据不能为空！");
        }
        List<HxpSmartTerminalByExcel> failSmartTerminalList = new ArrayList <>();
        for (HxpSmartTerminalByExcel smartTerminal : smartTerminalList) {
            //流水线验证
            flowLineCheck(smartTerminal,failSmartTerminalList, hxpSmartTerminalByExcel);
        }
        return failSmartTerminalList;
    }

    private void flowLineCheck(HxpSmartTerminalByExcel smartTerminal, List<HxpSmartTerminalByExcel> failSmartTerminalList, HxpSmartTerminalByExcel hxpSmartTerminalByExcel){
        // 校验是否装入错误数据
        boolean checkBox = true;

        LabHardware labHardware = new LabHardware();
        //验证设备编号不能为空
        if(StringUtils.isEmpty(smartTerminal.getTerminalNum())){
            if(checkBox){
                smartTerminal.getFailRemark().append("失败：");
                failSmartTerminalList.add(smartTerminal);
                checkBox = false;
            }
            smartTerminal.getFailRemark().append("设备编号不能为空、");
        }else{
            labHardware.setHardwareNum(smartTerminal.getTerminalNum());
            List<LabHardware> list = labHardwareMapper.selectLabHardwareStatusByRelay(labHardware);
            if(list.size()>0){
                if(checkBox){
                    smartTerminal.getFailRemark().append("失败：");
                    failSmartTerminalList.add(smartTerminal);
                    checkBox = false;
                }
                smartTerminal.getFailRemark().append("设备编号重复、");
            }
            if(smartTerminal.getTerminalNum().indexOf(" ")!=-1){
                if(checkBox){
                    smartTerminal.getFailRemark().append("失败：");
                    failSmartTerminalList.add(smartTerminal);
                    checkBox = false;
                }
                smartTerminal.getFailRemark().append("设备编号格式错误、");
            }
            if(!isLetterDigit(smartTerminal.getTerminalNum())){
                if(checkBox){
                    smartTerminal.getFailRemark().append("失败：");
                    failSmartTerminalList.add(smartTerminal);
                    checkBox = false;
                }
                smartTerminal.getFailRemark().append("设备编号只能是数字和字母、");
            }
            if(smartTerminal.getTerminalNum().length()>20){
                if(checkBox){
                    smartTerminal.getFailRemark().append("失败：");
                    failSmartTerminalList.add(smartTerminal);
                    checkBox = false;
                }
                smartTerminal.getFailRemark().append("设备编号超过二十个字符、");
            }
        }

        //实验室不能为空
        if(StringUtils.isEmpty(smartTerminal.getSubName())){
            if(checkBox){
                smartTerminal.getFailRemark().append("失败：");
                failSmartTerminalList.add(smartTerminal);
                checkBox = false;
            }
            smartTerminal.getFailRemark().append("实验室不能为空、");
        }else{
            List<SubDiyVO>  subList = subQueryManager.querySubs(new LabSubject(), SubQueryConfig.subQueryConfigList);
            for(int i=0;i<subList.size();i++){
                SubDiyVO hashMap = subList.get(i);
                if(hashMap.getName().equals(smartTerminal.getSubName())){
                    labHardware.setSubjectId(hashMap.getId());
                }
            }
            if(StringUtils.isNull(labHardware.getSubjectId())){
                if(checkBox){
                    smartTerminal.getFailRemark().append("失败：");
                    failSmartTerminalList.add(smartTerminal);
                    checkBox = false;
                }
                smartTerminal.getFailRemark().append("实验室不存在、");
            }
        }

        if(StringUtils.isNotEmpty(smartTerminal.getFailRemark())){
            smartTerminal.getFailRemark().deleteCharAt(smartTerminal.getFailRemark().length()-1);
        }

        if(StringUtils.isEmpty(smartTerminal.getFailRemark())){
            labHardware.setType(hxpSmartTerminalByExcel.getTerminalType());
            iLabHardwareService.insertLabHardware(labHardware);
        }

    }

    public static boolean isLetterDigit(String str) {
        String regex = "^[a-z0-9A-Z]+$";
        return str.matches(regex);
    }



    /**
     * 查询硬件列表
     *
     * @param labHardware 硬件
     * @return 硬件
     */
    @Override
    @DataScope(deptAlias = "xx" , userAlias = "xx", permi = PerPrefix.LABORATORY_HARDWARE)
    public List<LabHardwareVO> getCabinetLockList(LabHardware labHardware) {
        List<LabHardwareVO> list = labHardwareMapper.selectLabHardwareList(labHardware);
        List <LabHardwareVO> collect = Optional.ofNullable(list).orElseGet(Collections::emptyList).parallelStream().map(a -> {
            Map<String,Long> subMap = new HashMap<>();
            subMap.put("subId",a.getSubjectId());
            R<List <LinkedHashMap<String,String>>> cabinetList = remoteCabinetService.getCabinetList(subMap);
            if(StringUtils.isNotNull(cabinetList.getData()) && cabinetList.getData().size()>0){
                a.getCabinetList().addAll(cabinetList.getData());
            }
            return a;
        }).sorted(Comparator.comparing(LabHardwareVO::getCreateTime).reversed()).collect(Collectors.toList());
        return collect;
    }


    /**
     * 关联的机柜id
     *
     * @param LabHardware 需要关联的机柜id
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int setLockJoinCabinet(List<LabHardware> LabHardware) {
        Optional.ofNullable(LabHardware).orElseGet(Collections::emptyList).parallelStream()
                .forEach(a->{
                    Predicate <Long> predicate = b->b!=null;
                    if(predicate.test(a.getJoinCabinet())){
                        a.setJoinCabinetTime(new Date());
                    }
                    labHardwareMapper.setLockJoinCabinet(a);
                });
        return 1;
    }

    @Override
    @DataScope(deptAlias = "xx" , userAlias = "xx", permi = PerPrefix.LABORATORY_HARDWARE)
    public List <LabHardwareVO> selectLabHardwareByCabinetList(LabHardware labHardware) {
        List<LabHardwareVO> list = labHardwareMapper.selectLabHardwareByCabinetList(labHardware);
        return list;
    }
}
