package org.nl.acs.device.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.ListOrderedMap;
import org.nl.acs.auto.initial.ApplicationAutoInitial;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.acs.device.device_driver.standard_inspect.ItemDto;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.domain.DeviceExtra;
import org.nl.acs.device.domain.DeviceRunpoint;
import org.nl.acs.device.service.DeviceDriverDefinationAppService;
import org.nl.acs.device.service.DeviceExtraService;
import org.nl.acs.device.service.DeviceService;
import org.nl.acs.device.service.dto.DeviceDto;
import org.nl.acs.device.service.dto.DeviceQueryParam;
import org.nl.acs.device.service.dto.DeviceRunpointDto;
import org.nl.acs.device.service.mapper.DeviceExtraMapper;
import org.nl.acs.device.service.mapper.DeviceMapper;
import org.nl.acs.device.service.mapper.DeviceRunpointMapper;
import org.nl.acs.device_driver.DeviceDriverDefination;
import org.nl.acs.device_driver.ScannerDeviceDriver;
import org.nl.acs.device_driver.basedriver.oven_manipulator.OvenGantryManipulatorDeviceDriver;
import org.nl.acs.device_driver.basedriver.siemens_conveyor.SiemensConveyorDeviceDriver;
import org.nl.acs.device_driver.basedriver.siemens_conveyor_ckk.SiemensConveyorCkkDeviceDriver;
import org.nl.acs.device_driver.basedriver.siemens_conveyor_labeling.SiemensConveyorLabelingDeviceDriver;
import org.nl.acs.device_driver.basedriver.slit_two_manipulator.SlitTwoManipulatorDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_conveyor_control_with_scanner.StandardCoveyorControlWithScannerDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_inspect_site.StandardInspectSiteDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_ordinary_site.StandardOrdinarySiteDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_scanner.StandardScannerDeviceDriver;
import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.opc.service.OpcService;
import org.nl.acs.opc.service.dto.OpcDto;
import org.nl.acs.opc.service.dto.OpcPlcDto;
import org.nl.acs.plc.service.OpcPlcService;
import org.nl.acs.route.domain.RouteLine;
import org.nl.acs.route.service.mapper.RouteLineMapper;
import org.nl.acs.storage_cell.domain.StorageCell;
import org.nl.acs.storage_cell.service.dto.StorageCellDto;
import org.nl.acs.storage_cell.service.mapper.StorageCellMapper;
import org.nl.acs.utils.ConvertUtil;
import org.nl.acs.utils.ExportCSVUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.acs.utils.ReadUtil;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.FileUtil;
import org.nl.common.utils.RedisUtils;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.SpringContextHolder;
import org.nl.system.service.logicflow.dao.mapper.StageMapper;
import org.nl.system.service.param.ISysParamService;
import org.openscada.opc.lib.da.Server;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author jiaolm
 * @date 2023-05-09
 */
@Service
@AllArgsConstructor
@Slf4j
// @CacheConfig(cacheNames = DeviceService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeviceServiceImpl extends CommonServiceImpl<DeviceMapper, Device> implements DeviceService, ApplicationAutoInitial {

    // private final RedisUtils redisUtils;
    private final DeviceMapper deviceMapper;
    private final RouteLineMapper routeLineMapper;
    //    private final StageActorMapper stageActorMapper;
    private final StorageCellMapper storageCellMapper;
    private final DeviceExtraMapper deviceExtraMapper;
    private final DeviceRunpointMapper deviceRunpointMapper;

    private final StageMapper stageMapper;
    private final DeviceExtraService deviceExtraService;
    private final OpcService opcService;
    private final RedisUtils redisUtils;
    private final OpcPlcService opcPlcService;
    private final DeviceDriverDefinationAppService deviceDriverDefinationAppService;
    private final DeviceAppService deviceAppService;
    private final ISysParamService paramService;
    List<StorageCellDto> storageCells = new ArrayList<>();

    @Override
    public PageInfo<DeviceDto> queryAll(DeviceQueryParam query, Pageable pageable) {
        IPage<Device> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<Device> page = deviceMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, DeviceDto.class);
    }

    @Override
    public List<DeviceDto> queryAll(DeviceQueryParam query) {
        return ConvertUtil.convertList(deviceMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), DeviceDto.class);
    }

    @Override
    public Device getById(String id) {
        return deviceMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public DeviceDto findById(String id) {
        return ConvertUtil.convert(getById(id), DeviceDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DeviceDto resources) {
        Device entity = ConvertUtil.convert(resources, Device.class);
        return deviceMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(DeviceDto resources) {
        Device entity = ConvertUtil.convert(resources, Device.class);
        int ret = deviceMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids) {
        // delCaches(ids);
        return deviceMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id) {
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(String id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<String> ids) {
        for (String id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<DeviceDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (DeviceDto device : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("设备编码", device.getDeviceCode());
              map.put("设备名字", device.getDeviceName());
              map.put("设备类型", device.getDeviceType());
              map.put("所属区域", device.getRegion());
              map.put("生产厂家", device.getManufacturer());
              map.put("生产厂家电话", device.getManufacturerPhone());
              map.put("是否配置", device.getIsConfig());
              map.put("opcServer标识", device.getOpcServerId());
              map.put("opcPlc标识", device.getOpcPlcId());
              map.put("是否为路由设备", device.getIsRoute());
              map.put("设备驱动类型", device.getDriverCode());
              map.put("备注", device.getRemark());
              map.put("是否启用", device.getIsActive());
              map.put("顺序号", device.getSeqNum());
              map.put("是否删除", device.getIsDelete());
              map.put("创建者", device.getCreateBy());
              map.put("创建时间", device.getCreateTime());
              map.put("修改者", device.getUpdateBy());
              map.put("修改时间", device.getUpdateTime());
              map.put("地址号", device.getAddress());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/

    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        IPage<Device> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank((String) whereJson.get("device_type")), Device::getDevice_type, whereJson.get("device_type"));
        wrapper.nested(StringUtils.isNotBlank((String) whereJson.get("blurry")), i -> i.like(Device::getDevice_code, whereJson.get("blurry")).or().like(Device::getDevice_name, whereJson.get("blurry")));
        wrapper.orderByAsc(Device::getIs_config).orderByDesc(Device::getSeq_num).orderByDesc(Device::getUpdate_time);
        IPage<Device> devicePage = deviceMapper.queryPage(queryPage, wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(devicePage, Device.class));
        return json;
    }

    @Override
    public Map<String, Object> queryDeviceProtocol(Map whereJson, Pageable page) {
        IPage<DeviceExtra> queryPage = PageUtil.toMybatisPage(page);
        QueryWrapper<DeviceExtra> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank((String) whereJson.get("device_types")), "d.device_type", whereJson.get("device_types"));
        wrapper.nested(StringUtils.isNotBlank((String) whereJson.get("blurry")), i -> i.like("d.device_code", whereJson.get("blurry")).or().like("d.device_name", whereJson.get("blurry")));
        wrapper.eq(StringUtils.isNotBlank((String) whereJson.get("opc_id")), "d.opc_server_id", whereJson.get("opc_id"));
        wrapper.eq("d.is_delete", "0");
        wrapper.ne("e.filed_type", "01");
        IPage<DeviceExtra> devicePage = deviceExtraMapper.queryDeviceProtocolPage(queryPage, wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(devicePage, DeviceExtra.class));
        return json;
    }

    @Override
    public JSONArray queryDeviceProtocol(Map whereJson) {
        QueryWrapper<DeviceExtra> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank((String) whereJson.get("device_types")), "d.device_type", whereJson.get("device_types"));
        wrapper.nested(StringUtils.isNotBlank((String) whereJson.get("blurry")), i -> i.like("d.device_code", whereJson.get("blurry")).or().like("d.device_name", whereJson.get("blurry")));
        wrapper.eq(StringUtils.isNotBlank((String) whereJson.get("opc_id")), "d.opc_server_id", whereJson.get("opc_id"));
        wrapper.eq("d.is_delete", "0");
        wrapper.ne("e.filed_type", "01");
        List<DeviceExtra> deviceProtocolList = deviceExtraMapper.selectDeviceProtocolList(wrapper);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(deviceProtocolList));
        return jsonArray;
    }


    @Override
    public List<DeviceDto> queryAll(Map whereJson) {
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).list();
        return ConvertUtil.convertList(deviceList, DeviceDto.class);
    }

//    @Override
//    public DeviceDto findById(String device_id) {
//        WQLObject wo = WQLObject.getWQLObject("acs_device");
//        JSONObject json = wo.query("device_id ='" + device_id + "'").uniqueResult(0);
//        final DeviceDto obj = json.toJavaObject(DeviceDto.class);
//        return obj;
//    }

    @Override
    public DeviceDto findByCode(String code) {
        Device device = new LambdaQueryChainWrapper<>(deviceMapper).eq(Device::getDevice_code, code).one();
        return ConvertUtil.convert(device, DeviceDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(DeviceDto dto) {
        String device_code = dto.getDevice_code();
        DeviceDto deviceDto = this.findByCode(device_code);
        if (deviceDto != null && deviceDto.getIs_delete().equals("0")) {
            throw new BadRequestException("存在相同的设备编码");
        }

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();

        dto.setDevice_id(IdUtil.simpleUUID());
        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);

        Device entity = ConvertUtil.convert(dto, Device.class);
        deviceMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DeviceDto dto) {
        DeviceDto entity = this.findById(dto.getDevice_id());
        if (entity == null) {
            throw new BadRequestException("被删除或无权限，操作失败!");
        }

        String device_code = dto.getDevice_code();
        DeviceDto deviceDto = this.findByCode(device_code);
        if (deviceDto != null && deviceDto.getIs_delete().equals("0") && !deviceDto.getDevice_id().equals(dto.getDevice_id())) {
            throw new BadRequestException("存在相同的设备编码");
        }

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setUpdate_time(now);
        dto.setUpdate_by(currentUsername);

        Device device = ConvertUtil.convert(dto, Device.class);
        deviceMapper.updateById(device);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) {
//        WQLObject wo = WQLObject.getWQLObject("acs_device");
//        WQLObject storageTab = WQLObject.getWQLObject("acs_storage_cell");
//        //路由路线表【acs_route_line】
//        WQLObject routeLineTab = WQLObject.getWQLObject("acs_route_line");
//        //路由路线表【stage_actor】
//        WQLObject stageActorTab = WQLObject.getWQLObject("stage_actor");
        for (String device_id : ids) {
//            JSONObject deviceJson = wo.query("device_id = '" + device_id + "'").uniqueResult(0);
            Device deviceJson = new LambdaQueryChainWrapper<>(deviceMapper).eq(Device::getDevice_id, device_id).one();
            if (deviceJson == null) {
                continue;
            }
            String device_code = deviceJson.getDevice_code();
            log.debug("删除设备时候判断路由是否存在，如果存在，则不允许删除设备!");
//            JSONObject json = routeLineTab.query("device_code = '" + device_code + "' or next_device_code = '" + device_code + "'").uniqueResult(0);
            RouteLine json = new LambdaQueryChainWrapper<>(routeLineMapper).eq(RouteLine::getDevice_code, device_code).or().eq(RouteLine::getNext_device_code, device_code).one();
            if (json != null) {
                throw new BadRequestException("设备：【" + device_code + "】在路由已存在，无法删除!");
            }
            log.debug("删除舞台里面的设备!");
//            Map<String, String> map = new HashMap<>();
//            map.put("device_id", "");
//            map.put("device_code", "");
//            map.put("device_name", "");
//            stageActorTab.update(map, "device_code = '" + device_code + "'");
//            stageActorMapper.lambdaUpdate().eq(StageActor::getDevice_code,device_code)
//                    .set(StageActor::getDevice_code,"")
//                    .set(StageActor::getDevice_name,"")
//                    .update();
            log.debug("根据设备编码查询在缓存里面的舞台数据,并删除掉!");
//            JSONArray jsonArr = WQL.getWO("QStage_01").addParam("flag", "1").addParam("device_code", device_code).process().getResultJSONArray(0);

//            List<Stage> stageList = stageMapper.selectByDeviceCode(device_code);
//            for (int i = 0; i < stageList.size(); i++) {
//                String stage_code = stageList.get(i).getStage_code();
//                redisUtils.del("stage:mst:" + stage_code);
//                redisUtils.del("stage:dtl:" + stage_code);
//            }
            log.debug("删除缓存里面的设备！");
            Device deviceByCode = deviceAppService.findDeviceByCode(device_code);
            List<Device> allDevice = deviceAppService.findAllDevice();
            Iterator<Device> iterator = allDevice.iterator();
            while (iterator.hasNext()) {
                Device device = iterator.next();
                if (StrUtil.equals(device.getDevice_code(), device_code)) {
                    iterator.remove();
                }
            }


//            allDevice.remove(deviceByCode);

            log.info("设备删除成功!");
            if (deviceByCode != null) {
                if (StrUtil.equals("storage", deviceByCode.getDeviceDriverDefination().getFitDeviceTypes().get(0).name())) {
//                    storageTab.delete("substring_index( storage_code,'-',1)= '" + device_code + "'");
                    storageCellMapper.deleteByStorageCode(device_code);
                } else {
//                    JSONObject data = storageTab.query("storage_code ='" + device_code + "'").uniqueResult(0);
                    StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code, device_code).one();
                    if (storageCell != null) {
//                        storageTab.delete("storage_code = '" + device_code + "'");
                        Map<String, Object> map = new HashMap<>();
                        map.put("storage_code", device_code);
                        storageCellMapper.deleteByMap(map);
                    }
                }
            }
//            wo.delete("device_id = '" + device_id + "'");
            Map<String, Object> map = new HashMap<>();
            map.put("device_id", device_id);
            deviceMapper.deleteByMap(map);
        }
    }

    @Override
    public void download(List<DeviceDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (DeviceDto device : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("生产厂家", device.getManufacturer());
            map.put("厂家电话", device.getManufacturer_phone());
            map.put("opcServer标识", device.getOpc_server_id());
            map.put("opcPlc标识", device.getOpc_plc_id());
            map.put("是否启用", device.getIs_active());
            map.put("是否删除", device.getIs_delete());
            map.put("创建者", device.getCreate_by());
            map.put("创建时间", device.getCreate_time());
            map.put("修改者", device.getUpdate_by());
            map.put("修改时间", device.getUpdate_time());
            map.put("设备编码", device.getDevice_code());
            map.put("设备名字", device.getDevice_name());
            map.put("设备类型", device.getDevice_type());
            map.put("是否配置", device.getIs_config());
            map.put("备注", device.getRemark());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void downDeviceDBload(JSONArray jsonarr, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();

        for (int i = 0; i < jsonarr.size(); i++) {
            JSONObject jo = jsonarr.getJSONObject(i);
            Map<String, Object> map = new LinkedHashMap<>();
            System.out.println(jo.getString("extra_code"));
            String extra_code = jo.getString("extra_code");
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            map.put("Tag Name", extra_code);
            map.put("Address", jo.get("extra_name"));
            String datatype = jo.getString("extra_name");
            String str1 = datatype.substring(0, datatype.indexOf("."));
            String headtype = datatype.substring(str1.length() + 1, datatype.length());
            if (headtype.startsWith("B")) {
                datatype = "Byte";
            } else if (headtype.startsWith("W")) {
                datatype = "Word";
            } else if (headtype.startsWith("D")) {
                datatype = "DWord";
            }
            map.put("Data Type", datatype);
            map.put("Respect Data Type", "1");
            map.put("Client Access", "R/W");
            map.put("Scan Rate", "100");
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public JSONArray selectList() {
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' AND is_config = 'true'").orderByAsc(Device::getDevice_code).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("device_type", obj.getString("device_type"));
            json.put("device_code", obj.getString("device_code"));
            json.put("device_name", obj.getString("device_name"));
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectConveyorList() {
        //设备基础信息表【acs_device】
//        JSONArray arr = WQLObject.getWQLObject("acs_device").query("is_delete= '0' AND is_active= '1' AND device_type = 'conveyor'").getResultJSONArray(0);
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' AND device_type = 'conveyor'").list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("device_type", obj.getString("device_type"));
            json.put("device_code", obj.getString("device_code"));
            json.put("device_name", obj.getString("device_name"));
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectDeviceListByRegion(String region) {
        //设备基础信息表【acs_device】
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' and  region = '" + region + "'").orderByAsc(Device::getDevice_code).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        //acs_device_extra
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("device_code", obj.getString("device_code"));
            json.put("device_name", obj.getString("device_name"));

            List<DeviceExtra> deviceExtraList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, obj.getString("device_id")).list();
            JSONArray extraArr = JSONArray.parseArray(JSON.toJSONString(deviceExtraList));

            for (int m = 0; m < extraArr.size(); m++) {
                JSONObject jsonObject = extraArr.getJSONObject(m);
                String extra_code = jsonObject.getString("extra_code");
                //定点作业：自动创建任务
                if ("auto_create_task".equals(extra_code)) {
                    json.put("auto_create_task", jsonObject.getBoolean("extra_value"));
                }
                //呼叫
                if ("apply_task".equals(extra_code)) {
                    json.put("apply_task", jsonObject.getBoolean("extra_value"));
                }
                //响应
                if ("manual_create_task".equals(extra_code)) {
                    json.put("manual_create_task", jsonObject.getBoolean("extra_value"));
                }
                //清除
                if ("auto_clean_task".equals(extra_code)) {
                    json.put("auto_clean_task", jsonObject.getBoolean("extra_value"));
                }

            }
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectDeviceListOne() {
        //设备基础信息表【acs_device】
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' AND region = '1'").orderByAsc(Device::getSeq_num).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));

        //acs_device_extra
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("device_code", obj.getString("device_code"));
            json.put("checked", false);
            json.put("device_name", obj.getString("device_name"));
            Device device = deviceAppService.findDeviceByCode(obj.getString("device_code"));
            StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
            if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                json.put("quantity", standardOrdinarySiteDeviceDriver.getQty());
                json.put("material_type", standardOrdinarySiteDeviceDriver.getMaterial());
                json.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
            }
            List<DeviceExtra> deviceExtraList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, obj.getString("device_id")).list();
            JSONArray extraArr = JSONArray.parseArray(JSON.toJSONString(deviceExtraList));

            for (int m = 0; m < extraArr.size(); m++) {
                JSONObject jsonObject = extraArr.getJSONObject(m);
                String extra_code = jsonObject.getString("extra_code");
                //定点作业：自动创建任务
                if ("auto_create_task".equals(extra_code)) {
                    json.put("auto_create_task", jsonObject.getBoolean("extra_value"));
                }
                //呼叫
                if ("apply_task".equals(extra_code)) {
                    json.put("apply_task", jsonObject.getBoolean("extra_value"));
                }
                //响应
                if ("manual_create_task".equals(extra_code)) {
                    json.put("manual_create_task", jsonObject.getBoolean("extra_value"));
                }
                //清除
                if ("auto_clean_task".equals(extra_code)) {
                    json.put("auto_clean_task", jsonObject.getBoolean("extra_value"));
                }

            }
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectDeviceListTwo() {
        //设备基础信息表【acs_device】
//        JSONArray arr = WQLObject.getWQLObject("acs_device").query("is_delete= '0' AND is_active= '1' AND region = '2'", "seq_num").getResultJSONArray(0);
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' AND region = '2'").orderByAsc(Device::getSeq_num).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        //acs_device_extra
//        WQLObject extraTab = WQLObject.getWQLObject("acs_device_extra");
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("checked", false);
            json.put("device_code", obj.getString("device_code"));
            json.put("device_name", obj.getString("device_name"));
            Device device = deviceAppService.findDeviceByCode(obj.getString("device_code"));
            StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
            if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                json.put("quantity", standardOrdinarySiteDeviceDriver.getQty());
                json.put("material_type", standardOrdinarySiteDeviceDriver.getMaterial());
                json.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
            }
//            JSONArray extraArr = extraTab.query("device_id = '" + obj.getString("device_id") + "'").getResultJSONArray(0);
            List<DeviceExtra> deviceExtraList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, obj.getString("device_id")).list();
            JSONArray extraArr = JSONArray.parseArray(JSON.toJSONString(deviceExtraList));
            for (int m = 0; m < extraArr.size(); m++) {
                JSONObject jsonObject = extraArr.getJSONObject(m);
                String extra_code = jsonObject.getString("extra_code");
                //定点作业：自动创建任务
                if ("auto_create_task".equals(extra_code)) {
                    json.put("auto_create_task", jsonObject.getBoolean("extra_value"));
                }
                //呼叫
                if ("apply_task".equals(extra_code)) {
                    json.put("apply_task", jsonObject.getBoolean("extra_value"));
                }
                //响应
                if ("manual_create_task".equals(extra_code)) {
                    json.put("manual_create_task", jsonObject.getBoolean("extra_value"));
                }
                //清除
                if ("auto_clean_task".equals(extra_code)) {
                    json.put("auto_clean_task", jsonObject.getBoolean("extra_value"));
                }

            }
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectDeviceListThree() {
        //设备基础信息表【acs_device】
//        JSONArray arr = WQLObject.getWQLObject("acs_device").query("is_delete= '0' AND is_active= '1' AND region = '3'", "seq_num").getResultJSONArray(0);
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' AND region = '3'").orderByAsc(Device::getSeq_num).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        //acs_device_extra
//        WQLObject extraTab = WQLObject.getWQLObject("acs_device_extra");
        JSONArray result = new JSONArray();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject obj = arr.getJSONObject(i);
            JSONObject json = new JSONObject();
            json.put("device_id", obj.getString("device_id"));
            json.put("device_code", obj.getString("device_code"));
            json.put("checked", false);
            json.put("device_name", obj.getString("device_name"));
            Device device = deviceAppService.findDeviceByCode(obj.getString("device_code"));
            StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
            if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                json.put("quantity", standardOrdinarySiteDeviceDriver.getQty());
                json.put("material_type", standardOrdinarySiteDeviceDriver.getMaterial());
                json.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
            }
//            JSONArray extraArr = extraTab.query("device_id = '" + obj.getString("device_id") + "'").getResultJSONArray(0);
            List<DeviceExtra> deviceExtraList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, obj.getString("device_id")).list();
            JSONArray extraArr = JSONArray.parseArray(JSON.toJSONString(deviceExtraList));
            for (int m = 0; m < extraArr.size(); m++) {
                JSONObject jsonObject = extraArr.getJSONObject(m);
                String extra_code = jsonObject.getString("extra_code");
                //定点作业：自动创建任务
                if ("auto_create_task".equals(extra_code)) {
                    json.put("auto_create_task", jsonObject.getBoolean("extra_value"));
                }
                //呼叫
                if ("apply_task".equals(extra_code)) {
                    json.put("apply_task", jsonObject.getBoolean("extra_value"));
                }
                //响应
                if ("manual_create_task".equals(extra_code)) {
                    json.put("manual_create_task", jsonObject.getBoolean("extra_value"));
                }
                //清除
                if ("auto_clean_task".equals(extra_code)) {
                    json.put("auto_clean_task", jsonObject.getBoolean("extra_value"));
                }

            }
            result.add(json);
        }
        return result;
    }

    @Override
    public JSONArray selectDeviceDevicerInfo(String status) {

        JSONArray deviceInfo = new JSONArray();
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
//        JSONArray arr = WQLObject.getWQLObject("acs_device").query("is_delete= '0' AND is_active= '1' and  region != ''  and is_config=  'true' ").getResultJSONArray(0);
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).apply("is_delete= '0' AND is_active= '1' and  region != ''  and is_config=  'true' ").list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        JSONArray result = new JSONArray();

        // status=2 代表查询请求的设备 =3代表查询相应的设备
        if (status.equals("2")) {
            for (int i = 0; i < arr.size(); i++) {
                JSONObject devicejo = new JSONObject();
                JSONObject obj = arr.getJSONObject(i);
                String region = obj.getString("region");
                String device_code = obj.getString("device_code");
                Device device = appService.findDeviceByCode(device_code);
                if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                    standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                    int branchProtocol = standardOrdinarySiteDeviceDriver.getBranchProtocol();
                    if (branchProtocol == 2) {
                        devicejo.put("device_code", device_code);
                        devicejo.put("branchProtocol", branchProtocol);
                        devicejo.put("region", region);
                        devicejo.put("qty", standardOrdinarySiteDeviceDriver.getQty());
                        devicejo.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
                        devicejo.put("material", standardOrdinarySiteDeviceDriver.getMaterial());
                        devicejo.put("status", standardOrdinarySiteDeviceDriver.isRequireSucess());
                        deviceInfo.add(devicejo);
                    }
                }
            }
        } else if (status.equals("3")) {
            for (int i = 0; i < arr.size(); i++) {
                JSONObject devicejo = new JSONObject();
                JSONObject obj = arr.getJSONObject(i);
                String region = obj.getString("region");
                String device_code = obj.getString("device_code");
                Device device = appService.findDeviceByCode(device_code);
                if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                    standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                    int branchProtocol = standardOrdinarySiteDeviceDriver.getBranchProtocol();
                    if (branchProtocol == 3) {
                        devicejo.put("device_code", device_code);
                        devicejo.put("branchProtocol", branchProtocol);
                        devicejo.put("region", region);
                        devicejo.put("qty", standardOrdinarySiteDeviceDriver.getQty());
                        devicejo.put("material", standardOrdinarySiteDeviceDriver.getMaterial());
                        devicejo.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
                        devicejo.put("status", standardOrdinarySiteDeviceDriver.isRequireSucess());
                        deviceInfo.add(devicejo);
                    }
                }
            }
        } else {
            for (int i = 0; i < arr.size(); i++) {
                JSONObject devicejo = new JSONObject();
                JSONObject obj = arr.getJSONObject(i);
                String region = obj.getString("region");
                String device_code = obj.getString("device_code");
                Device device = appService.findDeviceByCode(device_code);
                if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
                    standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
                    int branchProtocol = standardOrdinarySiteDeviceDriver.getBranchProtocol();
                    devicejo.put("device_code", device_code);
                    devicejo.put("branchProtocol", branchProtocol);
                    devicejo.put("region", region);
                    devicejo.put("qty", standardOrdinarySiteDeviceDriver.getQty());
                    devicejo.put("material", standardOrdinarySiteDeviceDriver.getMaterial());
                    devicejo.put("remark", standardOrdinarySiteDeviceDriver.getRemark());
                    devicejo.put("status", standardOrdinarySiteDeviceDriver.isRequireSucess());
                    deviceInfo.add(devicejo);
                }
            }
        }


//        for(int i=0; i<result.size(); i++) {
//            JSONObject jo = (JSONObject) result.get(i);
//            JSONObject devicejo = new JSONObject();
//            String device_id = jo.getString("device_id");
//            String device_code = jo.getString("device_code");
//            String device_name = jo.getString("device_name");
//            Device device = appService.findDeviceByCode(device_code);
//            if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
//                standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
//                int branchProtocol = standardOrdinarySiteDeviceDriver.getBranchProtocol();
//                devicejo.put("device_code",device_code);
//                devicejo.put("branchProtocol",branchProtocol);
//                devicejo.put("qty",standardOrdinarySiteDeviceDriver.getQty());
//                devicejo.put("material",standardOrdinarySiteDeviceDriver.getMaterial());
//                devicejo.put("status",standardOrdinarySiteDeviceDriver.isRequireSucess());
//
//                deviceInfo.add(devicejo);
//            }
//        }

        return deviceInfo;

    }

    @Override
    public void updateConfig(JSONObject jsonObject) {
        //得到父表单的字段属性
        JSONObject parentForm = jsonObject.getJSONObject("parentForm");
        //得到扩展属性表字段记录
        JSONObject form = jsonObject.getJSONObject("form");
        //设备标识
        String device_id = parentForm.getString("device_id");
        String device_code = parentForm.getString("device_code");
        String opc_server_id = parentForm.getString("opc_id");
        String opc_plc_id = parentForm.getString("plc_id");
        String address = form.getString("address");
        String input_material = parentForm.getString("input_material");
        String device_type = parentForm.getString("device_type");
        String driver_code = parentForm.getString("driver_code");

        if (StrUtil.isEmpty(device_id)) {
            throw new BadRequestException("设备标识不能为空!");
        }

        log.info("更新设备主表信息");
        DeviceDto dto = this.findById(device_id);
        DeviceRunpointDto devrundto = new DeviceRunpointDto();
        if (dto != null) {
            dto.setIs_config("true");
            dto.setIs_route(parentForm.getString("is_route"));
            dto.setDriver_code(parentForm.getString("driver_code"));
            dto.setOpc_plc_id(opc_plc_id);
            dto.setOpc_server_id(opc_server_id);
            //dto.setIs_config("true");
            if (StrUtil.isEmpty(address)) {
                dto.setAddress("0");
            } else {
                dto.setAddress(address);
            }

            this.update(dto);
        }

        log.info("插入设备扩展表字段信息");

        //先删除设备扩展表【acs_device_extra】
        deviceExtraService.deleteAllByDeviceIds(new String[]{device_id});

        form.put("device_id", device_id);
        form.put("device_code", device_code);
        deviceExtraService.createByDeviceConfig(form, "01");

        //判断是否存在并开启站点管理
        if (form.containsKey("station_manager")) {

//            WQLObject wo = WQLObject.getWQLObject("acs_device_runpoint");
            if ("true".equals(form.get("station_manager").toString())) {
                //判断数据库记录是否存在 不存在则新增 存在则修改
//                JSONObject json = wo.query("device_id ='" + device_id + "'").uniqueResult(0);
                DeviceRunpoint deviceRunpoint = new LambdaQueryChainWrapper<>(deviceRunpointMapper).eq(DeviceRunpoint::getDevice_id, device_id).one();

//                if (MapUtil.isEmpty(json)) {
                if (ObjectUtil.isEmpty(deviceRunpoint)) {
                    devrundto.setDevice_code(dto.getDevice_code());
                    devrundto.setDevice_id(dto.getDevice_id());
                    devrundto.setCreate_by("auto");
                    devrundto.setCreate_time(DateUtil.now());

                    DeviceRunpoint entity = ConvertUtil.convert(devrundto, DeviceRunpoint.class);
                    deviceRunpointMapper.insert(entity);

                } else {
                    deviceRunpoint.setContainer(null);
                    deviceRunpoint.setTaskno("0");
                    deviceRunpoint.setHasgoods("0");
                    deviceRunpoint.setRemark(null);
                    deviceRunpointMapper.updateById(deviceRunpoint);
                }
            } else {
                LambdaQueryWrapper<DeviceRunpoint> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(DeviceRunpoint::getDevice_id, device_id);
                deviceRunpointMapper.delete(wrapper);
            }

        }
        //有db
        JSONArray data1 = jsonObject.getJSONArray("data1");
        if (data1 != null) {
            //处理读的DB字段
            //设备扩展表【acs_device_extra】
//            WQLObject wo = WQLObject.getWQLObject("acs_device_extra");
//            wo.delete("device_id = '" + device_id + "' and filed_type = '02'");
            LambdaQueryWrapper<DeviceExtra> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DeviceExtra::getDevice_id, device_id);
            wrapper.eq(DeviceExtra::getFiled_type, "02");
            deviceExtraMapper.delete(wrapper);
            for (int i = 0; i < data1.size(); i++) {
                JSONObject param = new JSONObject();
                JSONObject json = data1.getJSONObject(i);
                param.put("extra_id", IdUtil.simpleUUID());
                //heartbeat
                param.put("extra_code", json.getString("code"));
                param.put("extra_name", json.getString("db"));
                param.put("remark", json.getString("name"));
                param.put("order_seq", i + 1);
                //DB读
                param.put("filed_type", "02");
                param.put("device_id", device_id);
                param.put("device_code", device_code);
                param.put("create_by", SecurityUtils.getCurrentUsername());
                param.put("create_time", DateUtil.now());
//                wo.insert(param);
                DeviceExtra entity = ConvertUtil.convert(param, DeviceExtra.class);
                deviceExtraMapper.insert(entity);
            }

        }
        //处理写
        JSONArray data2 = jsonObject.getJSONArray("data2");
        if (data2 != null) {
            LambdaQueryWrapper<DeviceExtra> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DeviceExtra::getDevice_id, device_id);
            wrapper.eq(DeviceExtra::getFiled_type, "03");
            deviceExtraMapper.delete(wrapper);
            for (int i = 0; i < data2.size(); i++) {
                JSONObject param = new JSONObject();
                JSONObject json = data2.getJSONObject(i);
                param.put("extra_id", IdUtil.simpleUUID());
                //heartbeat
                param.put("extra_code", json.getString("code"));
                param.put("extra_name", json.getString("db"));
                param.put("remark", json.getString("name"));
                param.put("order_seq", i + 1);
                //DB读
                param.put("filed_type", "03");
                param.put("device_id", device_id);
                param.put("device_code", device_code);
                param.put("create_by", SecurityUtils.getCurrentUsername());
                param.put("create_time", DateUtil.now());
//                wo.insert(param);
                DeviceExtra entity = ConvertUtil.convert(param, DeviceExtra.class);
                deviceExtraMapper.insert(entity);
            }
        }

//        WQLObject wo = WQLObject.getWQLObject("acs_storage_cell");
        if (StrUtil.equals(device_type, "storage")) {
            int x = form.getInteger("x");
            int maxY = form.getInteger("maxY");
            int minY = form.getInteger("minY");
            int maxZ = form.getInteger("maxZ");
            int minZ = form.getInteger("minZ");
            for (int i = minY; i <= maxY; i++) {
                for (int j = minZ; j <= maxZ; j++) {
//                    JSONObject json = wo.query("storage_code='" + device_code + "-" + formatNum(i) + "-" + formatNum(j) + "'").uniqueResult(0);
                    StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code, device_code + "-" + formatNum(i) + "-" + formatNum(j)).one();
                    if (ObjectUtil.isEmpty(storageCell)) {
                        StorageCellDto celldto = new StorageCellDto();
                        celldto.setStorage_id(IdUtil.simpleUUID());
                        celldto.setStorage_code(device_code + "-" + formatNum(i) + "-" + formatNum(j));
                        celldto.setParent_storage_code(device_code + "-" + formatNum(i) + "-" + formatNum(j));
                        celldto.setX(formatNum(x));
                        celldto.setY(formatNum(i));
                        celldto.setZ(formatNum(j));
                        //celldto.setAddress(Integer.parseInt(CodeUtil.getNewCode("NDCADDRESS_NO")));
                        celldto.setCreate_by("admin");
                        celldto.setCreate_time(DateUtil.now());
//                        wo.insert((JSONObject) JSONObject.toJSON(celldto));
                        StorageCell entity = ConvertUtil.convert(celldto, StorageCell.class);
                        storageCellMapper.insert(entity);
                    }
                }
            }
        } else {
            //空盘堆叠驱动 需要按照数量生成
            if (StrUtil.equals(driver_code, "standard_emptypallet_site") && form.containsKey("max_emptypalletnum")) {
                int num = form.getInteger("max_emptypalletnum");
                for (int i = 1; i < num + 1; i++) {
//                    JSONObject json = wo.query("storage_code ='" + device_code + "." + i + "'").uniqueResult(0);
                    StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code, device_code + "." + i).one();
                    if (ObjectUtil.isEmpty(storageCell)) {
                        StorageCellDto celldto = new StorageCellDto();
                        celldto.setStorage_id(IdUtil.simpleUUID());
                        celldto.setStorage_code(device_code + "." + i);
                        celldto.setParent_storage_code(device_code + "." + i);
                        celldto.setX("0");
                        celldto.setY("0");
                        celldto.setZ("0");
                        celldto.setAddress(Integer.parseInt(CodeUtil.getNewCode("NDCADDRESS_NO")));
                        celldto.setCreate_by("admin");
                        celldto.setCreate_time(DateUtil.now());
//                        wo.insert((JSONObject) JSONObject.toJSON(celldto));
                        StorageCell entity = ConvertUtil.convert(celldto, StorageCell.class);
                        storageCellMapper.insert(entity);
                    }
                }
            } else {
//                JSONObject json = wo.query("storage_code ='" + device_code + "'").uniqueResult(0);
                StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code, device_code).one();
                if (ObjectUtil.isEmpty(storageCell)) {
                    StorageCellDto celldto = new StorageCellDto();
                    celldto.setStorage_id(IdUtil.simpleUUID());
                    celldto.setStorage_code(device_code);
                    celldto.setParent_storage_code(device_code);
                    celldto.setX("0");
                    celldto.setY("0");
                    celldto.setZ("0");
                    celldto.setAddress(Integer.parseInt(CodeUtil.getNewCode("NDCADDRESS_NO")));
                    celldto.setCreate_by("admin");
                    celldto.setCreate_time(DateUtil.now());
//                    wo.insert((JSONObject) JSONObject.toJSON(celldto));
                    StorageCell entity = ConvertUtil.convert(celldto, StorageCell.class);
                    storageCellMapper.insert(entity);
                }
            }

        }
        deviceAppService.removeDevice(device_code);
        deviceAppService.addDevice(device_code);
    }


    @Override
    public void changeDeviceStatus(JSONObject form) {
        String device_code = form.getString("device_code");
        if (StrUtil.contains(device_code, "-") && StrUtil.count(device_code, "-") == 2) {
            String[] point = device_code.split("-");
            device_code = point[0];
        }
        //需要数量
        String hasGoodStatus = form.getString("hasGoodStatus");
        if (StrUtil.isEmpty(hasGoodStatus)) {
            hasGoodStatus = "0";
        }
        String batch = form.getString("batch");
        String material_type = form.getString("material_type");
        String quantity = form.getString("quantity");
        String remark = form.getString("remark");
        String vehicle_code = form.getString("vehicle_code");
        String islock = form.getString("islock");
        String requireSucess = form.getString("requireSucess");
        String fullrequireSucess = form.getString("fullrequireSucess");
        if (device_code.indexOf(".") != -1) {
            device_code = device_code.substring(0, device_code.indexOf("."));
        }
        Device device = deviceAppService.findDeviceByCode(device_code);
        if (ObjectUtil.isEmpty(device)) {
            throw new BadRequestException("未找到对应设备:" + device_code);
        }
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        SlitTwoManipulatorDeviceDriver slitTwoManipulatorDeviceDriver;
        //检测站点
        StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver;
        if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
            if (!StrUtil.isEmpty(hasGoodStatus)) {
                standardOrdinarySiteDeviceDriver.setHasGoods(Integer.parseInt(hasGoodStatus));
                device.setHas_goods(Integer.parseInt(hasGoodStatus));
            }
            if (StrUtil.isNotEmpty(material_type)) {
                standardOrdinarySiteDeviceDriver.setMaterial(material_type);
                device.setMaterial_type(material_type);
            } else {
                standardOrdinarySiteDeviceDriver.setMaterial("");
                device.setMaterial_type("");
            }
            if (StrUtil.isNotEmpty(quantity)) {
                standardOrdinarySiteDeviceDriver.setQty(quantity);
                device.setQuantity(quantity);
            } else {
                standardOrdinarySiteDeviceDriver.setQty("");
                device.setQuantity("");
            }
            if (StrUtil.isNotEmpty(remark)) {
                standardOrdinarySiteDeviceDriver.setRemark(remark);
                device.setRemark(remark);
            } else {
                standardOrdinarySiteDeviceDriver.setRemark("");
                device.setRemark("");
            }
            if (StrUtil.isNotEmpty(batch)) {
                standardOrdinarySiteDeviceDriver.setBatch(batch);
                device.setBatch(batch);
            } else {
                standardOrdinarySiteDeviceDriver.setBatch("");
                device.setBatch("");
            }
//            WQLObject runpointwo = WQLObject.getWQLObject("acs_device_runpoint");
//            JSONObject json = runpointwo.query("device_code ='" + device_code + "'").uniqueResult(0);
            DeviceRunpoint deviceRunpoint = new LambdaQueryChainWrapper<>(deviceRunpointMapper).eq(DeviceRunpoint::getDevice_code, device_code).one();
            if (!ObjectUtil.isEmpty(deviceRunpoint)) {
//                DeviceRunpointDto obj = json.toJavaObject(DeviceRunpointDto.class);
                deviceRunpoint.setHasgoods(hasGoodStatus);
                deviceRunpoint.setMaterial_type(material_type);
                deviceRunpoint.setBatch(batch);
                device.setHas_goods(Integer.parseInt(hasGoodStatus));
                device.setMaterial_type(material_type);
                device.setRemark(remark);
                device.setQuantity(quantity);
                device.setBatch(batch);
                device.setIslock(islock);
//                JSONObject updatejson = (JSONObject) JSONObject.toJSON(obj);
//                runpointwo.update(updatejson, "device_code = '" + device_code + "'");
                LambdaQueryWrapper<DeviceRunpoint> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(DeviceRunpoint::getDevice_code, device_code);
                deviceRunpointMapper.delete(wrapper);
            }
        } else if (device.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) {
            standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) device.getDeviceDriver();
            standardInspectSiteDeviceDriver.setMaterial(material_type);
            standardInspectSiteDeviceDriver.setBatch(batch);
            device.setMaterial_type(material_type);
            device.setBatch(batch);
        } else if (device.getDeviceDriver() instanceof SlitTwoManipulatorDeviceDriver) {
            slitTwoManipulatorDeviceDriver = (SlitTwoManipulatorDeviceDriver) device.getDeviceDriver();
            slitTwoManipulatorDeviceDriver.setDeviceStatus(form);
        } else if (device.getDeviceDriver() instanceof SiemensConveyorDeviceDriver) {
            SiemensConveyorDeviceDriver siemensConveyorDeviceDriver = (SiemensConveyorDeviceDriver) device.getDeviceDriver();
            siemensConveyorDeviceDriver.setDeviceStatus(form);
        } else if (device.getDeviceDriver() instanceof SiemensConveyorLabelingDeviceDriver) {
            SiemensConveyorLabelingDeviceDriver siemensConveyorLabelingDeviceDriver = (SiemensConveyorLabelingDeviceDriver) device.getDeviceDriver();
            siemensConveyorLabelingDeviceDriver.setDeviceStatus(form);
        } else if (device.getDeviceDriver() instanceof OvenGantryManipulatorDeviceDriver) {
            OvenGantryManipulatorDeviceDriver ovenGantryManipulatorDeviceDriver = (OvenGantryManipulatorDeviceDriver) device.getDeviceDriver();
            ovenGantryManipulatorDeviceDriver.setDeviceStatus(form);
        } else if (device.getDeviceDriver() instanceof SiemensConveyorCkkDeviceDriver) {
            SiemensConveyorCkkDeviceDriver siemensConveyorCkkDeviceDriver = (SiemensConveyorCkkDeviceDriver) device.getDeviceDriver();
            siemensConveyorCkkDeviceDriver.setDeviceStatus(form);
        } else if (device.getDeviceDriver() instanceof StandardCoveyorControlWithScannerDeviceDriver) {
            StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver = (StandardCoveyorControlWithScannerDeviceDriver) device.getDeviceDriver();
            standardCoveyorControlWithScannerDeviceDriver.setDeviceStatus(form);
        }
    }

    @Override
    public void changeFenceStatus(JSONObject form) {
        String device_code = form.getString("device_code");
        String suspended = form.getString("suspended");
        if (StrUtil.isEmpty(suspended)) {
            return;
        }

        Device device = deviceAppService.findDeviceByCode(device_code);

    }

    public String formatNum(int x) {
        if (x < 10) {
            return "0" + x;
        }
        return String.valueOf(x);
    }

    @Override
    public void callAgv(JSONObject form) {
        String device_code = form.getString("device_code");
        //需要数量
        String quantity = form.getString("quantity");
        //物料类型
        String material_type = form.getString("material_type");
        String remark = form.getString("remark");
        if (StrUtil.isEmpty(quantity) || StrUtil.isEmpty(material_type)) {
            throw new BadRequestException("数量及物料不可为空，操作失败!");
        }
        Device device = deviceAppService.findDeviceByCode(device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
            if (standardOrdinarySiteDeviceDriver.getBranchProtocol() == 2) {
                throw new BadRequestException("该设备已有呼叫请求未响应，操作失败!");
            } else {
                standardOrdinarySiteDeviceDriver.setBranchProtocol(2);
                standardOrdinarySiteDeviceDriver.setQty(quantity);
                standardOrdinarySiteDeviceDriver.setMaterial(material_type);
                standardOrdinarySiteDeviceDriver.setRemark(remark);
            }
        }

        StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver;
        if (device.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) {
            standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) device.getDeviceDriver();
            standardInspectSiteDeviceDriver.setBranchProtocol(2);
            standardInspectSiteDeviceDriver.setQty(quantity);
            standardInspectSiteDeviceDriver.setMaterial(material_type);
            standardInspectSiteDeviceDriver.setRemark(remark);
        }
    }

    @Override
    public void addMaterial(JSONObject form) {
        String device_code = form.getString("device_code");
        //需要数量
        String quantity = form.getString("quantity");
        //物料类型
        String material_type = form.getString("material_type");
        String remark = form.getString("remark");

        Device device = deviceAppService.findDeviceByCode(device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
            standardOrdinarySiteDeviceDriver.setQty(quantity);
            standardOrdinarySiteDeviceDriver.setMaterial(material_type);
            standardOrdinarySiteDeviceDriver.setRemark(remark);
            device.setMaterial_type(material_type);
            device.setQuantity(quantity);
            device.setRemark(remark);
        }

    }

    @Override
    public void responseAgv(JSONObject form) {
        //起始设备
        String start_device_code = form.getString("start_device_code");
        //下一设备
        String next_device_code = form.getString("device_code");
        //需要数量
        String quantity = form.getString("qty");
        //物料类型
        String material_type = form.getString("material");
        //备注信息
        String remark = form.getString("remark");

        Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (startDevice.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) startDevice.getDeviceDriver();
            standardOrdinarySiteDeviceDriver.setBranchProtocol(3);
            standardOrdinarySiteDeviceDriver.setQty(quantity);
            standardOrdinarySiteDeviceDriver.setMaterial(material_type);
            standardOrdinarySiteDeviceDriver.setRemark(remark);
            standardOrdinarySiteDeviceDriver.setPurpose(next_device_code);
        }
    }

    @Override
    public void autoCreateTask(JSONObject form) {
        //起始设备
        String start_device_code = form.getString("start_device_code");
        String material_type = form.getString("material_type");
        String batch = form.getString("batch");

        Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (startDevice.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) startDevice.getDeviceDriver();
            standardOrdinarySiteDeviceDriver.setBranchProtocol(4);
            standardOrdinarySiteDeviceDriver.setMaterial(material_type);
            standardOrdinarySiteDeviceDriver.setBatch(batch);
        }
    }

    @Override
    public void unlock(List<String> deviceCodes) {
        for (int i = 0; i < deviceCodes.size(); i++) {
            String deviceCode = deviceCodes.get(i);
            Device startDevice = deviceAppService.findDeviceByCode(deviceCode);
        }
    }

    @Override
    public void cleanTask(JSONObject json) {
        //起始设备
        String start_device_code = json.getString("start_device_code");

        Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (startDevice.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) startDevice.getDeviceDriver();
            standardOrdinarySiteDeviceDriver.setHasGoods(0);
            JSONObject jsonjo = new JSONObject();
            jsonjo.put("device_code", start_device_code);
            jsonjo.put("hasGoodStatus", "0");
            changeDeviceStatus(jsonjo);
        }
    }

    @Override
    public void cleanMaterial(JSONObject json) {
        String device_code = json.getString("device_code");
        //需要数量
        String quantity = json.getString("quantity");
        //物料类型
        String material_type = json.getString("material_type");
        String remark = json.getString("remark");

        Device device = deviceAppService.findDeviceByCode(device_code);
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
            standardOrdinarySiteDeviceDriver.setHasGoods(0);
            standardOrdinarySiteDeviceDriver.setQty("");
            standardOrdinarySiteDeviceDriver.setMaterial("");
            standardOrdinarySiteDeviceDriver.setRemark("");
            JSONObject jsonjo = new JSONObject();
            jsonjo.put("device_code", device_code);
            jsonjo.put("hasGoodStatus", "0");
            changeDeviceStatus(jsonjo);
        }
    }

    @Override
    public JSONObject queryDriverConfigByDeviceId(String device_id, String driver_code) {
        final JSONObject extraObj = new JSONObject();
        DeviceDto dto = this.findById(device_id);
        if (ObjectUtil.isNull(dto)) {
            return new JSONObject();
        }
        log.info("判断设备是否配置过驱动!");
        //处理设备扩展属性
        JSONObject result = new JSONObject();

        //根据设备驱动定义获取OPC读写数据
        DeviceDriverDefination deviceDriverDefination = deviceDriverDefinationAppService.getDeviceDriverDefination(driver_code);
        OpcDeviceDriverDefination opcDeviceDriverDefination = null;
        if (deviceDriverDefination instanceof OpcDeviceDriverDefination) {
            opcDeviceDriverDefination = (OpcDeviceDriverDefination) deviceDriverDefination;
            //处理DB读和写属性
            result.put("rs", opcDeviceDriverDefination.getReadableItemDtos());
            result.put("ws", opcDeviceDriverDefination.getWriteableItemDtos());
        }


//        JSONArray arr = WQLObject.getWQLObject("acs_device_extra").query("filed_type ='01' and device_id = '" + device_id + "'").getResultJSONArray(0);
        List<DeviceExtra> deviceExtraList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getFiled_type, "01").list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceExtraList));
        for (int i = 0; i < arr.size(); i++) {
            final JSONObject json = arr.getJSONObject(i);
            if ("true".equalsIgnoreCase(json.getString("extra_value")) || "false".equalsIgnoreCase(json.getString("extra_value"))) {
                extraObj.put(json.getString("extra_code"), json.getBoolean("extra_value"));
            } else {
                boolean endsWith = json.getString("extra_value").endsWith("]");
                boolean startsWith = json.getString("extra_value").startsWith("[");
                if (endsWith && startsWith) {
                    JSONArray extraValue = JSONArray.parseArray(json.getString("extra_value"));
                    extraObj.put(json.getString("extra_code"), extraValue);
                } else {
                    extraObj.put(json.getString("extra_code"), json.get("extra_value"));
                }
            }
        }

        extraObj.put("address", dto.getAddress());
        result.put("form", extraObj);


        JSONObject json = (JSONObject) JSONObject.toJSON(dto);


        String opc_id = dto.getOpc_server_id();
        if (StrUtil.isNotEmpty(opc_id)) {
            OpcDto opcDto = opcService.findById(opc_id);
            String opc_code = opcDto.getOpc_code();
            json.put("opc_code", opc_code);
        }

        String plc_id = dto.getOpc_plc_id();
        if (StrUtil.isNotEmpty(opc_id)) {
            OpcPlcDto opcPlcDto = opcPlcService.findById(plc_id);
            String plc_code = opcPlcDto.getPlc_code();
            json.put("plc_code", plc_code);
        }

        String address = dto.getAddress();
        if (StrUtil.isNotEmpty(address)) {
            json.put("address", address);
        }

        //父表单
        result.put("parentForm", json);

        //判断是否配置过
        if (json.getBoolean("is_config")) {
            //设备扩展表【acs_device_extra】
//            JSONArray rs = WQLObject.getWQLObject("acs_device_extra").query("filed_type='02' and  device_id = '" + device_id + "'", "order_seq").getResultJSONArray(0);
            List<DeviceExtra> dList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getFiled_type, "02").orderByAsc(DeviceExtra::getOrder_seq).list();
            JSONArray rs = JSONArray.parseArray(JSON.toJSONString(dList));
            JSONArray r_arry = new JSONArray();
            //先获取模板
            if (ObjectUtil.isNotEmpty(opcDeviceDriverDefination)) {
                List<ItemDto> readableItemDtos = opcDeviceDriverDefination.getReadableItemDtos();
                List<JSONObject> readableItemJsons = new ArrayList<>();
                for (int i = 0; i < readableItemDtos.size(); i++) {
                    ItemDto itemDto = readableItemDtos.get(i);
                    JSONObject readableItemJson = new JSONObject();
                    readableItemJson.put("code", itemDto.getCode());
                    readableItemJson.put("name", itemDto.getName());
                    // readableItemJson.put("db",itemDto.getDb());
                    readableItemJsons.add(readableItemJson);
                }
                for (int i = 0; i < rs.size(); i++) {
                    JSONObject robj = new JSONObject();
                    String extra_code = rs.getJSONObject(i).getString("extra_code");
                    final String[] split = extra_code.split("\\.");
                    String code = split[split.length - 1];
                    robj.put("code", code);
                    robj.put("name", rs.getJSONObject(i).getString("remark"));
                    if (readableItemJsons.contains(robj)) {
                        robj.put("code", rs.getJSONObject(i).getString("extra_code"));
                        robj.put("db", rs.getJSONObject(i).getString("extra_name"));
                        r_arry.add(robj);
                    }
                }
                List<JSONObject> rarry = new ArrayList<>();
                for (int i = 0; i < r_arry.size(); i++) {
                    JSONObject rJson = r_arry.getJSONObject(i);
                    String code = rJson.getString("code");
                    String[] split = code.split("\\.");
                    code = split[split.length - 1];
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("code", code);
                    jsonObject.put("name", rJson.getString("name"));
                    rarry.add(jsonObject);
                }
                for (int i = 0; i < readableItemDtos.size(); i++) {
                    ItemDto itemDto = readableItemDtos.get(i);
                    JSONObject readableItemJson = new JSONObject();
                    readableItemJson.put("code", itemDto.getCode());
                    readableItemJson.put("name", itemDto.getName());
                    if (!rarry.contains(readableItemJson)) {
                        readableItemJson.put("db", itemDto.getDb());
                        r_arry.add(readableItemJson);
                    }
                }
//                JSONArray ws = WQLObject.getWQLObject("acs_device_extra").query("filed_type='03' and  device_id = '" + device_id + "'", "order_seq").getResultJSONArray(0);
                List<DeviceExtra> wsList = new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getFiled_type, "03").orderByAsc(DeviceExtra::getOrder_seq).list();
                JSONArray ws = JSONArray.parseArray(JSON.toJSONString(wsList));

                JSONArray w_arry = new JSONArray();
                List<ItemDto> writeableItemDtos = opcDeviceDriverDefination.getWriteableItemDtos();
                List<JSONObject> writeableItemJsons = new ArrayList<>();
                for (int i = 0; i < writeableItemDtos.size(); i++) {
                    ItemDto itemDto = writeableItemDtos.get(i);
                    JSONObject writeableItemJson = new JSONObject();
                    writeableItemJson.put("code", itemDto.getCode());
                    writeableItemJson.put("name", itemDto.getName());
                    //writeableItemJson.put("db",itemDto.getDb());
                    writeableItemJsons.add(writeableItemJson);
                }
                for (int i = 0; i < ws.size(); i++) {
                    String extra_code = ws.getJSONObject(i).getString("extra_code");
                    final String[] split = extra_code.split("\\.");
                    String code = split[split.length - 1];
                    JSONObject robj = new JSONObject();
                    robj.put("code", code);
                    robj.put("name", ws.getJSONObject(i).getString("remark"));
                    if (writeableItemJsons.contains(robj)) {
                        robj.put("code", ws.getJSONObject(i).getString("extra_code"));
                        robj.put("db", ws.getJSONObject(i).getString("extra_name"));
                        w_arry.add(robj);
                    }
                }
                List<JSONObject> warry = new ArrayList<>();
                for (int i = 0; i < w_arry.size(); i++) {
                    JSONObject wJson = w_arry.getJSONObject(i);
                    String code = wJson.getString("code");
                    String[] split = code.split("\\.");
                    code = split[split.length - 1];
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("code", code);
                    jsonObject.put("name", wJson.getString("name"));
                    warry.add(jsonObject);
                }
                for (int i = 0; i < writeableItemDtos.size(); i++) {
                    ItemDto itemDto = writeableItemDtos.get(i);
                    JSONObject writeableItemJson = new JSONObject();
                    writeableItemJson.put("code", itemDto.getCode());
                    writeableItemJson.put("name", itemDto.getName());
                    if (!warry.contains(writeableItemJson)) {
                        writeableItemJson.put("db", itemDto.getDb());
                        w_arry.add(writeableItemJson);
                    }
                }
                if (!r_arry.isEmpty()) {
                    result.put("rs", r_arry);
                }
                if (!w_arry.isEmpty()) {
                    result.put("ws", w_arry);
                }
            }


        } else {
            //处理DB读和写属性
//            result.put("rs", ReadUtil.getReadableItemDtos());
//            result.put("ws", ReadUtil.getWriteableItemDtos());
        }


        return result;
    }

    @Override
    public JSONArray testRead(Map map) {
        List dbItems = (List) map.get("dbItems");
        String opc_id = (String) map.get("opc_id");
        List<String> itemString = new ArrayList<String>();
        for (int i = 0; i < dbItems.size(); i++) {
            Object ob = dbItems.get(i);
            JSONObject json = (JSONObject) JSONObject.toJSON(ob);
            itemString.add(json.getString("code"));

        }
        Server server = ReadUtil.getServer(opc_id);
        final Map<String, Object> readList = ReadUtil.read(itemString, server);
        JSONArray result = new JSONArray();
        for (int i = 0; i < dbItems.size(); i++) {
            Object ob = dbItems.get(i);
            JSONObject json = (JSONObject) JSONObject.toJSON(ob);
            String code = json.getString("code");
            if (readList.containsKey(code)) {
                json.put("dbr_value", readList.get(code));
            }
            result.add(json);

        }
        return result;
    }

    @Override
    public void testWrite(Map map) {
        List dbItems = (List) map.get("dbItems");
        String opc_id = (String) map.get("opc_id");
        Map<String, Object> itemMap = new HashMap<String, Object>();
        for (int i = 0; i < dbItems.size(); i++) {
            Object ob = dbItems.get(i);
            JSONObject json = (JSONObject) JSONObject.toJSON(ob);
            if (!StrUtil.isEmpty(json.getString("dbw_value"))) {
                itemMap.put(json.getString("code"), json.getString("dbw_value"));
            }
        }
        Server server = ReadUtil.getServer(opc_id);
        ReadUtil.write(itemMap, server);
    }

    /**
     * 判断字符串中某个字符存在的个数
     *
     * @param str1 完整字符串
     * @param str2 要统计匹配个数的字符
     * @return
     */
    public static int countStr(String str1, String str2) {
        int count = 0;
        if (str1.indexOf(str2) == -1) {
            return 0;
        }
        while (str1.indexOf(str2) != -1) {
            count++;
            str1 = str1.substring(str1.indexOf(str2) + str2.length());
        }
        return count;
    }

    @Override
    public void downDeviceDBloadCSV(JSONArray jsonarr, HttpServletResponse response) {
        List<Object[]> cellList = new ArrayList<>();
        for (int i = 0; i < jsonarr.size(); i++) {
            List item = new ArrayList();
            JSONObject jo = jsonarr.getJSONObject(i);
            String extra_code = jo.getString("extra_code");
            //校验数据 格式为： RD1.RD1.A1.mode
            int num = countStr(extra_code, ".");
            if (num != 3) {
                throw new BadRequestException(extra_code + "数据格式不正确");
            }

            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            item.add(extra_code);
            item.add(jo.get("extra_name"));
            String datatype = jo.getString("extra_name");
            //西门子1200、1500 为DB
            if (datatype.startsWith("DB")) {
                //校验数据 格式为：DB600.B1
//                if(datatype.indexOf(".") == -1 ){
//                    throw new BadRequestException(jo.getString("extra_code") + "点位数据格式不正确");
//                }
//                int count = countStr(datatype,".");
//                if(count != 1){
//                    throw new BadRequestException(jo.getString("extra_code") + "点位数据格式不正确");
//                }

                String str1 = datatype.substring(0, datatype.indexOf("."));
                String headtype = datatype.substring(str1.length() + 1, datatype.length());
                if (headtype.startsWith("B")) {
                    if (headtype.contains(".")) {
                        datatype = "Boolean";
                    } else {
                        datatype = "Byte";
                    }
                } else if (headtype.startsWith("W")) {
                    datatype = "Word";
                } else if (headtype.startsWith("D")) {
                    datatype = "DWord";
                } else if (headtype.startsWith("S")) {
                    datatype = "String";
                } else if (headtype.startsWith("REAL")) {
                    datatype = "REAL";
                }
            } else {
                //西门子200
                if (datatype.indexOf(".") == -1) {
                    datatype = "Byte";
                } else {
                    datatype = "Boolean";
                }
            }

            item.add(datatype);
            item.add("1");
            item.add("R/W");
            item.add("100");

            cellList.add(item.toArray());
        }

        String[] tableHeaderArr = {"Tag Name", "Address", "Data Type", "Respect Data Type", "Client Access", "Scan Rate"};
        String fileName = "导出文件.csv";
        byte[] bytes = ExportCSVUtil.writeCsvAfterToBytes(tableHeaderArr, cellList);
        ExportCSVUtil.responseSetProperties(fileName, bytes, response);
    }

    @Override
    public void downDeviceDBloadOumulongCSV(JSONArray jsonarr, HttpServletResponse response) {
        List<Object[]> cellList = new ArrayList<>();
        for (int i = 0; i < jsonarr.size(); i++) {
            List item = new ArrayList();
            JSONObject jo = jsonarr.getJSONObject(i);
            String extra_code = jo.getString("extra_code");
            //校验数据 格式为： RD1.RD1.A1.mode
            int num = countStr(extra_code, ".");
            if (num != 3) {
                throw new BadRequestException(extra_code + "数据格式不正确");
            }

            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            item.add(extra_code);
            item.add(jo.get("extra_name"));
            String datatype = jo.getString("extra_name");
            //西门子200
            if (datatype.indexOf(".") == -1) {
                datatype = "Word";
            } else {
                datatype = "Boolean";
            }

            item.add(datatype);
            item.add("1");
            item.add("R/W");
            item.add("100");

            cellList.add(item.toArray());
        }

        String[] tableHeaderArr = {"Tag Name", "Address", "Data Type", "Respect Data Type", "Client Access", "Scan Rate"};
        String fileName = "导出文件.csv";
        byte[] bytes = ExportCSVUtil.writeCsvAfterToBytes(tableHeaderArr, cellList);
        ExportCSVUtil.responseSetProperties(fileName, bytes, response);
    }

    @Override
    public JSONArray selectDeviceListByType(String type) {
//        JSONArray arr = WQLObject.getWQLObject("acs_device").query("is_delete= '0' AND is_active= '1' and  device_type = '" + type + "' AND is_config = 'true'", "device_code").getResultJSONArray(0);
//        return arr;
        List<Device> deviceList = new LambdaQueryChainWrapper<>(deviceMapper).eq(Device::getIs_delete, "0").eq(Device::getIs_active, "1").eq(Device::getDevice_type, type).eq(Device::getIs_config, "true").orderByAsc(Device::getDevice_code).list();
        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(deviceList));
        return arr;
    }

    @Override
    public JSONObject queryStorageExtra(String device_code) {
//        JSONObject device = WQLObject.getWQLObject("acs_device").query("device_code = '" + device_code + "'").uniqueResult(0);
        Device device = new LambdaQueryChainWrapper<>(deviceMapper).eq(Device::getDevice_code, device_code).one();
        String device_id = device.getDevice_id();
//        WQLObject wo = WQLObject.getWQLObject("acs_device_extra");
        JSONObject jo = new JSONObject();
//        jo.put("maxY", wo.query("device_id = '" + device_id + "' AND extra_code = 'maxY'").uniqueResult(0).getString("extra_value"));
//        jo.put("minY", wo.query("device_id = '" + device_id + "' AND extra_code = 'minY'").uniqueResult(0).getString("extra_value"));
//        jo.put("maxZ", wo.query("device_id = '" + device_id + "' AND extra_code = 'maxZ'").uniqueResult(0).getString("extra_value"));
//        jo.put("minZ", wo.query("device_id = '" + device_id + "' AND extra_code = 'minZ'").uniqueResult(0).getString("extra_value"));
//        jo.put("tunnel", wo.query("device_id = '" + device_id + "' AND extra_code = 'tunnel'").uniqueResult(0).getString("extra_value"));
        jo.put("maxY", new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getExtra_code, "maxY").one().getExtra_value());
        jo.put("minY", new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getExtra_code, "minY").one().getExtra_value());
        jo.put("maxZ", new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getExtra_code, "maxZ").one().getExtra_value());
        jo.put("minZ", new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getExtra_code, "minZ").one().getExtra_value());
        jo.put("tunnel", new LambdaQueryChainWrapper<>(deviceExtraMapper).eq(DeviceExtra::getDevice_id, device_id).eq(DeviceExtra::getExtra_code, "tunnel").one().getExtra_value());
        return jo;
    }

    @Override
    public String queryScannerByCode(String device_code) throws Exception {
        Device device = deviceAppService.findDeviceByCode(device_code);
        StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver = null;
        String str = null;
        if (device.getDeviceDriver() instanceof StandardCoveyorControlWithScannerDeviceDriver) {
            standardCoveyorControlWithScannerDeviceDriver = (StandardCoveyorControlWithScannerDeviceDriver) device.getDeviceDriver();
            str = standardCoveyorControlWithScannerDeviceDriver.barcode();
        }
        return str;
    }

    @Override
    public void autoInitial() throws Exception {
        this.reload();
    }

    /**
     * 加载货位信息
     */
    @Override
    public void reload() {
        this.storageCells = queryAllStorageCell();
    }

    @Override
    public List<StorageCellDto> queryAllStorageCell() {
        List<StorageCell> list = new LambdaQueryChainWrapper<>(storageCellMapper).list();
        return ConvertUtil.convertList(list, StorageCellDto.class);
    }

    @Override
    public List<StorageCellDto> findAllStorageCellFromCache() {
        return storageCells;
    }

    @Override
    public int queryAddressBydeviceCode(String code) {
        Iterator iterator = storageCells.iterator();
        while (iterator.hasNext()) {
            StorageCellDto storageCellDto = (StorageCellDto) iterator.next();
            if (storageCellDto.getStorage_code().equals(code)) {
                if (storageCellDto.getAddress() != null) {
                    return storageCellDto.getAddress();
                }
            }
        }
        return 0;
    }

    @Override
    public String queryDeviceCodeByAddress(int code) {
        Iterator iterator = storageCells.iterator();
        while (iterator.hasNext()) {
            StorageCellDto storageCellDto = (StorageCellDto) iterator.next();
            if (storageCellDto.getAddress() != null && storageCellDto.getAddress() == code) {
                return storageCellDto.getStorage_code();
            }
        }
        return "0";
    }

    @Override
    public List<Device> findCacheDevice() {
        List<Device> list = deviceAppService.findAllDevice();
        return list;
    }

    @Override
    public void updateBarcode(JSONObject json) throws Exception {
        String device_code = json.getString("device_code");
        String barcode = json.getString("barcode");
        Device device = deviceAppService.findDeviceByCode(device_code);
        StandardScannerDeviceDriver standardScannerDeviceDriver;
        if (device.getDeviceDriver() instanceof ScannerDeviceDriver) {
            standardScannerDeviceDriver = (StandardScannerDeviceDriver) device.getDeviceDriver();
            standardScannerDeviceDriver.writeBarcode(barcode);
        }


    }

    @Override
    public JSONObject queryDBInfoByDriverCode(String driver_code) {
        //处理设备扩展属性
        JSONObject result = new JSONObject();
        //根据设备驱动定义获取OPC读写数据
        DeviceDriverDefination deviceDriverDefination = deviceDriverDefinationAppService.getDeviceDriverDefination(driver_code);
        if (deviceDriverDefination instanceof OpcDeviceDriverDefination) {
            OpcDeviceDriverDefination opcDeviceDriverDefination = (OpcDeviceDriverDefination) deviceDriverDefination;
            //处理DB读和写属性
            result.put("rs", opcDeviceDriverDefination.getReadableItemDtos());
            result.put("ws", opcDeviceDriverDefination.getWriteableItemDtos());
        }
        return result;
    }

    @Override
    public void downloadProtocolConfig(JSONObject param, HttpServletResponse response) throws IOException {
        JSONObject form = param.getJSONObject("form");
        String type = form.getString("type");
        Integer device_code = Integer.parseInt(form.getString("device_code"));
        int db_interval = Integer.parseInt(form.getString("db_interval"));
        JSONArray rss = param.getJSONArray("rs");
        JSONArray wss = param.getJSONArray("ws");
        int numberSize = Integer.parseInt(form.getString("device_number"));
        List<Map<String, Object>> list = new LinkedList<>();

        if (type.equals("db")) {
            for (int i = 0; i < numberSize; i++) {
                int dbInterval = db_interval * i;
                Integer deviceCode = device_code + i;
                for (int j = 0; j <= rss.size(); j++) {
                    Map<String, Object> map = new ListOrderedMap<>();
                    if (wss.size() > rss.size()) {
                        if (j == rss.size()) {
                            continue;
                        }
                    } else {
                        if (j == rss.size()) {
                            map.put("设备编码", "");
                            map.put("读取地址", "");
                            map.put("读取意义", "");
                            map.put("", "");
                            map.put("写入地址", "");
                            map.put("写入意义", "");
                            list.add(map);
                            continue;
                        }
                    }

                    if (i == 0 && j == 0) {
                        map.put("设备编码", "");
                    } else {
                        map.put("设备编码", deviceCode);
                    }
                    JSONObject rs = rss.getJSONObject(j);
                    String db = rs.getString("db");
                    String name = rs.getString("name");
                    if (i > 0) {
                        if (name.equals("心跳")) {
                            continue;
                        }
                    }
                    String[] dbs = db.split("\\.");
                    String startDB = dbs[0];
                    String endDB = dbs[1];
                    String endDBFirst = endDB.substring(0, 1);
                    Integer endDBEnd = Integer.parseInt(endDB.substring(1, endDB.length()));
                    endDBEnd = endDBEnd + dbInterval;
                    db = startDB + "." + endDBFirst + endDBEnd;
                    map.put("读取地址", db);
                    map.put("读取意义", name);
                    Map<String, Object> value = getValue(wss, j, dbInterval, i);
                    map.putAll(value);
                    list.add(map);
                    System.out.println(map);
                }
                if (wss.size() > rss.size()) {
                    int s = wss.size() - rss.size();
                    for (int l = 0; l <= s + 1; l++) {
                        Map<String, Object> map = new ListOrderedMap<>();
                        if (l == s + 1) {
                            map.put("设备编码", "");
                            map.put("读取地址", "");
                            map.put("读取意义", "");
                            map.put("", "");
                            map.put("写入地址", "");
                            map.put("写入意义", "");
                            list.add(map);
                            continue;
                        }
                        map.put("设备编码", deviceCode);
                        map.put("读取地址", "");
                        map.put("读取意义", "");
                        Map<String, Object> value = getValue(wss, rss.size() + l, dbInterval, i);
                        map.putAll(value);
                        list.add(map);
                    }
                }
            }
        } else if (type.equals("v")) {
            for (int i = 0; i < numberSize; i++) {
                int dbInterval = db_interval * i;
                Integer deviceCode = device_code + i;
                for (int j = 0; j <= rss.size(); j++) {
                    Map<String, Object> map = new ListOrderedMap<>();
                    if (j == rss.size()) {
                        map.put("设备编码", "");
                        map.put("读取地址", "");
                        map.put("读取意义", "");
                        map.put("", "");
                        map.put("写入地址", "");
                        map.put("写入意义", "");
                        list.add(map);
                        continue;
                    }
                    if (i == 0 && j == 0) {
                        map.put("设备编码", "");
                    } else {
                        map.put("设备编码", deviceCode);
                    }
                    JSONObject rs = rss.getJSONObject(j);
                    String db = rs.getString("db");
                    String name = rs.getString("name");
                    if (i > 0) {
                        if (name.equals("心跳")) {
                            continue;
                        }
                    }
                    //String[] dbs = db.split("\\.");
                    String startDB = db.substring(0, 2);
                    String endDB = db.substring(2, db.length());
                    Integer endDBEnd = Integer.parseInt(endDB);
                    endDBEnd = endDBEnd + dbInterval;
                    db = startDB + endDBEnd + "";
                    map.put("读取地址", db);
                    map.put("读取意义", name);
                    Map<String, Object> value = getValue1(wss, j, dbInterval, i);
                    map.putAll(value);
                    list.add(map);
                    System.out.println(map);
                }
            }
        }

        response.setContentType("application/octet-stream");
        FileUtil.downloadExcel(list, response);
    }

    public Map<String, Object> getValue(JSONArray wss, int j, Integer dbInterval, int i) {
        int size = wss.size();
        Map<String, Object> map = new ListOrderedMap<>();
        if (i == 0 && j == 0) {
            map.put("", "");
            map.put("写入地址", "");
            map.put("写入意义", "");
            return map;
        }
        if (i == 0 && j > 0) {
            if (j - 1 < size) {
                JSONObject ws = wss.getJSONObject(j - 1);
                String db = ws.getString("db");
                String name = ws.getString("name");
                String[] dbs = db.split("\\.");
                String startDB = dbs[0];
                String endDB = dbs[1];
                String endDBFirst = endDB.substring(0, 1);
                Integer endDBEnd = Integer.parseInt(endDB.substring(1, endDB.length()));
                endDBEnd = endDBEnd + dbInterval;
                db = startDB + "." + endDBFirst + endDBEnd;
                map.put("", "");
                map.put("写入地址", db);
                map.put("写入意义", name);
                return map;
            }
        }
        if (i > 0) {
            j = j - 1;
        }
        if (j < size) {
            JSONObject ws = wss.getJSONObject(j);
            String db = ws.getString("db");
            String name = ws.getString("name");
            String[] dbs = db.split("\\.");
            String startDB = dbs[0];
            String endDB = dbs[1];
            String endDBFirst = endDB.substring(0, 1);
            Integer endDBEnd = Integer.parseInt(endDB.substring(1, endDB.length()));
            endDBEnd = endDBEnd + dbInterval;
            db = startDB + "." + endDBFirst + endDBEnd;
            map.put("", "");
            map.put("写入地址", db);
            map.put("写入意义", name);
            return map;
        } else {
            map.put("", "");
            map.put("写入地址", "");
            map.put("写入意义", "");
            return map;
        }
    }

    @Override
    public void downDeviceDBloadSmartCSV(JSONArray jsonarr, HttpServletResponse response) {
        List<Object[]> cellList = new ArrayList<>();
        for (int i = 0; i < jsonarr.size(); i++) {
            List item = new ArrayList();
            JSONObject jo = jsonarr.getJSONObject(i);
            String extra_code = jo.getString("extra_code");
            //校验数据 格式为： RD1.RD1.A1.mode
            int num = countStr(extra_code, ".");
            if (num != 3) {
                throw new BadRequestException(extra_code + "数据格式不正确");
            }

            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            item.add(extra_code);
            item.add(jo.get("extra_name"));
            String datatype = jo.getString("extra_name");
            //西门子200
            if (!datatype.contains(".")) {
                String[] split = datatype.split("");
                if (split[1].equals("W")) {
                    datatype = "Word";
                } else if (split[1].equals("D")) {
                    datatype = "DWord";
                }
            } else {
                datatype = "Boolean";
            }

            item.add(datatype);
            item.add("1");
            item.add("R/W");
            item.add("100");

            cellList.add(item.toArray());
        }

        String[] tableHeaderArr = {"Tag Name", "Address", "Data Type", "Respect Data Type", "Client Access", "Scan Rate"};
        String fileName = "导出文件.csv";
        byte[] bytes = ExportCSVUtil.writeCsvAfterToBytes(tableHeaderArr, cellList);
        ExportCSVUtil.responseSetProperties(fileName, bytes, response);
    }

    @Override
    public void downDeviceDBloadFX5UCSV(JSONArray jsonarr, HttpServletResponse response) {
        List<Object[]> cellList = new ArrayList<>();
        for (int i = 0; i < jsonarr.size(); i++) {
            List item = new ArrayList();
            JSONObject jo = jsonarr.getJSONObject(i);
            String extra_code = jo.getString("extra_code");
            //校验数据 格式为： RD1.RD1.A1.mode
            int num = countStr(extra_code, ".");
            if (num != 3) {
                throw new BadRequestException(extra_code + "数据格式不正确");
            }

            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            extra_code = extra_code.substring(extra_code.indexOf(".") + 1, extra_code.length());
            item.add(extra_code);
            item.add(jo.get("extra_name"));
            String datatype = jo.getString("extra_name");
            //FX5U
            if (!datatype.contains(".")) {
                String[] split = datatype.split("");
                if (split[1].equals("D")) {
                    datatype = "Long";
                }
            } else {
                datatype = "Boolean";
            }

            item.add(datatype);
            item.add("1");
            item.add("R/W");
            item.add("100");

            cellList.add(item.toArray());
        }

        String[] tableHeaderArr = {"Tag Name", "Address", "Data Type", "Respect Data Type", "Client Access", "Scan Rate"};
        String fileName = "导出文件.csv";
        byte[] bytes = ExportCSVUtil.writeCsvAfterToBytes(tableHeaderArr, cellList);
        ExportCSVUtil.responseSetProperties(fileName, bytes, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void excelImport(MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) {
            throw new BadRequestException("文件为空,请添加数据后重新导入");
        }
        Long currentUserId = Long.valueOf(SecurityUtils.getCurrentUserId());
        String nickName = SecurityUtils.getCurrentNickName();
        String now = DateUtil.now();
        // 1.获取上传文件输入流
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        WQLObject wo = WQLObject.getWQLObject("acs_device");

        // 调用用 hutool 方法读取数据 默认调用第一个sheet
        ExcelReader excelReader = ExcelUtil.getReader(inputStream);
        // 从第二行开始获取数据   excelReader.read的结果是一个2纬的list，外层是行，内层是行对应的所有列
        List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
        // 循环获取的数据
        for (int i = 0; i < read.size(); i++) {
            List list = read.get(i);
            JSONObject param = new JSONObject();
            String device_code = list.get(0).toString();
            String device_name = list.get(1).toString();
            String device_type = list.get(2).toString();
            String is_config = list.get(3).toString();
            String is_route = list.get(4).toString();
            String region = list.get(5).toString();
            if (StrUtil.isEmpty(device_code)) {
                throw new BadRequestException("设备编号为空!");
            }
            if (StrUtil.isEmpty(device_name)) {
                device_name = device_code;
            }
            if (StrUtil.isEmpty(device_type)) {
                device_type = "conveyor";
            }
            if (StrUtil.isEmpty(is_config)) {
                is_config = "FALSE";
            }
            if (StrUtil.isEmpty(is_route)) {
                is_route = "false";
            }
            DeviceDto dto = this.findByCode(device_code);
            if (ObjectUtil.isNotEmpty(dto)) {
                continue;
            }
            //按照列获取
            param.put("device_id", IdUtil.getSnowflake(1, 1).nextId());
            param.put("device_code", device_code);
            param.put("device_name", device_name);
            param.put("device_type", device_type);
            param.put("is_config", is_config);
            param.put("is_route", is_route);
            param.put("create_by", nickName);
            param.put("create_time", now);
            param.put("update_by", nickName);
            param.put("update_time", now);
            param.put("region", region);

//            wo.insert(param);
            Device entity = ConvertUtil.convert(param, Device.class);
            deviceMapper.insert(entity);
        }
    }

    public Map<String, Object> getValue1(JSONArray wss, int j, Integer dbInterval, int i) {
        int size = wss.size();
        Map<String, Object> map = new ListOrderedMap<>();
        if (i == 0 && j == 0) {
            map.put("", "");
            map.put("写入地址", "");
            map.put("写入意义", "");
            return map;
        }
        if (i == 0 && j > 0) {
            if (j - 1 < size) {
                JSONObject ws = wss.getJSONObject(j - 1);
                String db = ws.getString("db");
                String name = ws.getString("name");
                //String[] dbs = db.split("\\.");
                String startDB = db.substring(0, 2);
                String endDB = db.substring(2, db.length());
                Integer endDBEnd = Integer.parseInt(endDB);
                endDBEnd = endDBEnd + dbInterval;
                db = startDB + endDBEnd + "";
                map.put("", "");
                map.put("写入地址", db);
                map.put("写入意义", name);
                return map;
            }
        }
        if (i > 0) {
            j = j - 1;
        }
        if (j < size) {
            JSONObject ws = wss.getJSONObject(j);
            String db = ws.getString("db");
            String name = ws.getString("name");
            String startDB = db.substring(0, 2);
            String endDB = db.substring(2, db.length());
            Integer endDBEnd = Integer.parseInt(endDB);
            endDBEnd = endDBEnd + dbInterval;
            db = startDB + endDBEnd + "";
            map.put("", "");
            map.put("写入地址", db);
            map.put("写入意义", name);
            return map;
        } else {
            map.put("", "");
            map.put("写入地址", "");
            map.put("写入意义", "");
            return map;
        }
    }
}
