dedsudiyu 1 ay önce
ebeveyn
işleme
7aabd774a9

BIN
public/models/BxiaoQu.glb


BIN
public/models/NxiaoQu.glb


BIN
public/models/demo_b.glb


BIN
public/models/demo_n.glb


+ 931 - 0
src/views/cengterMaxBox/canvasMap/newIndex.vue

@@ -0,0 +1,931 @@
+<!-- 模型地图 -->
+<template>
+  <div>
+    <div class="canvasMap" ref="container"></div>
+  </div>
+</template>
+
+<script>
+  import * as THREE from 'three';
+  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
+  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
+  import TWEEN from 'tween.js';
+  import { CSS2DRenderer, CSS2DObject, } from "three/examples/jsm/renderers/CSS2DRenderer";
+  export default {
+    data() {
+      return {
+        animationId: null,  // 存储动画帧ID
+        model:null,
+        rotateType:true,
+        subModels: [],
+        houses:[],
+        textures: [], // 预加载的贴图选项
+        scene: null,
+        camera: null,
+        renderer: null,
+        controls: null,
+        labelRenderer:null,
+        // initialCameraPosition: new THREE.Vector3(0.265357272970017,1.0753467424793826,0.29965000584249346),//旋转-距离-俯角
+        initialCameraPosition: new THREE.Vector3(0.5,0.60,0.5),//旋转-距离-俯角
+        /*
+        {"x":0.2509298883560245,"y":1.2088432847403026,"z":0.19985043873282318}
+        {"x":0.265357272970017,"y":1.0753467424793826,"z":0.29965000584249346}
+        */
+        initialControlsTarget: new THREE.Vector3(0, 0, 0),
+        /*本地管理数据*/
+        modelBuildingList:[
+          {school:'B',	name:'5号楼',	buildId:'101093843117592833',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'6B教学楼',	buildId:'101093843117592815',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'中心实验楼',	buildId:'101093843117592829',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'信息工程学院教学楼',	buildId:'101093843117592812',centerValue:'101093843117592812',valueList:['101093843117592812'],alarmType:false,},
+          {school:'B',	name:'养虫楼',	buildId:'101093843117592805',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'农业机械实验室平房',	buildId:'101093843117592807',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'农药研究所',	buildId:'101093843117592804',centerValue:'101093843117592804',valueList:['101093843117592804'],alarmType:false,},
+          {school:'B',	name:'动物中心B座',	buildId:'101093843117592785',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'动物中心实验楼A',	buildId:'101093843117592765',centerValue:'101093843117592765',valueList:['101093843117592765'],alarmType:false,},
+          {school:'B',	name:'动物中心实验楼B',	buildId:'101093843117592764',centerValue:'101093843117592764',valueList:['101093843117592764'],alarmType:false,},
+          {school:'B',	name:'动物科技学院楼',	buildId:'101093843117592831',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'动科楼',	buildId:'101093843117592832',centerValue:'101093843117592832',valueList:['101093843117592832'],alarmType:false,},
+          {school:'B',	name:'北1号教学楼',	buildId:'101093843117592802',centerValue:'101093843117592802',valueList:['101093843117592802'],alarmType:false,},
+          {school:'B',	name:'北2号教学楼',	buildId:'101093843117592813',centerValue:'101093843117592813',valueList:['101093843117592813'],alarmType:false,},
+          {school:'B',	name:'北3号教学楼',	buildId:'101093843117592782',centerValue:'101093843117592782',valueList:['101093843117592782'],alarmType:false,},
+          {school:'B',	name:'北4号教学楼',	buildId:'101093843117592781',centerValue:'101093843117592781',valueList:['101093843117592781'],alarmType:false,},
+          {school:'B',	name:'北5号教学楼',	buildId:'101093843117592783',centerValue:'101093843117592833',valueList:['101093843117592833'],alarmType:false,},
+          {school:'B',	name:'北6号教学楼',	buildId:'101093843117592814',centerValue:'101093843117592814',valueList:['101093843117592814'],alarmType:false,},
+          {school:'B',	name:'北7号教学楼',	buildId:'101093843117592816',centerValue:'101093843117592816',valueList:['101093843117592816'],alarmType:false,},
+          {school:'B',	name:'危化品服务中心',	buildId:'101093843117592826',centerValue:'101093843117592826-03',valueList:['101093843117592826-01','101093843117592826-02','101093843117592826-03','101093843117592826-04','101093843117592826-05'],alarmType:false,},
+          {school:'B',	name:'原农一站办公楼',	buildId:'101093843117592811',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'工程训练中心楼',	buildId:'101093843117592808',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'教学办公楼',	buildId:'101093843117592806',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'未知实验室	',buildId:'1855791848753147906',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'机械及液压实验室平房',	buildId:'101093843117592810',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'机电锻铸车间',	buildId:'101093843117592809',centerValue:'101093843117592809',valueList:['101093843117592809'],alarmType:false,},
+          {school:'B',	name:'水利与建筑工程学院',	buildId:'101093843117592788',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'水利与建筑工程学院A',	buildId:'101093843117592766',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'水利与建筑工程学院B',	buildId:'101093843117592768',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'水利与建筑工程学院C',	buildId:'101093843117592769',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'水利与建筑工程学院D',	buildId:'101093843117592767',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'水工厅', buildId:'1871736666456633346',centerValue:'1871736666456633346',valueList:['1871736666456633346'],alarmType:false,},
+          {school:'B',	name:'水工水力学实验大厅', buildId:'1871729400227606529',centerValue:'1871729400227606529-01',valueList:['1871729400227606529-01','1871729400227606529-02'],alarmType:false,},
+          {school:'B',	name:'理科综合实验楼A',	buildId:'101093843117592774',centerValue:'101093843117592774',valueList:['101093843117592774'],alarmType:false,},
+          {school:'B',	name:'理科综合实验楼B',	buildId:'101093843117592779',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'理科综合实验楼C',	buildId:'101093843117592775',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'理科综合实验楼D',	buildId:'101093843117592776',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'理科综合实验楼E',	buildId:'101093843117592780',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'老昆虫博物馆',	buildId:'101093843117592786',centerValue:'101093843117592786',valueList:['101093843117592786'],alarmType:false,},
+          {school:'B',	name:'食品楼',	buildId:'101093843117592789',centerValue:'101093843117592789',valueList:['101093843117592789'],alarmType:false,},
+          {school:'B',	name:'食品楼A',	buildId:'101093843117592771',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'食品楼B',	buildId:'101093843117592770',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'食品楼C',	buildId:'101093843117592772',centerValue:'',valueList:[],alarmType:false,},
+          {school:'B',	name:'食品楼D',	buildId:'101093843117592773',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'农科楼(农学院)',	buildId:'101084081109864872',centerValue:'101084081109864872',valueList:['101084081109864872'],alarmType:false,},
+          {school:'N',	name:'农科楼(园艺学院)',	buildId:'101084081109864874',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'农科楼(植物保护学院)',	buildId:'101084081109864873',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'农科楼(资源环境学院)',	buildId:'101093843117592803',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'农科院子校教学楼(初中)',	buildId:'101093843117592823',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'南2号教学楼',	buildId:'101093843117592817',centerValue:'101093843117592817',valueList:['101093843117592817'],alarmType:false,},
+          {school:'N',	name:'南3号教学楼',	buildId:'101093843117592820',centerValue:'101093843117592820',valueList:['101093843117592820'],alarmType:false,},
+          {school:'N',	name:'南校子校楼',	buildId:'101093843117592800',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'南校水保楼',	buildId:'101093843117592801',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'家畜生物学重点实验室楼',	buildId:'101093843117592787',centerValue:'101093843117592787',valueList:['101093843117592787'],alarmType:false,},
+          {school:'N',	name:'木艺坊',	buildId:'101093843117592819',centerValue:'101093843117592819',valueList:['101093843117592819'],alarmType:false,},
+          {school:'N',	name:'林学院实验楼',	buildId:'101093843117592818',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'科研主楼',	buildId:'101093843117592784',centerValue:'101093843117592784',valueList:['101093843117592784'],alarmType:false,},
+          {school:'N',	name:'科研楼',	buildId:'101093843117592822',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'经管园林楼(文科楼)A',	buildId:'101093843117592777',centerValue:'101093843117592777',valueList:['101093843117592777'],alarmType:false,},
+          {school:'N',	name:'经管园林楼(文科楼)C',	buildId:'101093843117592778',centerValue:'',valueList:[],alarmType:false,},
+          {school:'N',	name:'草业与草原楼',	buildId:'101093843117592825',centerValue:'101093843117592825',valueList:['101093843117592825'],alarmType:false,},
+          {school:'N',	name:'林学院实验楼',	buildId:'101093843117592821',centerValue:'101093843117592821',valueList:['101093843117592821'],alarmType:false,},
+          {school:'旱研院校区',	name:'农一站科研楼',	buildId:'101093843117592827',centerValue:'',valueList:[],alarmType:false,},
+          {school:'旱研院校区',	name:'农机一站平房',	buildId:'101093843117592828',centerValue:'',valueList:[],alarmType:false,},
+          {school:'校外',	name:'农三站科研办公楼',	buildId:'101093843117592790',centerValue:'',valueList:[],alarmType:false,},
+          {school:'校外',	name:'器材楼',	buildId:'101093843117592792',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'人工降雨实验大厅',	buildId:'101093843117592793',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'南校区农科楼',	buildId:'101093843117592799',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'国家重点实验室西楼',	buildId:'101093843117592798',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'水保所人工干旱环境气候室工程',	buildId:'101093843117592795',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'水保所国家重点实验室楼',	buildId:'101093843117592794',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'水保所科研大楼',	buildId:'101093843117592797',centerValue:'',valueList:[],alarmType:false,},
+          {school:'水保所校区',	name:'水保所西区科研楼',	buildId:'101093843117592796',centerValue:'',valueList:[],alarmType:false,},
+          {school:'老附中校区',	name:'附中实验楼',	buildId:'101093843117592830',centerValue:'',valueList:[],alarmType:false,},
+          {school:'老附中校区',	name:'附中教学楼',	buildId:'101093843117592791',centerValue:'',valueList:[],alarmType:false,},
+        ],
+        // 本地
+        modelsUrlN:'/models/NxiaoQu.glb',
+        modelsUrlB:'/models/BxiaoQu.glb',
+        alarmUrl:'/png/alarm.png',
+        noAlarmUrl:'/png/noAlarm.png',
+        // 本地部署
+        // modelsUrlN:this.judgmentNetworkReturnAddress()?'/v3/largeScreen/models/NxiaoQu.glb':'/labAppTest/largeScreen/models/NxiaoQu.glb',
+        // modelsUrlB:this.judgmentNetworkReturnAddress()?'/v3/largeScreen/models/BxiaoQu.glb':'/labAppTest/largeScreen/models/BxiaoQu.glb',
+        // alarmUrl:this.judgmentNetworkReturnAddress()?'/v3/largeScreen/png/alarm.png':'/labAppTest/largeScreen/png/alarm.png',
+        // noAlarmUrl:this.judgmentNetworkReturnAddress()?'/v3/largeScreen/png/noAlarm.png':'/labAppTest/largeScreen/png/noAlarm.png',
+        // 线上部署
+        // modelsUrlN:'/largeScreen/models/NxiaoQu.glb',
+        // modelsUrlB:'/largeScreen/models/BxiaoQu.glb',
+        // alarmUrl:'/largeScreen/png/alarm.png',
+        // noAlarmUrl:'/largeScreen/png/noAlarm.png',
+        //当前校区状态
+        schoolType:'',
+      };
+    },
+
+    mounted() {
+      this.initThree();
+      this.loadModel('N');
+      this.loadAssets();
+      window.addEventListener('resize', this.onWindowResize);
+    },
+
+    beforeDestroy() {
+      // 停止动画循环
+      if (this.animationId) {
+        cancelAnimationFrame(this.animationId);
+      }
+      // 销毁Three.js相关资源
+      this.disposeThreeResources();
+      // 停止所有补间动画
+      TWEEN.removeAll();
+      // 移除事件监听器
+      window.removeEventListener('resize', this.onWindowResize);
+      this.renderer.dispose();
+    },
+
+    methods: {
+      //初始化
+      initThree() {
+        // 初始化场景
+        this.scene = new THREE.Scene();
+        //场景背景色
+        this.scene.background = new THREE.Color(0x020716);
+        // 初始化渲染器
+        this.renderer = new THREE.WebGLRenderer({ antialias: true });
+        // 主渲染器尺寸设置
+        this.renderer = new THREE.WebGLRenderer({ antialias: true });
+        this.renderer.setSize(5927, 2160);  // 固定尺寸
+        this.$refs.container.appendChild(this.renderer.domElement);
+        // 初始化相机时使用存储的位置
+        this.camera = new THREE.PerspectiveCamera(
+          75,
+          // window.innerWidth / window.innerHeight,
+          5927 / 2160,
+          0.1,
+          1000
+        );
+        this.camera.position.copy(this.initialCameraPosition);
+
+        // 初始化控制器时存储初始目标
+        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
+        this.controls.target.copy(this.initialControlsTarget);
+        this.labelRenderer = new CSS2DRenderer();
+        this.labelRenderer.setSize(5927, 2160);
+        this.labelRenderer.domElement.style.position = 'absolute';
+        this.labelRenderer.domElement.style.top = '0';
+        this.labelRenderer.domElement.style.pointerEvents = 'none';//注释后 锁死鼠标视角
+        this.$refs.container.appendChild(this.labelRenderer.domElement);
+
+        // 初始化控制器
+        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
+        this.controls.enableDamping = true;
+        this.controls.dampingFactor = 0.05;
+
+        // 添加灯光
+        const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
+        this.scene.add(ambientLight);
+
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
+        directionalLight.position.set(-1.5, 2, -1.5);
+        this.scene.add(directionalLight);
+
+        // 启动动画循环
+        this.animate();
+      },
+      //模型加载
+      loadModel(type) {
+        let self = this;
+        this.$set(this,'schoolType',type);
+        if(type == 'N'){
+          //南校区
+          const loaderN = new GLTFLoader();
+          loaderN.load(self.modelsUrlN, (gltf) => {
+            const model = gltf.scene;
+            this.model = gltf.scene;
+            this.scene.add(model);
+            // 递归查找所有Group
+            const traverseGroups = (obj) => {
+              if (obj.isGroup) {
+                this.registerHouse(obj);
+              }
+              obj.children.forEach(child => traverseGroups(child));
+            };
+            traverseGroups(gltf.scene);
+            // 获取所有子模型并计算中心点
+            model.traverse((child) => {
+              if (child.isGroup) {
+                const center = this.getBoundingBoxCenter(child);
+                this.subModels.push({
+                  name: child.name,
+                  center: center,
+                  originalPosition: child.position.clone(),
+                  mesh: child  // 直接引用mesh对象 用于材质修改
+                });
+              }
+            });
+          });
+        }else if(type == 'B'){
+          //北校区
+          const loaderB = new GLTFLoader();
+          loaderB.load(self.modelsUrlB, (gltf) => {
+            const model = gltf.scene;
+            this.model = gltf.scene;
+            this.scene.add(model);
+            // 递归查找所有Group
+            const traverseGroups = (obj) => {
+              if (obj.isGroup) {
+                this.registerHouse(obj);
+              }
+              obj.children.forEach(child => traverseGroups(child));
+            };
+            traverseGroups(gltf.scene);
+            // 获取所有子模型并计算中心点
+            model.traverse((child) => {
+              if (child.isGroup) {
+                const center = this.getBoundingBoxCenter(child);
+                this.subModels.push({
+                  name: child.name,
+                  center: center,
+                  originalPosition: child.position.clone(),
+                  mesh: child  // 直接引用mesh对象 用于材质修改
+                });
+              }
+            });
+          });
+        }
+        setTimeout(function(){
+          self.buildingApplyTexture([]);
+          // self.buildingColor([]);
+        },500);
+      },
+      /****** 新模型相关方法-开始 *******/
+      // 修改后的 registerHouse 方法
+      registerHouse(group) {
+        const bbox = new THREE.Box3().setFromObject(group);
+        const center = bbox.getCenter(new THREE.Vector3());
+
+        // 记录原始材质
+        const originalMaterials = [];
+        group.traverse(child => {
+          if (child.isMesh) {
+            originalMaterials.push({
+              mesh: child,
+              material: child.material.clone() // 重要:必须克隆原始材质
+            });
+          }
+        });
+
+        this.houses.push({
+          name:group.name,
+          uuid: group.uuid,
+          group: group,
+          screenPosition: new THREE.Vector2(),
+          worldPosition: center,
+          originalMaterials: originalMaterials // 新增原始材质存储
+        });
+      },
+      // 预加载材质和贴图
+      loadAssets() {
+        const textureLoader = new THREE.TextureLoader();
+        this.textures = [
+          textureLoader.load('/png/alarm.png')
+        ];
+      },
+      // 报警样式
+      changeTexture(house) {
+        const texture = this.textures[Math.floor(Math.random() * this.textures.length)];
+        texture.needsUpdate = true;
+
+        house.group.traverse(child => {
+          if (child.isMesh) {
+            child.material.map = texture;
+            child.material.needsUpdate = true;
+          }
+        });
+      },
+      // 恢复正常显示
+      restoreOriginalMaterial(house) {
+        house.originalMaterials.forEach(entry => {
+          entry.mesh.material.dispose(); // 清理当前材质
+          entry.mesh.material = entry.material.clone();
+          entry.mesh.material.needsUpdate = true;
+        });
+      },
+      /****** 新模型相关方法-结束 *******/
+
+      getBoundingBoxCenter(obj) {
+        const box = new THREE.Box3().setFromObject(obj);
+        return box.getCenter(new THREE.Vector3());
+      },
+      onWindowResize() {
+        this.camera.aspect = 5927 / 2160;
+        this.camera.updateProjectionMatrix();
+        this.renderer.setSize(5927, 2160);
+        this.labelRenderer.setSize(5927, 2160);
+
+      },
+      //动画刷新
+      animate() {
+        if (this.model&&this.rotateType) {
+          this.model.rotation.y += 0.001; // 添加简单旋转动画
+        }else if(this.model&&!this.rotateType){
+          this.model.rotation.y = 0;
+        }
+        // requestAnimationFrame(this.animate);
+        // TWEEN.update();
+        // this.controls.update();
+        // this.renderer.render(this.scene, this.camera);
+        // this.labelRenderer.render(this.scene, this.camera);
+        this.animationId = requestAnimationFrame(this.animate);
+        TWEEN.update();
+        this.controls.update();
+        this.renderer.render(this.scene, this.camera);
+        this.labelRenderer.render(this.scene, this.camera);
+      },
+      //预案关闭
+      alarmOff(){
+        let self = this;
+        self.$set(this,'rotateType',true)
+        if(this.schoolType == 'N'){
+          self.resetCamera();
+          self.del2dText();
+          // self.buildingColor([]);
+          self.buildingApplyTexture([]);
+        }else{
+          //删除所有文字
+          for(let i=0;i<self.scene.children.length;i++){
+            if(self.scene.children[i].isCSS2DObject){
+              self.scene.remove(self.scene.children[i]);
+              i--
+            }
+          }
+          //删除模型数据
+          this.$set(this,'subModels',[]);
+          this.$set(this,'houses',[]);
+          this.scene.children.forEach((item)=>{
+            if(item.type == 'Group'){
+              this.scene.remove(item);
+            }
+          })
+          self.resetCamera();
+          this.delLoadModel('N');
+        }
+      },
+      // 新增恢复视角方法
+      resetCamera() {
+        this.controls.enabled = false;
+        new TWEEN.Tween(this.camera.position)
+          .to(this.initialCameraPosition, 1500)
+          .easing(TWEEN.Easing.Quadratic.InOut)
+          .start();
+
+        new TWEEN.Tween(this.controls.target)
+          .to(this.initialControlsTarget, 1500)
+          .easing(TWEEN.Easing.Quadratic.InOut)
+          .onComplete(() => {
+            this.controls.enabled = true;
+          })
+          .start();
+        this.del2dText();
+      },
+      //删除所有2d文字
+      del2dText(){
+        let self = this;
+        for(let i=0;i<self.scene.children.length;i++){
+          if(self.scene.children[i].isCSS2DObject){
+            this.scene.remove(self.scene.children[i]);
+            i--
+          }
+        }
+      },
+      //预案触发
+      alarmTrigger(list,obj,type){
+        let self = this;
+        self.$set(this,'rotateType',false)
+        //list=所有报警数据 obj=需要聚焦的报警数据 type=报警的校区
+        if(this.schoolType == type){
+          //当前校区
+          self.buildingApplyTexture(list);
+          // self.buildingColor(list);
+          self.focusingLens(obj);
+          //删除所有文字
+          for(let i=0;i<self.scene.children.length;i++){
+            if(self.scene.children[i].isCSS2DObject){
+              self.scene.remove(self.scene.children[i]);
+              i--
+            }
+          }
+          //生成新文字
+          this.alarmTextLabel(list);
+        }else{
+          //其他校区
+          //删除所有文字
+          for(let i=0;i<self.scene.children.length;i++){
+            if(self.scene.children[i].isCSS2DObject){
+              self.scene.remove(self.scene.children[i]);
+              i--
+            }
+          }
+          //删除模型数据
+          this.$set(this,'subModels',[]);
+          this.$set(this,'houses',[]);
+          this.scene.children.forEach((item)=>{
+            if(item.type == 'Group'){
+              self.scene.remove(item);
+            }
+          })
+          //加载新模型
+          this.newLoadModel(list,obj,type);
+        }
+      },
+      //新模型加载
+      newLoadModel(list,obj,type) {
+        let self = this;
+        this.$set(this,'schoolType',type);
+        if(type == 'N'){
+          //南校区
+          const loaderN = new GLTFLoader();
+          loaderN.load(self.modelsUrlN, (gltf) => {
+            const model = gltf.scene;
+            this.model = gltf.scene;
+            this.scene.add(model);
+            // 递归查找所有Group
+            const traverseGroups = (obj) => {
+              if (obj.isGroup) {
+                this.registerHouse(obj);
+              }
+              obj.children.forEach(child => traverseGroups(child));
+            };
+            traverseGroups(gltf.scene);
+            // 获取所有子模型并计算中心点
+            model.traverse((child) => {
+              if (child.isGroup) {
+                const center = this.getBoundingBoxCenter(child);
+                this.subModels.push({
+                  name: child.name,
+                  center: center,
+                  originalPosition: child.position.clone(),
+                  mesh: child  // 直接引用mesh对象 用于材质修改
+                });
+              }
+            });
+          });
+        }else if(type == 'B'){
+          //北校区
+          const loaderB = new GLTFLoader();
+          loaderB.load(self.modelsUrlB, (gltf) => {
+            const model = gltf.scene;
+            this.model = gltf.scene;
+            this.scene.add(model);
+            // 递归查找所有Group
+            const traverseGroups = (obj) => {
+              if (obj.isGroup) {
+                this.registerHouse(obj);
+              }
+              obj.children.forEach(child => traverseGroups(child));
+            };
+            traverseGroups(gltf.scene);
+            // 获取所有子模型并计算中心点
+            model.traverse((child) => {
+              if (child.isGroup) {
+                const center = this.getBoundingBoxCenter(child);
+                this.subModels.push({
+                  name: child.name,
+                  center: center,
+                  originalPosition: child.position.clone(),
+                  mesh: child  // 直接引用mesh对象 用于材质修改
+                });
+              }
+            });
+          });
+        }
+
+        setTimeout(function(){
+          self.focusingLens(obj);
+          self.buildingApplyTexture(list);
+          // self.buildingColor(list);
+          self.alarmTextLabel(list);
+        },1000);
+      },
+      //预案停止模型加载
+      delLoadModel(type) {
+        let self = this;
+        this.$set(this,'schoolType',type);
+        //南校区
+        const loaderN = new GLTFLoader();
+        loaderN.load(self.modelsUrlN, (gltf) => {
+          const model = gltf.scene;
+          this.model = gltf.scene;
+          this.scene.add(model);
+          // 递归查找所有Group
+          const traverseGroups = (obj) => {
+            if (obj.isGroup) {
+              this.registerHouse(obj);
+            }
+            obj.children.forEach(child => traverseGroups(child));
+          };
+          traverseGroups(gltf.scene);
+          // 获取所有子模型并计算中心点
+          model.traverse((child) => {
+            if (child.isGroup) {
+              const center = this.getBoundingBoxCenter(child);
+              this.subModels.push({
+                name: child.name,
+                center: center,
+                originalPosition: child.position.clone(),
+                mesh: child  // 直接引用mesh对象 用于材质修改
+              });
+            }
+          });
+        });
+        setTimeout(function(){
+          self.buildingApplyTexture([]);
+          // self.buildingColor([]);
+        },1000);
+      },
+      //初始化楼栋标记(报警时调用)
+      buildingColor(list){
+        let self = this;
+        //处理基础数据
+        self.modelBuildingList.forEach((maxItem)=>{
+          let num = 0;
+          list.forEach((item)=>{
+            if(maxItem.buildId == item.buildId){
+              num++
+            }
+          })
+          maxItem.alarmType = num != 0;
+        })
+        //处理预警与正常贴图
+        self.modelBuildingList.forEach((maxItem)=>{
+          maxItem.valueList.forEach((bigItem)=>{
+            this.scene.children.forEach((item)=>{
+              if(item.type == 'Group'){
+                item.children.forEach((minItem)=>{
+                  if(minItem.name == bigItem){
+                    if(maxItem.alarmType){
+                      self.applyTexture(self.alarmUrl,minItem);
+                    }else{
+                      self.applyTexture(self.noAlarmUrl,minItem);
+                    }
+                  }
+                })
+              }
+            })
+          })
+        })
+      },
+      buildingApplyTexture(list){
+        let self = this;
+        //处理基础数据
+        self.modelBuildingList.forEach((maxItem)=>{
+          let num = 0;
+          list.forEach((item)=>{
+            if(maxItem.buildId == item.buildId){
+              num++
+            }
+          })
+          maxItem.alarmType = num != 0;
+        })
+        this.$forceUpdate()
+        //处理预警与正常贴图
+        self.modelBuildingList.forEach((maxItem)=>{
+          maxItem.valueList.forEach((bigItem)=>{
+            self.houses.forEach((minItem)=>{
+              if(minItem.name == bigItem){
+                if(maxItem.alarmType){
+                  self.changeTexture(minItem);
+                }else{
+                  self.restoreOriginalMaterial(minItem);
+                }
+              }
+            })
+          })
+        })
+      },
+      //图片材质替换
+      applyTexture(textureName,obj) {
+        const textureLoader = new THREE.TextureLoader();
+        textureLoader.load(
+          textureName, // 图片放在public目录下
+          (texture) => {
+            texture.flipY = false; // 根据图片格式调整
+            obj.traverse((child) => {
+              if (child.isMesh) {
+                // 释放旧纹理资源
+                if (child.material.map) {
+                  child.material.map.dispose();
+                }
+                child.material.map = texture;
+                child.material.needsUpdate = true;
+              }
+            });
+          },
+          undefined,
+          (error) => {
+            console.error('材质加载失败:', error);
+          }
+        );
+      },
+      //材质方法调用
+      changeMaterial(options) {
+        const {
+          modelSelector,    // 支持三种选择方式:名称(name)/索引(index)/'all'
+          materialParams,   // 新材质参数对象
+          keepOriginal = false // 是否保留原始材质
+        } = options;
+
+        const targetMeshes = this.getTargetMeshes(modelSelector);
+
+        targetMeshes.forEach(mesh => {
+          // 创建新材质
+          const newMaterial = this.createMaterial(materialParams);
+
+          // 处理旧材质
+          if (!keepOriginal && mesh.userData.originalMaterial) {
+            mesh.material.dispose();
+          }
+
+          // 应用新材质
+          mesh.material = newMaterial;
+        });
+      },
+      // 辅助方法:获取目标网格
+      getTargetMeshes(selector) {
+        if (selector === 'all') {
+          return this.subModels.map(m => m.mesh);
+        }
+
+        if (typeof selector === 'number') {
+          return [this.subModels[selector].mesh];
+        }
+
+        if (typeof selector === 'string') {
+          return this.subModels
+            .filter(m => m.name === selector)
+            .map(m => m.mesh);
+        }
+
+        return [];
+      },
+      // 材质工厂方法
+      createMaterial(params) {
+        const type = params.type || 'Standard';
+        const baseParams = {
+          color: new THREE.Color(params.color || 0xffffff),
+          map: params.texture ? this.loadTexture(params.texture) : null,
+          transparent: params.transparent || false,
+          opacity: params.opacity || 1.0,
+          ...params
+        };
+
+        switch(type.toLowerCase()) {
+          case 'basic':
+            return new THREE.MeshBasicMaterial(baseParams);
+          case 'phong':
+            return new THREE.MeshPhongMaterial(baseParams);
+          case 'standard':
+            return new THREE.MeshStandardMaterial(baseParams);
+          case 'physical':
+            return new THREE.MeshPhysicalMaterial(baseParams);
+          default:
+            return new THREE.MeshStandardMaterial(baseParams);
+        }
+      },
+      //聚焦镜头查询
+      focusingLens(obj){
+        let self = this;
+        this.modelBuildingList.forEach((maxItem)=>{
+          if(maxItem.buildId == obj.buildId){
+            self.subModels.forEach((bigItem)=>{
+              if(bigItem.name == maxItem.centerValue){
+                self.moveCameraToModel(bigItem,bigItem.name);
+              }
+            })
+          }
+        })
+      },
+      //镜头聚焦方法
+      moveCameraToModel(model,name) {
+        let self = this;
+        // 禁用控制器
+        this.controls.enabled = false;
+
+        // 计算目标位置(模型中心前上方)
+        const targetPosition = new THREE.Vector3()
+          .copy(model.center)
+          .add(new THREE.Vector3(0.2,0.2, 0.2));
+
+        // 动画参数
+        const duration = 1500;
+        const easing = TWEEN.Easing.Quadratic.InOut;
+
+        // 相机位置动画
+        new TWEEN.Tween(this.camera.position)
+          .to(targetPosition, duration)
+          .easing(easing)
+          .start();
+
+        // 控制器目标点动画
+        new TWEEN.Tween(this.controls.target)
+          .to(model.center, duration)
+          .easing(easing)
+          .onComplete(() => {
+            this.controls.enabled = true; // 恢复控制
+          })
+          .start();
+      },
+      //预警文本生成
+      alarmTextLabel(list){
+        let self = this;
+        let newList = [];
+        self.modelBuildingList.forEach((maxItem)=>{
+          list.forEach((item)=>{
+            if(maxItem.buildId == item.buildId){
+              let num = 0;
+              newList.forEach((minItem)=>{
+                if(minItem.buildId == item.buildId){
+                  num++
+                  if(!minItem.textList[1]){
+                    minItem.textList.push(
+                      "<div style='border-top:1px dashed #E90104;margin-top:35px;'>" +
+                      "<p style='color:#FF8400;font-size:34px;line-height:49px;margin-top:29px;'>"+item.riskPlanName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+this.parseTime(item.eventStartTime,"{y}-{m}-{d} {h}:{i}:{s}")+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+item.floorName+"-"+item.roomNum+"-"+item.deptName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'><span style='border:1px solid "+item.classLevelColor+";padding:0 10px;margin-right:20px;border-radius:20px;color:"+item.classLevelColor+";'>"+item.classLevelName+"</span>"+item.subName+"</p>"+
+                      "</div>"
+                    )
+                  }else{
+                    minItem.textList.splice(0,1)
+                    minItem.textList.push(
+                      "<div style='border-top:1px dashed #E90104;margin-top:35px;'>" +
+                      "<p style='color:#FF8400;font-size:34px;line-height:49px;margin-top:29px;'>"+item.riskPlanName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+this.parseTime(item.eventStartTime,"{y}-{m}-{d} {h}:{i}:{s}")+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+item.floorName+"-"+item.roomNum+"-"+item.deptName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'><span style='border:1px solid "+item.classLevelColor+";padding:0 10px;margin-right:20px;border-radius:20px;color:"+item.classLevelColor+";'>"+item.classLevelName+"</span>"+item.subName+"</p>"+
+                      "</div>"
+                    )
+                  }
+                }
+              })
+              if(num == 0){
+                newList.push(
+                  {
+                    buildId:item.buildId,
+                    centerValue:maxItem.centerValue,
+                    text:"",
+                    //校区-楼栋
+                    titleName:item.schoolName+' - '+item.buildName,
+                    textList:[
+                      "<div>" +
+                      "<p style='color:#FF8400;font-size:34px;line-height:49px;margin-top:29px;'>"+item.riskPlanName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+this.parseTime(item.eventStartTime,"{y}-{m}-{d} {h}:{i}:{s}")+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'>"+item.floorName+"-"+item.roomNum+"-"+item.deptName+"</p>"+
+                      "<p style='font-size:34px;line-height:49px;margin-top:15px;'><span style='border:1px solid "+item.classLevelColor+";padding:0 10px;margin-right:20px;border-radius:20px;color:"+item.classLevelColor+";'>"+item.classLevelName+"</span>"+item.subName+"</p>"+
+                      "</div>"
+                    ]
+                  }
+                )
+              }
+            }
+          })
+        })
+        //循环定位模型位置并生成textTable
+        newList.forEach((maxItem,maxIndex)=>{
+          maxItem.text = "<div style='z-index:"+maxIndex+";border-radius:20px;padding:30px;color:#ffffff;border:1px solid #E90104;box-shadow: inset 0 0 10px rgba(176, 0, 0, 1);background-color: rgba(187,0,0,0.5)'>"
+          maxItem.text = maxItem.text+"<p style='border-bottom:1px solid #E90104;line-height:104px;'>"+maxItem.titleName+"</p>";
+          maxItem.textList.forEach((html)=>{
+            maxItem.text = maxItem.text + html
+          })
+          maxItem.text = maxItem.text+"</div>"
+          self.subModels.forEach((bigItem)=>{
+            if(bigItem.name == maxItem.centerValue){
+              forScene(bigItem,maxItem.text);
+            }
+          })
+        })
+        function forScene(model,text){
+          self.scene.children.forEach((item)=>{
+            if(item.type == 'Group'){
+              item.children.forEach((minItem)=>{
+                if(minItem.name == model.name){
+                  self.add2dFont(minItem,model.center,text);
+                }
+              })
+            }
+          })
+        }
+      },
+      //生成css2d文字
+      add2dFont(model,center,text){
+        const labelDiv = document.createElement('div');
+        labelDiv.style.fontSize = '40px';
+        labelDiv.style.width = '800px';
+        labelDiv.style.borderRadius = '10px';
+        labelDiv.style.whiteSpace = "pre-line";
+        labelDiv.innerHTML  = text;
+
+        // 创建 CSS2D 对象并绑定到目标
+        const label = new CSS2DObject(labelDiv);
+        const targetPosition = new THREE.Vector3()
+          .copy(center)
+          .add(new THREE.Vector3(0.09,0.08,-0.1));
+        label.position.set(targetPosition.x,targetPosition.y,targetPosition.z); // 在对象上方 1 单位位置
+        this.scene.add(label);
+      },
+      //内外网地址判定
+      judgmentNetworkReturnAddress() {
+        /*判断是否是内网IP*/
+        // 获取当前页面url
+        var curPageUrl = window.location.href;
+
+        var reg1 = /(http|ftp|https|www):\/\//g;//去掉前缀
+        curPageUrl =curPageUrl.replace(reg1,'');
+
+        var reg2 = /\:+/g;//替换冒号为一点
+        curPageUrl =curPageUrl.replace(reg2,'.');
+
+        curPageUrl = curPageUrl.split('.');//通过一点来划分数组
+
+
+        var ipAddress = curPageUrl[0]+'.'+curPageUrl[1]+'.'+curPageUrl[2]+'.'+curPageUrl[3];
+
+        var isInnerIp = false;//默认给定IP不是内网IP
+        var ipNum = getIpNum(ipAddress);
+        /**
+         * 私有IP:A类  10.0.0.0    -10.255.255.255
+         *       B类  172.16.0.0  -172.31.255.255
+         *       C类  192.168.0.0 -192.168.255.255
+         *       D类   127.0.0.0   -127.255.255.255(环回地址)
+         **/
+        var aBegin = getIpNum("10.0.0.0");
+        var aEnd = getIpNum("10.255.255.255");
+        var bBegin = getIpNum("172.16.0.0");
+        var bEnd = getIpNum("172.31.255.255");
+        var cBegin = getIpNum("192.168.0.0");
+        var cEnd = getIpNum("192.168.255.255");
+        var dBegin = getIpNum("127.0.0.0");
+        var dEnd = getIpNum("127.255.255.255");
+        isInnerIp = isInner(ipNum,aBegin,aEnd) || isInner(ipNum,bBegin,bEnd) || isInner(ipNum,cBegin,cEnd) || isInner(ipNum,dBegin,dEnd);
+        return isInnerIp?true:false;
+        /*获取IP数*/
+        function getIpNum(ipAddress) {
+          var ip = ipAddress.split(".");
+          var a = parseInt(ip[0]);
+          var b = parseInt(ip[1]);
+          var c = parseInt(ip[2]);
+          var d = parseInt(ip[3]);
+          var ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
+          return ipNum;
+        }
+        function isInner(userIp,begin,end){
+          return (userIp>=begin) && (userIp<=end);
+        }
+      },
+      // 资源销毁方法
+      disposeThreeResources() {
+        // 释放几何体和材质
+        this.scene.traverse(child => {
+          if (child.isMesh) {
+            child.geometry.dispose();
+            if (Array.isArray(child.material)) {
+              child.material.forEach(m => m.dispose());
+            } else {
+              child.material.dispose();
+            }
+          }
+        });
+
+        // 释放渲染器
+        this.renderer.dispose();
+        this.labelRenderer.domElement.remove();
+        this.labelRenderer = null;
+
+        // 释放场景和相机
+        this.scene = null;
+        this.camera = null;
+
+        // 释放控制器
+        this.controls.dispose();
+        this.controls = null;
+      },
+    }
+  };
+</script>
+<style scoped lang="scss">
+  .canvasMap{
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+  }
+</style>

+ 8 - 5
src/views/demo6.vue

@@ -101,7 +101,7 @@
         labelDiv.style.height = '40px';
         labelDiv.style.borderRadius = '4px';
         labelDiv.style.whiteSpace = "pre-line";
-        labelDiv.innerHTML  = "<div style=\"background: url(&quot;png/img_yjbge@1x.png&quot;);\"><p>名称</p></div>";
+        labelDiv.innerHTML  = "<div style=\"background: url(&quot;png/img_yjbge@1x.png&quot;);\"><p>"+name+"</p></div>";
 
         // 创建 CSS2D 对象并绑定到目标
         const label = new CSS2DObject(labelDiv);
@@ -115,10 +115,10 @@
       },
       //点击方法
       moveCameraToModel(model,name) {
-        console.log('点击=>model=>',model)
+        // console.log('点击=>model=>',model)
         console.log('点击=>name=>',name)
-        console.log('点击=>scene=>',this.scene)
-        console.log('点击=>subModels=>',this.subModels)
+        // console.log('点击=>scene=>',this.scene)
+        // console.log('点击=>subModels=>',this.subModels)
         let self = this;
         // 禁用控制器
         this.controls.enabled = false;
@@ -240,7 +240,7 @@
       //模型加载
       loadModel() {
         const loader = new GLTFLoader();
-        loader.load('/models/demo2.glb', (gltf) => {
+        loader.load('/models/NxiaoQu.glb', (gltf) => {
           const model = gltf.scene;
           this.scene.add(model);
 
@@ -257,6 +257,9 @@
               });
             }
           });
+          this.subModels.forEach((item)=>{
+            console.log(item.name)
+          })
         });
       },
       getBoundingBoxCenter(obj) {

+ 21 - 20
src/views/demo8.vue

@@ -11,7 +11,7 @@
           top: `${house.screenPosition.y}px`,
         }"
       >
-        <button @click="changeMaterial(house)">更换材质</button>
+        <!--<button @click="changeMaterial(house)">更换材质</button>-->
         <button @click="changeTexture(house)">更换贴图</button>
         <button @click="restoreOriginalMaterial(house)">恢复材质</button>
       </div>
@@ -111,7 +111,7 @@
 
       async loadModel() {
         const loader = new GLTFLoader();
-        const gltf = await loader.loadAsync('/models/demo2.glb');
+        const gltf = await loader.loadAsync('/models/NxiaoQu.glb');
 
         // 递归查找所有Group
         const traverseGroups = (obj) => {
@@ -155,13 +155,13 @@
         const textureLoader = new THREE.TextureLoader();
         this.textures = [
           textureLoader.load('/png/alarm.png'),
-          textureLoader.load('/png/noAlarm.png'),
+          // textureLoader.load('/png/noAlarm.png'),
         ];
 
-        this.materials = [
-          new THREE.MeshStandardMaterial({ color: 0xff0000 }),
-          new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
-        ];
+        // this.materials = [
+        //   new THREE.MeshStandardMaterial({ color: 0xff0000 }),
+        //   new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
+        // ];
       },
 
       updateScreenPositions() {
@@ -176,7 +176,20 @@
         });
       },
 
-      // 新增恢复方法
+      // 报警样式
+      changeTexture(house) {
+        console.log('houses',this.houses)
+        const texture = this.textures[Math.floor(Math.random() * this.textures.length)];
+        texture.needsUpdate = true;
+
+        house.group.traverse(child => {
+          if (child.isMesh) {
+            child.material.map = texture;
+            child.material.needsUpdate = true;
+          }
+        });
+      },
+      // 恢复正常显示
       restoreOriginalMaterial(house) {
         house.originalMaterials.forEach(entry => {
           entry.mesh.material.dispose(); // 清理当前材质
@@ -194,18 +207,6 @@
           }
         });
       },
-
-      changeTexture(house) {
-        const texture = this.textures[Math.floor(Math.random() * this.textures.length)];
-        texture.needsUpdate = true;
-
-        house.group.traverse(child => {
-          if (child.isMesh) {
-            child.material.map = texture;
-            child.material.needsUpdate = true;
-          }
-        });
-      },
       onWindowResize() {
         this.camera.aspect = window.innerWidth / window.innerHeight;
         this.camera.updateProjectionMatrix();

+ 171 - 2
src/views/home.vue

@@ -158,7 +158,8 @@
   import alarmComponents from "@/views/cengterMaxBox/alarmComponents/index.vue";
   import videoSurveillance from "@/views/cengterMaxBox/videoSurveillance/index.vue";
   //地图模型组件
-  import canvasMap from "@/views/cengterMaxBox/canvasMap/index.vue";
+  // import canvasMap from "@/views/cengterMaxBox/canvasMap/index.vue";
+  import canvasMap from "@/views/cengterMaxBox/canvasMap/newIndex.vue";
   export default {
     name: 'home',
     components: {
@@ -263,7 +264,7 @@
           {school:'N',	name:'经管园林楼(文科楼)A',	buildId:'101093843117592777',buildIdList:[],},
           {school:'N',	name:'经管园林楼(文科楼)C',	buildId:'101093843117592778',buildIdList:[],},
           {school:'N',	name:'草业与草原楼',	buildId:'101093843117592825',buildIdList:[],},
-          {school:'N',	name:'学院实验楼',	buildId:'101093843117592821',buildIdList:[],},
+          {school:'N',	name:'学院实验楼',	buildId:'101093843117592821',buildIdList:[],},
           {school:'旱研院校区',	name:'农一站科研楼',	buildId:'101093843117592827',buildIdList:[],},
           {school:'旱研院校区',	name:'农机一站平房',	buildId:'101093843117592828',buildIdList:[],},
           {school:'校外',	name:'农三站科研办公楼',	buildId:'101093843117592790',buildIdList:[],},
@@ -310,6 +311,174 @@
       }
     },
     methods:{
+      demo(){
+        console.log('demo')
+        // let list = [{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592777",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101084081109864872",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592817",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592820",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592787",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592819",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592784",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592825",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592821",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592821",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },{
+        //   "subName": "分子设计育种实验室",
+        //   "riskPlanName": "温度测试预案",
+        //   "eventStartTime": "2025-03-12T10:42:18",
+        //   "deptName": "草业学院",
+        //   "schoolName": "南校区",
+        //   "buildId": "101093843117592821",
+        //   "buildName": "草业与草原楼",
+        //   "floorName": "1层",
+        //   "roomNum": "109",
+        //   "classLevelName": "Ⅲ级",
+        //   "classLevelColor": "#FFBB00",
+        // },];
+        let list = [{
+          "subName": "分子设计育种实验室",
+          "riskPlanName": "温度测试预案",
+          "eventStartTime": "2025-03-12T10:42:18",
+          "deptName": "草业学院",
+          "schoolName": "南校区",
+          "buildId": "101093843117592809",
+          "buildName": "草业与草原楼",
+          "floorName": "1层",
+          "roomNum": "109",
+          "classLevelName": "Ⅲ级",
+          "classLevelColor": "#FFBB00",
+          "school":'B'
+        }]
+        let obj = {
+          "subName": "分子设计育种实验室",
+          "riskPlanName": "温度测试预案",
+          "eventStartTime": "2025-03-12T10:42:18",
+          "deptName": "草业学院",
+          "schoolName": "南校区",
+          "buildId": "101093843117592809",
+          "buildName": "草业与草原楼",
+          "floorName": "1层",
+          "roomNum": "109",
+          "classLevelName": "Ⅲ级",
+          "classLevelColor": "#FFBB00",
+          "school":'B'
+        };
+        this.$refs['canvasMap'].alarmTrigger(list,obj,obj.school);
+      },
+      demo1(){
+        this.$refs['canvasMap'].alarmOff();
+      },
       openBackManageUrl(){
         this.$confirm('确定注销并退出系统吗?', '提示', {
           confirmButtonText: '确定',