<script setup lang="ts">
import { nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
import '../../../../Cesium/Widgets/widgets.css';
import { useMessage } from 'naive-ui';
import {
  getCameraIdApi,
  getCarPointAllCarApi,
  getCemeraPointApi,
  getFenceListsApi,
  getHomeCarApi,
  getMonitorIdApi,
  getMonitorPointApi,
  getPointAllPersonApi,
  getPointListApi
} from '@/api';
import { create3D } from '@/api/utils/cesium';
import { getElevationFromRay, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { cesiumToLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { iconPoint } from '@/api/utils/home/cesiumPositions';
import { carSpeed } from '@/api/utils/carSpeed';
import fullScreen from '@/utils/full';
import { webVideo } from '@/utils/ai';
import bluePersonIcon from '@/assets/blueperson.png';
import arrowLeftImg from '@/assets/jinrun/arrow-left.png';
import arrowRightImg from '@/assets/jinrun/arrow-right.png';
import redCarIcon from '@/assets/icon15Red.png';
import redVideoIcon from '@/assets/icon16Red.png';
import redBianIcon from '@/assets/icon17Red.png';
import blueCarIcon from '@/assets/icon15.png';
import blueVideoIcon from '@/assets/icon16.png';
import blueBianIcon from '@/assets/icon17.png';
import redPersonIcon from '../../../assets/redperson.png';
import MultiSelect from './appselect.vue';

let viewer: any = null;
const message = useMessage();
let personEntity: any;
const pins: any = [];
const full = ref(false);
let entityId: any;
let link: any;
let speed = 0;
let text = '';
const personList = ref([]);
const modelData = ref([
  [122.04736846370741, 37.48958083145254],
  [122.04760069379522, 37.489226301608184],
  [122.04823299200363, 37.489451482540346],
  [122.04802271634016, 37.48983410372907],
  [122.04748237248322, 37.49016152294277]
]);

const options = [
  {
    label: '全选',
    value: '1'
  },
  {
    label: '在线监测设备',
    value: '3'
  },
  {
    label: '视频监控',
    value: '2'
  },
  {
    label: '人员定位',
    value: '4'
  },
  {
    label: '车辆定位',
    value: '5'
  },
  {
    label: '越界开采',
    value: '6'
  }
];
const value = ref(options.map(opt => opt.value));

const data = ref([]);
const datasouce = ref();
const fence = ref<any>();
const personShow = ref(false);
const carShow = ref(false);
const equipmentShow = ref(false);
const videoShow = ref(false);
const treeFence = ref<any>([]);

const wallEntities = ref<any[]>([]);
const iconEntities = ref<any[]>([]);
const fenceData = ref({
  imagePath: '',
  imageColor: ''
});
const labelData = ref<any>();

const formData = ref([]);

// zhaojunbao 开始
// REM自适应配置
const active = ref(false);
const REM_CONFIG = {
  // 设计稿宽度
  designWidth: 1920,
  designHeight: 1080,
  // 基准值：1rem = 100px
  baseSize: 100
};
// 跳转首页
const navTo = () => {
  window.location.href = '/home';
};

/**
 * 设置REM单位
 * 根据窗口宽度动态计算根元素font-size
 */
const setRemUnit = () => {
  const { designWidth, designHeight, baseSize } = REM_CONFIG;
  // 获取当前窗口尺寸
  const windowWidth = window.innerWidth;
  const windowHeight = window.innerHeight;

  // 计算宽高缩放比例
  const scaleX = windowWidth / designWidth;
  const scaleY = windowHeight / designHeight;

  // 取较小的缩放比例以适应屏幕，确保内容不会被裁剪
  const scale = Math.min(scaleX, scaleY);

  // 设置根元素font-size，确保最小为50px（可选）
  const fontSize = Math.max(baseSize * scale, 50);
  document.documentElement.style.fontSize = `${fontSize}px`;
};

// 控制左右模块显示状态的响应式变量
const isLeftModulesVisible = ref(true);
const isRightModulesVisible = ref(true);

const toggleBothModules = () => {
  isLeftModulesVisible.value = !isLeftModulesVisible.value;
  isRightModulesVisible.value = !isRightModulesVisible.value;
};
// zhaojunbao 结束
// 模型
function add3dtiles() {
  const CesiumConfig = {
    defaultAccessToken:
      'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTE1OTUxOS1jNTc5LTQwNmMtOWU5My1jNTI3NTIyYzAxNTUiLCJpZCI6MjUwODM5LCJpYXQiOjE3Mjk5MjE1MzV9.xromwPD3oA1e0YsWV035DE5KmYvivkC6fxt344vwObA'
  };

  Cesium.Ion.defaultAccessToken = CesiumConfig.defaultAccessToken;

  viewer = new Cesium.Viewer('cesiumContainer', {
    geocoder: false,
    homeButton: false,
    infoBox: false,
    animation: false,
    fullscreenButton: false,
    enableCompass: true, // 启用指南针
    enableCompassOuterRing: true, // 启用指南针外环
    sceneModePicker: false,
    timeline: false,
    navigationHelpButton: false,
    baseLayerPicker: false,
    enableZoomControls: false, // 禁用缩放控件
    enableDistanceLegend: false, // 禁用比例尺
    selectionIndicator: false
  });

  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.cesiumWidget.creditContainer.style.display = 'none';
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  getModel().then(item => {
    create3D(viewer, item, 0);
  });
}

// 监听选中值的变化
watch(
  value,
  (newVal, oldVal) => {
    // 防止无限递归
    if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;

    // 获取除全选外的所有选项值
    const otherValues = options.slice(1).map(opt => opt.value);
    // 检查是否选中了所有其他选项
    const allOtherSelected = otherValues.every(val => newVal.includes(val));
    // 检查是否点击了全选
    const allSelectedNow = newVal.includes('1');
    const allSelectedBefore = oldVal.includes('1');

    // 点击了全选选项
    if (allSelectedNow && !allSelectedBefore) {
      value.value = options.map(opt => opt.value);
      return;
    }

    // 取消了全选选项
    if (!allSelectedNow && allSelectedBefore) {
      // 检查是否所有其他选项都被选中
      const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
      if (allOtherOptionsSelected) {
        // 如果所有其他选项都被选中，取消所有选中状态
        value.value = [];
      } else {
        // 如果不是所有其他选项都被选中，只取消全选选项
        value.value = newVal.filter(val => val !== '1');
      }
      return;
    }
    const someOptionUnselected = oldVal.length > newVal.length;
    if (someOptionUnselected && allSelectedNow) {
      // 如果取消了某个选项且当前处于全选状态，取消全选，但保留其他选项
      value.value = newVal.filter(val => val !== '1');
    }
    // 选中了所有其他选项，自动选中全选
    if (allOtherSelected && !allSelectedNow) {
      value.value = options.map(opt => opt.value);
    }
    // 如果取消了所有选项，清空value
    if (newVal.length === 0) {
      value.value = [];
    }
  },
  { deep: true }
);

// 监听选择框的变化
watch(
  value,
  newValue => {
    // 如果选中了"全选"，显示所有实体
    if (newValue.includes('1')) {
      wallEntities.value.forEach(entity => (entity.show = true));

      // 显示所有图标和标签
      pins.forEach(pin => {
        if (pin.entity) pin.entity.show = true;
        if (pin.labelEntity) pin.labelEntity.show = true;
        if (pin.backgroundEntity) pin.backgroundEntity.show = true;
      });
    } else {
      // 根据选中的选项显示对应实体
      wallEntities.value.forEach(entity => {
        entity.show = newValue.includes('6'); // 越界开采对应电子围栏
      });

      // 根据选中的选项显示对应图标和标签
      pins.forEach(pin => {
        const type = pin.type;
        let shouldShow = false;

        switch (type) {
          case 1: // 人员定位
            shouldShow = newValue.includes('4');
            break;
          case 2: // 车辆定位
            shouldShow = newValue.includes('5');
            break;
          case 3: // 在线监测设备
            shouldShow = newValue.includes('3');
            break;
          case 4: // 视频监控
            shouldShow = newValue.includes('2');
            break;
          default:
            shouldShow = false;
        }

        // 设置图标和标签的显示状态
        if (pin.entity) pin.entity.show = shouldShow;
        if (pin.labelEntity) pin.labelEntity.show = shouldShow;
        if (pin.backgroundEntity) pin.backgroundEntity.show = shouldShow;
      });
    }
  },
  { immediate: true }
);

async function fenceListGet() {
  const res = await getFenceListsApi();

  formData.value = res.data.data;

  for (const item of res.data.data) {
    const positions = item.coordinate.map((item: { xcoordinate: any; ycoordinate: any }) => {
      return [item.xcoordinate, item.ycoordinate];
    });
    const heights: any = [];
    for (const data of item.coordinate) {
      const cartographic = Cesium.Cartographic.fromDegrees(data.xcoordinate, data.ycoordinate);
      const height = await getElevationFromRay(cartographic, viewer);

      heights.push(height);
    }
    electronic(positions, heights, item.rangeType);
  }
}

// 电子围栏
function electronic(position: any, heightData: any, rangeType: any) {
  function map_common_addDatasouce(datasouceName: string) {
    let datasouce = viewer.dataSources._dataSources.find(t => {
      return t && t.name == datasouceName;
    });
    if (!datasouce) {
      datasouce = new Cesium.CustomDataSource(datasouceName);
      viewer.dataSources.add(datasouce);
    }
    return datasouce;
  }

  function DynamicWallMaterialProperty(options: any) {
    this._definitionChanged = new Cesium.Event();
    this._color = undefined;
    this._colorSubscription = undefined;
    this.color = options.color || Color.BLUE;
    this.duration = options.duration || 1000;
    this.trailImage = options.trailImage;
    this._time = new Date().getTime();
  }
  function _getDirectionWallShader(options: any) {
    if (options && options.get) {
      let materail =
        'czm_material czm_getMaterial(czm_materialInput materialInput)\n\
          {\n\
              czm_material material = czm_getDefaultMaterial(materialInput);\n\
              vec2 st = materialInput.st;';
      if (options.freely == 'vertical') {
        // （由下到上）
        materail += `vec4 colorImage = texture(image, vec2(fract(st.s), fract(float(${options.count})*st.t${
          options.direction
        } time)));\n\ `;
      } else {
        // （逆时针）
        materail += `vec4 colorImage = texture(image, vec2(fract(float(${options.count})*st.s ${
          options.direction
        } time), fract(st.t)));\n\ `;
      }
      // 泛光
      materail +=
        'vec4 fragColor;\n\
              fragColor.rgb = (colorImage.rgb+color.rgb) / 1.0;\n\
              fragColor = czm_gammaCorrect(fragColor);\n\
              material.diffuse = colorImage.rgb;\n\
              material.alpha = colorImage.a;\n\
              material.emission = fragColor.rgb;\n\
              return material;\n\
          }';
      return materail;
    }
  }

  Object.defineProperties(DynamicWallMaterialProperty.prototype, {
    isConstant: {
      get() {
        return false;
      }
    },
    definitionChanged: {
      get() {
        return this._definitionChanged;
      }
    },
    color: Cesium.createPropertyDescriptor('color')
  });

  const MaterialType = `wallType${Number.parseInt(Math.random() * 1000)}`;
  DynamicWallMaterialProperty.prototype.getType = function (time) {
    return MaterialType;
  };

  DynamicWallMaterialProperty.prototype.getValue = function (time, result) {
    if (!Cesium.defined(result)) {
      result = {};
    }
    result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
    result.image = this.trailImage;
    if (this.duration) {
      result.time = ((new Date().getTime() - this._time) % this.duration) / this.duration;
    }
    viewer.scene.requestRender();
    return result;
  };

  DynamicWallMaterialProperty.prototype.equals = function (other) {
    return (
      this === other ||
      (other instanceof DynamicWallMaterialProperty && Cesium.Property.equals(this._color, other._color))
    );
  };

  Cesium.Material._materialCache.addMaterial(MaterialType, {
    fabric: {
      type: MaterialType,
      uniforms: {
        color: new Cesium.Color(1.0, 0.0, 0.0, 0.1),
        image: Cesium.Material.DefaultImageId,
        time: -20
      },
      source: _getDirectionWallShader({
        get: true,
        count: 3.0,
        freely: 'vertical',
        direction: '-'
      })
    },
    translucent(material) {
      return true;
    }
  });
  Cesium.DynamicWallMaterialProperty = DynamicWallMaterialProperty;

  function loadWall() {
    position.push(position[0]);
    heightData.push(heightData[0]);

    const data = position.map((item: any) => {
      return item;
    });
    const heightMax = heightData.map((item: any) => {
      return item;
    });

    const coor = Array.prototype.concat.apply([], data);

    const minHeightList = heightMax.map((item: any) => {
      return item + 30;
    });

    datasouce.value = map_common_addDatasouce('wall');

    if (fence.value) {
      if (treeFence.value.length > 0) {
        for (const item of treeFence.value) {
          datasouce.value.entities.remove(item);
        }
      }
    }

    if (rangeType == 1) {
      fenceData.value = {
        imagePath: '/src/assets/wallss.png',
        imageColor: 'Cesium.Color.ORANGE'
      };
    } else if (rangeType == 2) {
      fenceData.value = {
        imagePath: '/src/assets/walls.png',
        imageColor: 'Cesium.Color.CYAN'
      };
    } else {
      fenceData.value = {
        imagePath: '/src/assets/wallsRed.png',
        imageColor: 'Cesium.Color.RED'
      };
    }

    const entity = datasouce.value.entities.add({
      wall: {
        positions: Cesium.Cartesian3.fromDegreesArray(coor),
        maximumHeights: heightMax,
        minimumHeights: minHeightList,
        material: new Cesium.DynamicWallMaterialProperty({
          trailImage: fenceData.value.imagePath,
          color: fenceData.value.imageColor,
          duration: 1500
        })
      }
    });

    wallEntities.value.push(entity);
    // 保存围栏数据用于边界检测
    window.fenceData = position;
  }
  loadWall();
}

// 点击弹框隐藏
function videosShow() {
  if (videoShow.value == true) {
    videoShow.value = false;
    iconShow();
  }
}
function equipmentsShow() {
  if (equipmentShow.value == true) {
    equipmentShow.value = false;
    iconShow();
  }
}
function carsShow() {
  if (carShow.value == true) {
    carShow.value = false;
    iconShow();
  }
}
function personsShow() {
  if (personShow.value == true) {
    personShow.value = false;
    iconShow();
  }
}

function iconShow() {
  for (const item of pins) {
    if (item.type == 1) {
      item.image = bluePersonIcon;
    } else if (item.type == 2) {
      item.image = blueCarIcon;
    } else if (item.type == 3) {
      item.image = blueBianIcon;
    } else {
      item.image = blueVideoIcon;
    }
  }
  iconPoint(viewer, pins);
}

// 设置员工类型
function getPersonTypeName(type: number): string {
  switch (type) {
    case 1:
      return '员工';
    case 2:
      return '访客';
    default:
      return '没有该类型';
  }
}

async function setTimePerson() {
  const res = await getPointAllPersonApi();
  for (const item of pins) {
    const pin = res.data.data.find((personData: any) => personData.cardId == item.id);
    if (pin) {
      personShow.value = false;
      item.image = bluePersonIcon;
      item.position = {
        lon: pin.lon,
        lat: pin.lat
      };
    }
  }
  const carRes = await getCarPointAllCarApi();
  for (const item of pins) {
    const pin = carRes.data.data.find((carData: any) => carData.carNumber == item.id);
    if (pin) {
      carShow.value = false;
      item.image = blueCarIcon;
      item.position = {
        lon: pin.lon,
        lat: pin.lat
      };
    }
  }
  iconPoint(viewer, pins);
}
setInterval(setTimePerson, 2 * 60 * 1000);

onMounted(async () => {
  add3dtiles();
  setTimeout(async () => {
    fenceListGet();

    const res = await getPointAllPersonApi();
    const personData = res.data.data;
    personData.map(item => {
      pins.push({
        id: item.cardId,
        name: item.realName,
        type: 1,
        image: bluePersonIcon,
        position: {
          lon: item.lon,
          lat: item.lat
        },
        data: item,
        entity: null
      });
    });

    // 获取并显示车辆数据，使用不同的前缀
    const resCar = await getCarPointAllCarApi();
    const carData = resCar.data.data;
    carData.map(item => {
      pins.push({
        id: item.carNumber,
        name: item.carNumber,
        type: 2,
        image: blueCarIcon,
        position: {
          lon: item.lon,
          lat: item.lat
        },
        data: item,
        entity: null
      });
    });

    // 获取在线监测
    const resPoint = await getMonitorPointApi();
    const pointData = resPoint.data.data;
    pointData.map(item => {
      pins.push({
        id: item.id,
        type: 3,
        name: item.equipname,
        image: blueBianIcon,
        position: {
          lon: item.longitude,
          lat: item.latitude
        },
        data: item,
        entity: null,
        label: null
      });
    });

    // 获取视频监控信息
    const resVideo = await getCemeraPointApi();
    const videoData = resVideo.data.data;
    videoData.map(item => {
      pins.push({
        id: item.id,
        name: item.cameraName,
        type: 4,
        image: blueVideoIcon,
        position: {
          lon: item.lon,
          lat: item.lat
        },
        data: item,
        entity: null
      });
    });

    iconPoint(viewer, pins).then(result => {
      console.log(result);
    });
  }, 2000);
  // setTimePerson();

  setRemUnit();
  // 监听窗口大小变化
  window.addEventListener('resize', setRemUnit);

  // zhaojunbao 结束

  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  handler.setInputAction(async function (click: any) {
    const pickedObject = viewer.scene.pick(click.position);

    for (const item of pins) {
      if (item.type == 1) {
        item.image = bluePersonIcon;
      } else if (item.type == 2) {
        item.image = blueCarIcon;
      } else if (item.type == 3) {
        item.image = blueBianIcon;
      } else {
        item.image = blueVideoIcon;
      }
    }

    if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
      const pin = pins.find(item => item.entity === pickedObject.id);

      if (pin.type == 1) {
        equipmentShow.value = false;
        videoShow.value = false;
        carShow.value = false;
        personShow.value = true;
        labelData.value = pin.data;

        pin.image = redPersonIcon;
      } else if (pin.type == 2) {
        // 车
        equipmentShow.value = false;
        videoShow.value = false;
        personShow.value = false;
        carShow.value = true;
        const res = await getHomeCarApi(pin.id);
        console.log(res);

        if (res.data.code == 200) {
          speed = res.data.data.point ? carSpeed(res.data.data) : 0;
          labelData.value = res.data.data;
          link = `${labelData.value.ipAddress}?lang=zh&devIdno=${labelData.value.cameraNo}&account=${labelData.value.username}&password=${labelData.value.password}&channel=1`;
        }

        pin.image = redCarIcon;
      } else if (pin.type == 3) {
        // 监测设备
        videoShow.value = false;
        carShow.value = false;
        personShow.value = false;
        equipmentShow.value = true;
        const res = await getMonitorIdApi(pin.id);
        if (res.data.code == 200) {
          if (res.data.data.devicetype == 3) {
            text = '表面位移';
          } else if (res.data.data.devicetype == 6) {
            text = '降雨量';
          }
          labelData.value = res.data.data;
        }

        pin.image = redBianIcon;
      } else {
        // 摄像头
        equipmentShow.value = false;
        videoShow.value = true;
        carShow.value = false;
        personShow.value = false;
        videoShow.value = true;
        const res = await getCameraIdApi(pin.id);
        if (res.data.code == 200) {
          labelData.value = res.data.data;
          console.log(labelData.value);
          const webRtcServrce = ref();
          nextTick(() => {
            webRtcServrce.value = new WebRtcStreamer('video', `${location.protocol}//` + `192.168.2.53:8000`);
            webRtcServrce.value.connect(res.data.data.videoStream);
          });
        }

        pin.image = redVideoIcon;
      }
      iconPoint(viewer, pins);
    } else {
      equipmentShow.value = false;
      videoShow.value = false;
      carShow.value = false;
      personShow.value = false;

      iconPoint(viewer, pins);
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});

onUnmounted(() => {
  // 清理Cesium资源
  if (viewer) {
    viewer.destroy();
    viewer = null;
  }

  // 移除窗口大小变化监听
  window.removeEventListener('resize', setRemUnit);

  // 移除html元素style属性中的font-size
  document.documentElement.style.fontSize = '';
});
</script>

<template>
  <div class="wrapper">
    <div class="top-toolbar">
      <div class="baojing">
        声光报警
        <NSwitch v-model:value="active" />
      </div>

      <!-- <i class="split-line"></i> -->
      <div class="split-line"></div>
      <div class="houtaiguanli" @click="navTo">后台管理</div>
    </div>
    <!-- cesium 容器 -->
    <div class="cesium-container">
      <div id="cesiumContainer">
        <!-- 选择框 -->
        <MultiSelect v-model="value" :options="options" style="position: fixed; z-index: 999; top: 100px; left: 63%" />
        <!-- 人员信息弹框 -->
        <div v-if="personShow == true" class="personMessage">
          <div style="display: flex; justify-content: flex-start; align-items: center; margin-bottom: 10px">
            <div style="width: 90%; margin: 0; font-size: 16px">
              <span>人员信息</span>
              <div class="person1"></div>
            </div>

            <button
              id="close-info"
              style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
              @click="personsShow()"
            >
              &times;
            </button>
          </div>
          <div style="line-height: 1.8">
            <p class="title1">
              <strong class="title2">姓名:</strong>
              {{ labelData.realName }}
            </p>
            <p class="title1">
              <strong class="title2">定位卡号:</strong>
              {{ labelData.cardId }}
            </p>
            <p class="title1">
              <strong class="title2">人员类型:</strong>
              {{ getPersonTypeName(labelData.personType) }}
            </p>
            <p class="title1">
              <strong class="title2">电话:</strong>
              {{ labelData.phone }}
            </p>
            <p class="title1">
              <strong class="title2">部门:</strong>
              {{ labelData.deptName }}
            </p>
          </div>
        </div>
        <!-- 车辆信息 -->
        <div v-if="carShow == true" class="carMessage">
          <div style="display: flex; justify-content: flex-start; align-items: center; margin-bottom: 10px">
            <div style="width: 90%; margin: 0; font-size: 16px">
              <span>车辆信息</span>
              <div class="person1"></div>
            </div>
            <button
              id="close-info"
              style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
              @click="carsShow()"
            >
              &times;
            </button>
          </div>
          <div style="line-height: 1.8; display: flex; justify-content: space-between">
            <div class="car-left">
              <div class="left-top">
                <p class="title1">
                  <strong class="title2">车牌号:</strong>
                  {{ labelData.carNumber || '暂无数据' }}
                </p>
                <p class="title1">
                  <strong class="title2">车队名称:</strong>
                  {{ labelData.teamName || '暂无数据' }}
                </p>
                <p class="title1">
                  <strong class="title2">当前车速:</strong>
                  {{ speed }} km/h
                </p>
                <p class="title1">
                  <strong class="title2">车辆类型:</strong>
                  {{ labelData.carType || '暂无数据' }}
                </p>
              </div>
              <div class="left-center"></div>
              <div class="left-bottom">
                <p class="title1">
                  <strong class="title2">司机姓名:</strong>
                  {{ labelData.driverName || '暂无数据' }}
                </p>
                <p class="title1">
                  <strong class="title2">工作开始时间:</strong>
                  {{ labelData.workStartTime || '暂无数据' }}
                </p>
                <p class="title1">
                  <strong class="title2">工作时长:</strong>
                  {{ labelData.workTime || '暂无数据' }}
                </p>
                <p class="title1">
                  <strong class="title2">终端设备编号:</strong>
                  {{ labelData.terminalNumber || '暂无数据' }}
                </p>
              </div>
            </div>
            <div class="car-right">
              <iframe
                allowfullscreen="true"
                allowtransparency="true"
                allow="autoplay"
                scrolling="no"
                :src="link"
                width="100%"
                height="100%"
                frameborder="0"
                style="padding-right: 20px"
              ></iframe>
              <!-- '${res.ipAddress}?lang=zh&devIdno=${res.cameraNo}&account=${res.username}&password=${res.password}&channel=1' -->
            </div>
          </div>
        </div>
        <!-- 在线检测设备信息 -->
        <div v-if="equipmentShow == true" class="equipmentMessage">
          <div style="display: flex; justify-content: flex-start; align-items: center; margin-bottom: 10px">
            <div style="width: 90%; margin: 0; font-size: 16px">
              <span>在线检测设备信息</span>
              <div class="person1"></div>
            </div>
            <button
              id="close-info"
              style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
              @click="equipmentsShow()"
            >
              &times;
            </button>
          </div>
          <div style="line-height: 1.8">
            <p class="title1">
              <strong class="title2">设备名称:</strong>
              {{ labelData.equipname }}
            </p>
            <p class="title1">
              <strong class="title2">设备状态:</strong>
              {{ labelData.dataStatus === 0 ? '在线' : '离线' }}
            </p>
            <p class="title1">
              <strong class="title2">设备类型:</strong>
              {{ text }}
            </p>
            <p class="title1">
              <strong class="title2">监测值:</strong>
              {{ labelData.value }}
            </p>
            <p class="title1">
              <strong class="title2">监测时间:</strong>
              {{ labelData.time }}
            </p>
            <p class="title1">
              <strong class="title2">数据状态:</strong>
              {{ labelData.onlineStatus === 0 ? '正常' : '蓝色报警' }}
            </p>
          </div>
        </div>
        <!-- 视频监控信息 -->
        <div v-if="videoShow == true" class="videoMessage">
          <div style="display: flex; justify-content: flex-start; align-items: center; margin-bottom: 10px">
            <div style="width: 90%; margin: 0; font-size: 16px">
              <span>视频监控信息</span>
              <div class="person1"></div>
            </div>
            <button
              id="close-info"
              style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
              @click="videosShow()"
            >
              &times;
            </button>
          </div>
          <div style="line-height: 1.8; display: flex; flex-direction: column; flex-wrap: nowrap">
            <div class="video-top">
              <div class="title3">
                <strong class="title2">● 摄像头名称:</strong>
                {{ labelData.areaName }}
              </div>
              <div class="title3">
                <strong class="title4">● 区域名称:</strong>
                {{ labelData.cameraName }}
              </div>
              <div class="title3">
                <strong class="title4">● 设备状态:</strong>
                {{ labelData.status === 0 ? '在线' : '离线' }}
              </div>
            </div>
            <div class="video-bottom">
              <video
                id="video"
                controls
                autoplay
                muted
                playsinline
                width="100%"
                height="100%"
                style="object-fit: fill; z-index: 1"
              ></video>
            </div>
          </div>
        </div>
        <!-- </div> -->
      </div>
    </div>
  </div>

  <div class="top">
    <div class="first-image">
      <img src="@/assets/jinrun/top.png" alt="" srcset="" />
      <div class="second-icon">
        <img src="@/assets/jinrun/title.png" alt="" />
      </div>
    </div>
  </div>
  <div class="bottom"></div>
  <div v-show="isLeftModulesVisible" class="left"></div>
  <div v-show="isRightModulesVisible" class="right"></div>

  <!-- 非cesium相关 开始 -->

  <!-- 左侧收起按钮 -->
  <div class="toggle-btn left-toggle" :class="{ collapsed: !isLeftModulesVisible }" @click="toggleBothModules">
    <div class="btn-arrow1">
      <div>
        <img :src="isLeftModulesVisible ? arrowLeftImg : arrowRightImg" alt="" srcset="" />
        <br />
        <div class="arrow-font">
          {{ isLeftModulesVisible ? '收起' : '展开' }}
        </div>
      </div>
    </div>
  </div>

  <!-- 右侧收起按钮 -->
  <div class="toggle-btn right-toggle" :class="{ collapsed: !isRightModulesVisible }" @click="toggleBothModules">
    <!-- <div class="btn-arrow1"><img src="@/assets/jinrun/arrow-right.png" alt="" srcset=""><br>收<br>起</div> -->
    <div class="btn-arrow1">
      <div>
        <img :src="isLeftModulesVisible ? arrowRightImg : arrowLeftImg" alt="" srcset="" />
        <br />
        <div class="arrow-font">
          {{ isLeftModulesVisible ? '收起' : '展开' }}
        </div>
      </div>
    </div>
  </div>

  <!-- 左侧模块容器 -->
  <Transition name="slide-left">
    <div v-show="isLeftModulesVisible" class="left-modules">
      <LeftDeviceStatus />
      <LeftRainfallTrend />
      <LeftOnlineMonitor />
    </div>
  </Transition>

  <!-- 右侧模块容器 -->
  <Transition name="slide-right">
    <div v-show="isRightModulesVisible" class="right-modules">
      <RightAiWarning />
      <RightEnvMonitor />
      <RightTodayAlarm />
    </div>
  </Transition>
  <!-- 非cesium相关 结束 -->
</template>

<style scoped>
html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.cesium-container {
  width: 100%;
  height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
}

#cesiumContainer {
  width: 100%;
  height: 100%;
}

.personMessage {
  width: 450px;
  height: 250px;
  position: absolute;
  padding: 15px 20px;
  color: white;
  font-family: sans-serif;
  font-size: 14px;
  pointer-events: auto;
  z-index: 9999;
  top: 100px;
  left: 20%;
  background-image: url('@/assets/person2.png');
  background-size: 100% 100%;
  transform: translate(50%, 50%);
}

.carMessage {
  width: 600px;
  height: 380px;
  position: absolute;
  padding: 15px 20px;
  color: white;
  font-family: sans-serif;
  font-size: 14px;
  pointer-events: auto;
  z-index: 9999;
  top: 100px;
  left: 20%;
  background-image: url('@/assets/person2.png');
  background-size: 100% 100%;
  transform: translate(50%, 50%);
}

.equipmentMessage {
  width: 450px;
  height: 290px;
  position: absolute;
  padding: 15px 20px;
  color: white;
  font-family: sans-serif;
  font-size: 14px;
  pointer-events: auto;
  z-index: 9999;
  top: 100px;
  left: 20%;
  background-image: url('@/assets/person2.png');
  background-size: 100% 100%;
  transform: translate(50%, 50%);
}

.videoMessage {
  width: 680px;
  height: 380px;
  position: absolute;
  padding: 15px 20px;
  color: white;
  font-family: sans-serif;
  font-size: 14px;
  pointer-events: auto;
  z-index: 9999;
  top: 100px;
  left: 20%;
  background-image: url('@/assets/person2.png');
  background-size: 100% 100%;
  transform: translate(50%, 50%);
}

.title1 {
  margin-top: 5px;
}

.title2 {
  color: #29d7fb;
  margin-right: 10px;
}

.title3 {
  display: flex;
  align-items: center;
  margin: 0px 0px 8px 0px;
}

.title4 {
  color: #29d7fb;
  margin-right: 10px;
  margin-left: 20px;
}

span {
  position: absolute;
  z-index: 4;
  left: 30px;
  top: 10px;
}

.person1 {
  width: 85%;
  height: 40px;
  background-image: url('@/assets/person1.png');
  background-size: 100% 100%;
  position: absolute;
  left: 6px;
  top: 20px;
}

.left-center {
  width: 100%;
  height: 10px;
  border-bottom: 1px solid #147f9c;
}

.right {
  width: 60%;
  height: 50%;
  /* margin-right: 20px; */
  /* margin-top: 20px; */
}

#video {
  height: 250px;
}

.video-top {
  width: 100%;
  height: 50%;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
}

.video-bottom {
  margin-right: 20px;
}

.select {
  width: 100%;
  border: none;
  background-image: url('@/assets/multiple-pop.png');
}

.n-select {
  background-image: url('@/assets/multiple-pop.png');
  background-position: center;
}

.n-select .n-select-trigger {
  background-color: transparent;
}

.n-select .n-select-menu {
  background-color: transparent;
}

:deep(.n-base-selection .n-base-selection-tags) {
  background-color: transparent !important;
}

:deep(.n-base-selection .n-base-selection-label .n-base-selection-input .n-base-selection-input__content) {
  color: white !important;
}

:deep(.n-base-selection .n-base-selection__border, .n-base-selection .n-base-selection__state-border) {
  border: 1px solid #4ab9fd;
}

:deep(.n-tag) {
  color: #fff;
  background: #10273e00;
  /* display:none; */
}

:deep(.n-tag .n-tag__border) {
  border: none;
}

:deep(.n-base-selection-tag-wrapper) {
  background: #10273e00;
}

/* zhaojunbao  */
.top-toolbar {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 240px;
  height: 0.4rem;
  color: #11e0ff;
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: space-between;

  .split-line {
    width: 0.03rem;
    height: 100%;
    background: #11e0ff;
  }

  .baojing {
    position: relative;
    padding-left: 25px;
    display: block;

    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      width: 20px;
      height: 20px;
      background-image: url('@/assets/jinrun/baojing.png');
      background-size: contain;
      background-repeat: no-repeat;
    }
  }

  .houtaiguanli {
    position: relative;
    padding-left: 25px;
    display: block;

    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      width: 20px;
      height: 20px;
      background-image: url('@/assets/jinrun/houtai.png');
      background-size: contain;
      background-repeat: no-repeat;
    }
  }
}

.top,
.bottom,
.left,
.right {
  position: absolute;
  background-repeat: no-repeat;
}

.top {
  top: 0;
  width: 100%;
  height: 1.25rem;
  position: absolute;

  .first-image {
    width: 100%;
    height: 100%;
    position: relative;

    & > img {
      width: 100%;
    }

    .second-icon {
      position: absolute;
      top: 30%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 5.04rem;
      /* 可根据实际需要调整大小 */
      height: 0.54rem;
      /* 可根据实际需要调整大小 */
    }
  }
}

.bottom {
  bottom: 0;
  left: 0;
  width: 100%;
  height: 0.4rem;
  background-image: url('@/assets/jinrun/bottom.png');
  background-size: cover;
}

.left {
  top: 0rem;
  left: 0;
  width: 5.76rem;
  height: calc(100vh);
  background-size: contain;
  background-position-x: left;
  background-image: url('@/assets/jinrun/bg-left.png');
}

.right {
  top: 0rem;
  right: 0;
  width: 5.76rem;
  height: calc(100vh);
  background-image: url('@/assets/jinrun/bg-right.png');
  background-size: contain;
  background-position-x: right;
}

.toggle-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 0.71rem;
  height: 1.87rem;
  background-image: url('@/assets/jinrun/toggle-left.png');
  background-size: cover;
  background-repeat: no-repeat;
  border-radius: 0 10px 10px 0;
  cursor: pointer;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;

  &.left-toggle {
    left: 5rem;
    /* 与左侧模块宽度一致 */
    background-image: url('@/assets/jinrun/toggle-left.png');
  }

  &.left-toggle:hover {
    background-image: url('@/assets/jinrun/toggle-left_click.png');
  }

  &.right-toggle {
    right: 5rem;
    /* 与左侧模块宽度一致 */
    background-image: url('@/assets/jinrun/toggle-right.png');
  }

  &.right-toggle:hover {
    background-image: url('@/assets/jinrun/toggle-right_click.png');
  }

  &.collapsed {
    &.left-toggle {
      left: 0.55rem;
      border-radius: 0 10px 10px 0;
    }

    &.right-toggle {
      right: 0.55rem;
      border-radius: 10px 0 0 10px;
    }
  }

  .btn-arrow1 {
    img {
      width: 0.18rem;
    }
  }

  .btn-arrow {
    width: 10px;
    height: 10px;
    border-top: 2px solid #fff;
    border-right: 2px solid #fff;
    transition: transform 0.3s ease;

    &::before {
      content: '';
      position: absolute;
      width: 2px;
      height: 10px;
      background: #fff;
      top: -4px;
      right: 4px;
    }
  }

  &.left-toggle .btn-arrow {
    transform: rotate(135deg);
  }

  &.right-toggle .btn-arrow {
    transform: rotate(-45deg);
  }

  &.collapsed {
    &.left-toggle .btn-arrow {
      transform: rotate(-45deg);
    }

    &.right-toggle .btn-arrow {
      transform: rotate(135deg);
    }
  }

  &:hover {
  }
}

.slide-left-enter-active,
.slide-left-leave-active {
  transition:
    transform 0.5s ease,
    opacity 0.5s ease;
}

.slide-left-enter-from {
  transform: translateX(-100%);
  opacity: 0;
}

.slide-left-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}

.slide-right-enter-active,
.slide-right-leave-active {
  transition:
    transform 0.5s ease,
    opacity 0.5s ease;
}

.slide-right-enter-from {
  transform: translateX(100%);
  opacity: 0;
}

.slide-right-leave-to {
  transform: translateX(100%);
  opacity: 0;
}

.left-modules:not(.v-enter-active):not(.v-leave-active).left-toggle:not(.collapsed) {
  left: 0;
  border-radius: 0 10px 10px 0;
}

.right-modules:not(.v-enter-active):not(.v-leave-active).right-toggle:not(.collapsed) {
  right: 0;
  border-radius: 10px 0 0 10px;
  background: pink;
}

.left-modules,
.right-modules {
  width: 4.6rem;
  padding-top: 0.95rem;
  position: absolute;
}

.left-modules {
  left: 0;
  margin-left: 0.4rem;
}

.right-modules {
  right: 0;
  margin-right: 0.4rem;
}

.arrow-font {
  width: 20px;
  color: #fff;
  font-size: 0.18rem;
  display: flex;
  flex-direction: column;
}

.video-container {
  width: 100%;
  height: 250px;
  border: 1px solid #ccc;
  background: #f5f5f5;
  position: relative;
}

#divPlugin {
  width: 100%;
  height: 100%;
}

.status-info {
  position: absolute;
  top: 10px;
  right: 10px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
}
</style>
