Procházet zdrojové kódy

添加孪生界面与数据驾驶舱切换功能

liling před 2 měsíci
rodič
revize
ca8a52cf0b

binární
src/assets/image/000.png


binární
src/assets/image/nav_bg.png


binární
src/assets/image/nav_bg1.png


+ 14 - 3
src/pages/components/Bottom.vue

@@ -16,17 +16,21 @@ export default {
         facModelLoadState:{
             type:Boolean,
             required: true
+        },
+        userRole:{
+            type:String
         }
     },
     setup(props,{emit}) {
+        const showIndexData = ref('');
         let dataTimer = null;
         const btnFrontBg = require('@/assets/image/nav_btn_front.png');
         let navlist=ref([
             {"code":"FAC","name":"全厂","active":true,"img":require('@/assets/image/nav_ico_fac1.png'),"img1":require('@/assets/image/nav_ico_fac2.png')},
             {"code":"IN02","name":"经编","active":false,"img":require('@/assets/image/nav_ico_in021.png'),"img1":require('@/assets/image/nav_ico_in022.png')},
-            {"code":"IN04","name":"前整","active":false,"img":require('@/assets/image/nav_ico_in041.png'),"img1":require('@/assets/image/nav_ico_in042.png')},
-            {"code":"IN03","name":"印花","active":false,"img":require('@/assets/image/nav_ico_in031.png'),"img1":require('@/assets/image/nav_ico_in032.png')},
-            {"code":"IN05","name":"后整","active":false,"img":require('@/assets/image/nav_ico_in051.png'),"img1":require('@/assets/image/nav_ico_in052.png')},
+            //{"code":"IN04","name":"前整","active":false,"img":require('@/assets/image/nav_ico_in041.png'),"img1":require('@/assets/image/nav_ico_in042.png')},
+            {"code":"IN03","name":"染整","active":false,"img":require('@/assets/image/nav_ico_in031.png'),"img1":require('@/assets/image/nav_ico_in032.png')},
+            //{"code":"IN05","name":"后整","active":false,"img":require('@/assets/image/nav_ico_in051.png'),"img1":require('@/assets/image/nav_ico_in052.png')},
         ]);    
         
         watch(() => props.facModelLoadState, newVal=> {
@@ -42,6 +46,10 @@ export default {
             }
         },{deep:true,immediate:true})
 
+        watch(() => props.userRole, newVal=> {
+            showIndexData.value = newVal;
+        },{deep:true,immediate:true})
+
         let DataFull={
             GetProductionLneInfo:function(){
                 if(window.CurrentTargetType=='IN02'||window.CurrentTargetType=='FAC'){
@@ -63,6 +71,9 @@ export default {
         //const emit = defineEmits(['call']);
 
         function loadNavModel(item){
+            if(showIndexData.value=='dataindex' && item.code=='IN02'){
+                return;
+            }
             for(let i=0;i<navlist.value.length;i++){
                 if(navlist.value[i].code==item.code){
                     navlist.value[i].active=true;

+ 67 - 6
src/pages/components/Fac.vue

@@ -1,12 +1,17 @@
 <template>
     <!--这是全厂模块的模块展示内容-->
-    <div for="FAC" id="top" class="top topfac">
+    <div for="FAC" id="top" class="top topfac" @click="switchIndex">
         <div title="返回主视图"
             style="cursor: pointer;position: absolute;right: 40px;top: 25px;height: 38px;width: 38px;text-align: center;"
-            @click="backMasterViewByFac"><img src="../../assets/image/view.png"></div>
+            @click.stop="backMasterViewByFac"><img src="../../assets/image/view.png"></div>
     </div>
     <div class="bg1"></div>
-    <div class="abs leftPanel">
+    <div class="abs tools" v-if="showIndexData=='dataindex'">
+        <div :class="item.active?'btn active':'btn'" v-for="item in toolsBtnList" :style="{backgroundImage: item.active?`url(${btnFrontBg})`:''}" @click="loadNavModel(item);">
+            <div>{{ item.name }}</div>
+        </div>
+    </div>
+    <div class="abs leftPanel" v-if="showIndexData=='index'">
         <div class="title_row"><div class="title_left_line"></div><span>平均值</span><span style="color:#27e6ff">(本月)</span></div>
         <div class="data_row"><img src="../../assets/image/icon_00.png">
             <div style="margin-left: 10px;"><table>
@@ -92,7 +97,7 @@
             </div>
         </div>
     </div>
-    <div class="abs rightPanel">
+    <div class="abs rightPanel" v-if="showIndexData=='index'">
         <div class="title_row" style="line-height: 30px;"><div class="title_left_line" style="margin-top: 7px;"></div>
             <span>生产趋势</span><span style="color:#27e6ff">(7天)</span>
             <span style="margin-left: auto !important;">
@@ -119,6 +124,7 @@
 </template>
 <script>
 import { ref,onMounted,watch,emit,onUnmounted } from 'vue';
+import {useRouter} from 'vue-router';
 import api from "@/api/system";
 import * as echarts from 'echarts';
 export default {
@@ -126,9 +132,13 @@ export default {
         facModelLoadState:{
             type:Boolean,
             required: true
+        },
+        userRole:{
+            type:String
         }
     },
     setup(props,{emit}) {
+        const router = useRouter();
         const isShowIframeWin=ref(false);
         const iframeWinData = ref({});
         const echarts1 = ref(null);
@@ -137,6 +147,14 @@ export default {
         const echarts4 = ref(null);
         const echarts_sc_qushi = ref(null);
         const echarts_used_qushi = ref(null);
+        const showIndexData=ref('');
+        const btnFrontBg = require('@/assets/image/nav_btn_front.png');
+        const toolsBtnList=ref([
+            {"code":"tools01","name":"能耗","active":true},
+            {"code":"tools02","name":"成本","active":false},
+            {"code":"tools03","name":"销售","active":false},
+        ]);
+
         let buttonCode1 = ref('');
         let buttonCode2 = ref('');
         let deviceStatData=ref({"avgMonth":{},"currYield":{"jb":{},"rz":{}}});
@@ -177,6 +195,10 @@ export default {
             }
         },{deep:true,immediate:true})
 
+        watch(() => props.userRole, newVal=> {
+            showIndexData.value = newVal;
+        },{deep:true,immediate:true})
+
         let DataFull={
             GetFacData:function(){
                 getDataTimer = setTimeout(function () {
@@ -193,6 +215,9 @@ export default {
                 });
             },
             GetDeviceStat:function(){
+                if(showIndexData.value=='dataindex') {
+                    return;
+                }
                 getDataTimer1 = setTimeout(function () {
                     //每1分钟主动查询一次数据
                     DataFull.GetDeviceStat()
@@ -394,7 +419,7 @@ export default {
                 return
             }
             v_series.push({
-                name: "经编", type: 'bar',  smooth: true, //symbol: 'none',
+                name: "经编", type: 'line',  //symbol: 'none',
                 data: week_aefficiency, itemStyle: {
                     normal: {
                         color: '#1EFFFF', // 这里设置折线的颜色
@@ -416,7 +441,7 @@ export default {
                 }
             });
             v_series.push({
-                name: "染整", type: 'bar',  smooth: true, //symbol: 'none',
+                name: "染整", type: 'line',  //symbol: 'none',
                 dataType:'Weight',
                 data: week_befficiency, itemStyle: {
                     normal: {
@@ -1083,6 +1108,13 @@ export default {
             isShowIframeWin.value=false;
             iframeWinData.value={};
         }
+        function switchIndex(){
+            if(showIndexData.value=='index'){
+                router.push('/datamain');
+            }else{
+                router.push('/main');
+            }
+        }
         onMounted(()=>{
             clearTimeout(getDataTimer);
             clearTimeout(getDataTimer1);
@@ -1111,6 +1143,9 @@ export default {
 
         });
         return{
+            showIndexData,
+            btnFrontBg,
+            toolsBtnList,
             backMasterViewByFac,
             loadmarkers,
             showStockTrend,
@@ -1135,6 +1170,7 @@ export default {
             echarts_used_qushi,
             buttonCode1,
             buttonCode2,
+            switchIndex,
         }
     }
 }
@@ -1169,6 +1205,31 @@ export default {
     background-size: 20px 20px;
    */
 }
+.tools{
+    display: flex;
+    justify-content: center; 
+    flex-flow: row;    
+    top: calc(80px * var(--hRate)) !important;
+    width: 98.2%;
+    z-index: 11;
+    
+}
+.tools .btn{
+    width: 100px !important;
+    height: 140px !important;
+    color: #1eabb7;
+    cursor: pointer;
+    font-size: 16px;
+}
+.tools .btn.active>div{
+    border: 2px solid #74b7c4 !important;
+    width: 66px;
+    height: 32px;
+    line-height: 32px;
+    box-shadow: 0px 0px 27px 2px rgb(225 208 208 / 67%);
+    background-color: #eeeff140;
+    border-radius: 5px;
+}
 .devicePanel{
     position: absolute;top: 5%;left: 2%;width: 300px;height: 306px;z-index: 2;color: rgb(255, 255, 255);font-size: 18px;padding: 10px;border: 1px solid #b4a9e6;background: #1d476c1c;border-radius: 5px;box-shadow: 0px 0px 4px #5d7a94;
 }

+ 3 - 0
src/pages/components/In02.vue

@@ -1393,6 +1393,9 @@ export default {
         },
         userTimeout:{
             type:Boolean
+        },
+        userRole:{
+            type:String
         }
     },
     setup(props,{emit}) {

+ 27 - 6
src/pages/components/In03.vue

@@ -1,10 +1,11 @@
 <template>
     <!--这是印花模块的模块展示内容-->
-    <div for="IN03"  id="top" class="top top03"></div>
+    <div for="IN03"  id="top" class="top topfac"  @click="switchIndex"></div>
     <div class="bg2"></div>
 </template>
 <script>
 import { ref ,watch,onUnmounted} from 'vue';
+import {useRouter} from 'vue-router';
 export default {
     props:{
         clickEvent:{
@@ -17,12 +18,17 @@ export default {
         },
         userTimeout:{
             type:Boolean
+        },
+        userRole:{
+            type:String
         }
     },
     setup(props,{emit}) {
+        const router = useRouter();
         let lines={};
         let oldLineState={};
         let updateLineStateTimer = null;
+        const showIndexData=ref('');
         watch(() => props.clickEvent, newVal=> {
             if(newVal==null){
                 return;
@@ -41,11 +47,16 @@ export default {
                 //if (!AutoPlayer.value && window.CurrentTargetType=='IN02') switchAutoPlayer(); //开启自动漫游               
             }
         },{deep:true,immediate:true}) 
+
+        watch(() => props.userRole, newVal=> {
+            showIndexData.value = newVal;
+        },{deep:true,immediate:true})
+
         async function init(){
             if(player==null || player.Native==null) return;
-            player.Native.Camera.moveTo([-79.28639598598434, -58.11055865195772, 81.65118471407432], 
-            [ -79.73865566374896, 63.89413313753133, -17.790826652375742], 
-            [-0.0023419608689169997, 0.6317835262434115, 0.7751413362650253], 1);
+            player.Native.Camera.moveTo([-82.44752782107487, -169.5681236210533, 197.8407699405502], 
+            [-83.9162839208987, 127.59715392660286, -64.11893924293801], 
+            [-0.00326832109282338, 0.66126128414494, 0.7501485400693781], 1);
             // 使用异步函数
             (async () => {
                 setTimeout(function() {
@@ -142,6 +153,13 @@ export default {
             }
             oldLineState = JSON.parse(JSON.stringify(window.IN345LINE));
         }
+        function switchIndex(){
+            if(showIndexData.value=='index'){
+                router.push('/datamain');
+            }else{
+                router.push('/main');
+            }
+        }
         onUnmounted(()=>{
             clearTimeout(updateLineStateTimer);
             if(player!=null && player.Native!=null && window.IN03Markers!=null){
@@ -151,15 +169,18 @@ export default {
             }
             window.IN03Markers=null;
         })
+        return{
+            switchIndex
+        }
     }
 }
 </script>
 <style scope="IN03">
 .bg2{
     z-index: 1; pointer-events: none;position: absolute;
-    top: 0;/*calc(90px * var(--hRate));*/
+    top: calc(90px * var(--hRate));
     left: 0;
-    width: 100%;
+    width: 98.2%;
     height: 89%;
     margin-left: 19px;
     border: 2px solid #17666e;

+ 570 - 0
src/pages/main/dataindex.vue

@@ -0,0 +1,570 @@
+<style src="../../styles/main.css"></style>
+<template>
+    <div>
+        <div v-if="!isLoaded" ref="loading_a1" id="loading_a1"></div>
+        <div v-if="!isLoaded" ref="loading" id="loading">正在加载模型中...</div>
+        <div v-if="reconnect" class="reconnect">网络连接中断,正在进行重连...</div>
+        <video ref="EngineContent" autoplay muted style="width: 1920px;height:1080px;">浏览器不支持</video>
+        <Fac v-if="currentTargetType=='FAC'"  user-role="dataindex" :fac-model-load-state="isLoaded"  @markerLClick="facMarkerLClick"></Fac>
+        <In02 ref="In02Ele" v-if="currentTargetType=='IN02'"  user-role="dataindex" :click-event="In02ClickEvent" :in02-model-load-state="in02modelloadstate" :user-timeout="AutoPlayer"></In02>
+        <In03 ref="In03Ele" v-if="currentTargetType=='IN03'"  user-role="dataindex" :click-event="In03ClickEvent" :in03-model-load-state="in03modelloadstate" :user-timeout="AutoPlayer"></In03>
+        <!--
+        <In04 v-if="currentTargetType=='IN04'" :click-event="In04ClickEvent" :in04-model-load-state="in04modelloadstate" :user-timeout="AutoPlayer"></In04>
+        <In05 v-if="currentTargetType=='IN05'" :click-event="In05ClickEvent" :in05-model-load-state="in05modelloadstate" :user-timeout="AutoPlayer"></In05>
+        -->
+        <Bottom @loadNavModel="loadNavModel"  user-role="dataindex" :fac-model-load-state="isLoaded"/>
+    </div>
+</template>
+<script>
+import { ref, onMounted, onBeforeUnmount } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElLoading } from "element-plus";
+import lottie from 'lottie-web';
+import api from "@/api/system";
+import Bottom from '../components/Bottom.vue';
+import Fac from '../components/Fac.vue';
+import In02 from '../components/In02.vue';
+import In03 from '../components/In03.vue';
+import In04 from '../components/In04.vue';
+import In05 from '../components/In05.vue';
+export default {    
+    components:{
+        Bottom,
+        Fac,
+        In02,
+        In03,
+        In04,
+        In05,
+    },
+    setup() {
+        const loading_a1=ref(null);
+        const EngineContent=ref(null);
+        const reconnect=ref(false);
+        const autoplayer_btn =ref(null);
+        let In02ClickEvent = ref(null);
+        let In04ClickEvent = ref(null);
+        let In03ClickEvent = ref(null);
+        let In05ClickEvent = ref(null);
+        const In03Ele = ref(null);
+        let isLoaded = ref(false);
+        let isClearEle = ref(false);
+        window.player = null;
+        let playerNative = ref(null);
+        let playerConnState=false;
+        window.modelLoadState = {};
+        const facModelLoadState=ref(false);
+        const in02modelloadstate=ref(false);
+        const in03modelloadstate=ref(false);
+        const in04modelloadstate=ref(false);
+        const in05modelloadstate=ref(false);
+        let currentTargetType = ref('');
+        let reconntimer=null;
+        let MarkerMapFac={};
+        let AutoPlayer=ref(false);
+        let markerLClickObj=null;        
+        
+        let  inPoints={
+            "IN02":{"Text001_002":1,"x1":-28.07801,"y1":37.95126,"x2":-23.32394,"y2":31.16921},
+            "IN03":{"Text001_006":1,"x1":46.86921,"y1":24.87041,"x2":51.91054,"y2":17.87417},
+            //"IN04":{"Text001_004":1,"x1":-38.46275,"y1":35.65208,"x2":-44.94122,"y2":28.22142},
+            //"IN05":{"Text001_005":1,"x1":102.43050,"y1":38.96248,"x2":108.99212,"y2":30.86295}
+        };
+        function ShowLoading(){
+            lottie.loadAnimation({
+                // 选取一个容器,用于渲染动画
+                container: loading_a1.value,
+                // 定义JSON文件路径
+                animationData: lottiedata,
+                // 是否循环播放
+                loop: true,
+                // 渲染的格式svg/canvas/html,svg性能更优,兼容性更好
+                renderer: "svg",
+            });
+        }
+        function loadNavModel(item){
+            //console.log(item)
+            switch(item.code){
+                case "FAC":
+                    loadFacModel(playerNative.value);
+                    break;
+                case "IN02":
+                    loadIn02Model(playerNative.value);
+                    break;
+                case "IN03":
+                    loadIn03Model(playerNative.value);
+                    break;
+                case "IN04":
+                    loadIn04Model(playerNative.value);
+                    break;
+                case "IN05":
+                    loadIn05Model(playerNative.value);
+                    break;
+            }
+            backMasterView();
+        }
+        function facMarkerLClick(obj){
+            //接收Fac组件中点击标记时的数据
+            markerLClickObj = obj;
+        }
+        function handleBodyClick(){
+            isClearEle.value=true;
+        }
+        async function moveFacAnything(name,event){
+            console.log(name, event)
+            if(event.object==null) return;
+            var se = event.object;
+            player.Native.ModelTree.setSelectItem(event.object.item);
+            var calcInfo = await PlayerUtils.call(player.Native.ModelTree.calcItemAabb, se.item);
+            console.log(calcInfo)
+            player.Native.Camera.moveToAabbWithDistance([calcInfo.localAabb.min, calcInfo.localAabb.max], 0.5, 0, 0.9);
+        }
+        function senceInit(){
+            player = new RemotePlayer({
+                video: EngineContent.value, //绑定视频标签或图片标签
+                signalServer: window.PLAYER3D_URL, //云渲染服务器,发布时需要改为实际地址
+                engineId: "" + Date.now(), // 引擎会话id,如果已存在则连接,没有则创建,会话在断开连接后超时自动关闭
+                rtcIni: 'rtc.ini', // 可指定webrtc配置文件,默认为rtc.ini,相对目录为集群节点的enginePath目录
+                autoResize: true, // 引擎是否跟跟随标签尺寸
+                limtMoveCPS: 10, // 限制每秒鼠标移动的消息个数
+                userTimeout: 1000 * 60 * 5, // 用户操作超时设置,毫秒
+                exitTimeout: 1000 * 60 * 60 * 999999, // 用户超时后多久断开会话
+                maxTimeout: 10000, // 会话超时时间,允许掉线后引擎保存多久,在该时间内可重新连接到会话,否则会创建新的会话
+                debug: false // 是否启用调试,开启后调用Native接口时会使用console.log进行记录
+            });
+            //2.[可选]监听连接成功消息
+            player.on("Connected", () => {
+                console.log("Has connected to engine")
+                playerConnState = true
+                reconnect.value = false;
+                if (reconntimer != null) clearTimeout(reconntimer);
+            });
+
+            //3.[可选]监听连接失败消息
+            player.on("Disconnected", (e) => {
+                console.log("Disconnected from engine", e);
+                reconnect.value = true;
+                isClearEle.value=true;
+                playerConnState = false
+                isLoaded.value = false;
+                facModelLoadState.value=false;
+                in02modelloadstate.value=false;
+                in03modelloadstate.value=false;
+                in04modelloadstate.value = false;
+                in05modelloadstate.value = false;
+                window.IN03Markers=null;
+                window.IN04Markers=null;
+                window.IN05Markers=null;      
+                AutoPlayer.value=false;     
+                EngineContent.value.pause();     
+                if(e=='signal websocket error'){
+                    //服务器网络不通
+                }
+                modelLoadState={};
+                //currentTargetType.value='';
+                //4.[推荐]尝试重新连接
+                reconntimer = setTimeout(function () {
+                    console.log('尝试自动重连:', playerConnState)
+                    if (playerConnState) return
+                    if(player==null ){
+                        window.location.reload();
+                        return;
+                    }
+                    player.reconnect();
+                }, 4000)
+            });
+
+            //5. [推荐] 响应UserTimeOut消息,引擎接收用户鼠标触屏事件超时发出通知
+            player.on("UserTimeOut", () => {
+                console.info('用户长时间没有操作三维视图,可调用player.resetTimer()取消退出');
+                //AutoPlayer.value = true;  //暂时取消自动漫游功能              
+            });
+            player.on('TimeOutExit',()=>{
+                console.info('长时间没有操作,已断开连接');
+            });
+            player.on('ConnectedFailed',(evt)=>{
+                console.info('服务器连接失败');
+            })
+            //6.监听远程过程调用加载完成消息
+            player.on("NativeLoad", async (Native) => {
+                modelLoadState={};
+                EngineContent.value.play();
+                playerNative.value =Native;
+                // // 选择Pickup工具
+                player.Native.Tools.setCurrentTool("system.Pickup");
+                player.Native.Settings.set('skybox',"string","null");
+                player.Native.Settings.set('bg.image.file',"string",'data/sky/bg.png');
+                //不显示提示框
+                player.Native.Settings.set("tips.enabled", "bool", false);
+                // //点选高亮显示
+                player.Native.Settings.set("pickUp.highlight", "bool", false);
+                //点选包围盒
+                player.Native.Settings.set("show.select.box", "bool", false);
+                player.Native.Settings.set("skybox.select", "string", "blue");
+                //点选背景虚化
+                player.Native.Settings.set("color.pickup.bkAlpha", "float", 0.8);
+                // 选中展示节点
+                // sam0023 = await player.Native.ModelTree.findItemByName("CYLINDER 3 of EQUIPMENT /C1101", 0, true, 3);
+                player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
+                player.Native.Settings.set('diffuseIntensity', 'float', 0.8);//初始化光线强度
+                player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
+                player.Native.Settings.set('searchLightIntensity', 'float', 0.5);//初始化探照灯强度
+                // 点击事件一般仅用于浏览工具,在点选工具下无效
+                Native.Tools.setCurrentTool("system.Browse");
+                switch(window.CurrentTargetType){
+                    case "IN02":
+                        loadIn02Model(Native);
+                        break;
+                    case "IN03":
+                        loadIn03Model(Native);
+                        break;
+                    case "IN04":
+                        loadIn04Model(Native);
+                        break;
+                    case "IN05":
+                        loadIn05Model(Native);
+                        break;
+                    default:
+                        loadFacModel(Native);
+                        break;
+                }                
+                setTimeout(function(){
+                    isLoaded.value=true
+                },2000);
+
+                //调整视角,使其达到最佳初始效果
+                backMasterView();
+                //player.Native.Camera.moveToItem(lastPtr,1);
+
+                Native.ModelTree.EventBrowseLClick.connect((event) => {
+                    if(event.object==null) return;
+
+                    if(currentTargetType.value=="FAC"){
+                        //必须延迟处理模型的点击事件,以判断是否是点击的标记,暂时没有找到更好的方法处理标记点击
+                        setTimeout(function(event){
+                            if(markerLClickObj!=null){
+                                //标记被点击时,不执行模型点击逻辑
+                                markerLClickObj = null;
+                                return;
+                            }
+                            markerLClickObj = null;
+                            var inTxt = "";
+                            if(inPoints[event.object.name]!=null){
+                                //进入楼层内部
+                                inTxt = txt;
+                            }else {
+                                for (var txt in inPoints) {
+                                    var item = inPoints[txt];
+                                    if(event.pos[1]>= item["x1"] && event.pos[2]<= item["y1"] &&event.pos[1]<= item["x2"] && event.pos[2]>= item["y2"]){
+                                        inTxt = txt;
+                                        break;
+                                    }
+                                }
+                            }
+                            if(inTxt!=""){
+                                switch(inTxt){
+                                    case "IN02":
+                                        loadIn02Model(Native);
+                                        break;
+                                    case "IN03":
+                                        loadIn03Model(Native);
+                                        break;
+                                    case "IN04":
+                                        loadIn04Model(Native);
+                                        break;
+                                    case "IN05":
+                                        loadIn05Model(Native);
+                                        break;
+                                    default:
+                                        break;
+                                }
+                                currentTargetType.value=inTxt;
+                                backMasterView();
+                            }else{
+                                //moveFacAnything("LClick", event);
+                            }
+                        },200,event);
+                        return;
+                    }
+                    if(currentTargetType.value=="IN02"){
+                        In02ClickEvent.value = event;
+                        //In02Ele.updateInfo("LClick", event);
+                    }
+                    if(currentTargetType.value=="IN03") {
+                        //move03Anything("LClick", event);
+                        In03ClickEvent.value = event;
+                    }
+                    if(currentTargetType.value=="IN04") {
+                        //move03Anything("LClick", event);
+                        In04ClickEvent.value = event;
+                    }
+                    if(currentTargetType.value=="IN05") {
+                        //move03Anything("LClick", event);
+                        In05ClickEvent.value = event;
+                    }
+                });
+                Native.ModelTree.EventBrowseRClick.connect((event) => {
+                    if(markerLClickObj!=null) return;
+                    //updateInfo("RClick", event)
+                });
+            })
+        }
+        function getBottomBtnImg(imgname, type){
+            if(currentTargetType.value==type) return require('@/assets/image/'+imgname+'_active.png');
+            else return require('@/assets/image/'+imgname+'.png');
+        }
+        async function loadFacModel(Native){
+            if(currentTargetType.value=="FAC") return;
+            currentTargetType.value="FAC";
+            await player.Native.Model.setModelVisible("IN02",false);
+            await player.Native.Model.setModelVisible("IN03",false);
+            await player.Native.Model.setModelVisible("IN04",false);
+            await player.Native.Model.setModelVisible("IN05",false);
+            if(modelLoadState[currentTargetType.value]==null){
+                var cf = "data://models/T_ALL.pr";
+                var errStr = await PlayerUtils.call(Native.Model.loadModel, currentTargetType.value, cf);
+                modelLoadState[currentTargetType.value] = true;
+            }
+            facModelLoadState.value=true;//全厂模型加载完成
+            await player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
+            await player.Native.Settings.set('diffuseIntensity', 'float', 1.2);//初始化光线强度
+            await player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
+            await player.Native.Model.setModelVisible(currentTargetType.value,true);
+            await player.Native.CameraAnimation.clearKeyFrame();
+        }
+        //后整
+        async function loadIn05Model(Native){
+            player.Native.Settings.set('ambientIndenty', 'float', 1);//初始化环境光补偿
+            player.Native.Settings.set('diffuseIntensity', 'float', 2.5);//初始化光线强度
+            player.Native.Settings.set('specularIntensity', 'float', 0.6);//初始化高光强度
+            if(currentTargetType.value=="IN05") return;
+            currentTargetType.value="IN05";
+            await player.Native.Model.setModelVisible("FAC",false);
+            await player.Native.Model.setModelVisible("IN02",false);
+            await player.Native.Model.setModelVisible("IN03",false);
+            await player.Native.Model.setModelVisible("IN04",false);
+            
+            if(modelLoadState[currentTargetType.value]==null){
+                var cf = "data://models/T_03.pr";
+                var errStr = await PlayerUtils.call(Native.Model.loadModel, 'IN03', cf);
+                modelLoadState[currentTargetType.value] = true;
+            }
+            //showMarker(currentTargetType.value);
+            await player.Native.Model.setModelVisible("IN03",true);
+            in05modelloadstate.value = true;
+        }
+        //前整
+        async function loadIn04Model(Native){
+            player.Native.Settings.set('ambientIndenty', 'float', 1);//初始化环境光补偿
+            player.Native.Settings.set('diffuseIntensity', 'float', 2.5);//初始化光线强度
+            player.Native.Settings.set('specularIntensity', 'float', 0.6);//初始化高光强度
+            if(currentTargetType.value=="IN04") return;
+            currentTargetType.value="IN04";
+            await player.Native.Model.setModelVisible("FAC",false);
+            await player.Native.Model.setModelVisible("IN02",false);
+            await player.Native.Model.setModelVisible("IN03",false);
+            await player.Native.Model.setModelVisible("IN05",false);            
+            if(modelLoadState[currentTargetType.value]==null){
+                var cf = "data://models/T_03.pr";
+                var errStr = await PlayerUtils.call(Native.Model.loadModel, 'IN03', cf);
+                modelLoadState[currentTargetType.value] = true;
+            }
+            //showMarker(currentTargetType.value);
+
+            await player.Native.Model.setModelVisible("IN03",true);
+            in04modelloadstate.value = true;
+        }
+        //印花
+        async function loadIn03Model(Native){
+            player.Native.Settings.set('ambientIndenty', 'float', 1);//初始化环境光补偿
+            player.Native.Settings.set('diffuseIntensity', 'float', 2.5);//初始化光线强度
+            player.Native.Settings.set('specularIntensity', 'float', 0.6);//初始化高光强度
+            if(currentTargetType.value=="IN03") return;
+            currentTargetType.value="IN03";
+            await player.Native.Model.setModelVisible("FAC",false);
+            await player.Native.Model.setModelVisible("IN02",false);
+            await player.Native.Model.setModelVisible("IN04",false);
+            await player.Native.Model.setModelVisible("IN05",false);            
+            if(modelLoadState[currentTargetType.value]==null){
+                var cf = "data://models/T_03.pr";
+                var errStr = await PlayerUtils.call(Native.Model.loadModel, 'IN03', cf);
+                modelLoadState[currentTargetType.value] = true;
+            }
+            //showMarker(currentTargetType.value);
+            await player.Native.Model.setModelVisible(currentTargetType.value,true);
+            player.Native.CameraAnimation.clearKeyFrame();
+            in03modelloadstate.value=true;
+        }
+        //经编
+        async function loadIn02Model(Native){
+            player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
+            player.Native.Settings.set('diffuseIntensity', 'float', 0.8);//初始化光线强度
+            player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
+            if(currentTargetType.value=="IN02") return;
+            currentTargetType.value="IN02";
+            await player.Native.Model.setModelVisible("FAC",false);
+            await player.Native.Model.setModelVisible("IN03",false);
+            await player.Native.Model.setModelVisible("IN04",false);
+            await player.Native.Model.setModelVisible("IN05",false);
+            
+            if(modelLoadState[currentTargetType.value]==null){
+                var cf = "data://models/T_02.pr";
+                var errStr = await PlayerUtils.call(Native.Model.loadModel, currentTargetType.value, cf);
+                modelLoadState[currentTargetType.value]=true;
+            }
+            await player.Native.Model.setModelVisible(currentTargetType.value,true);
+            showMarker(currentTargetType.value);
+            in02modelloadstate.value=true;
+        }
+        async function showMarker(type){
+            console.log(type)
+            console.log('MarkerMapFac:',MarkerMapFac)
+            for (var t in MarkerMapFac) {
+                if(t==type){
+                    for (var markPtr in MarkerMapFac[t]) {
+                        var options = MarkerMapFac[t][markPtr];
+                        options["visible"]=true;
+                        await player.Native.GisMarker.update(markPtr, options);
+                    }
+                }else{
+                    for (var markPtr in MarkerMapFac[t]) {
+                        var options = MarkerMapFac[t][markPtr];
+                        options["visible"]=false;
+                        await player.Native.GisMarker.update(markPtr, options);
+                    }
+                }
+            }
+        }
+        function backMasterView() {
+            switch(currentTargetType.value){
+                case "FAC":
+                    //backMasterViewByFac();
+                    break;
+                case "IN02":
+                    //backMasterViewBy02();
+                    break;
+                case "IN03":
+                    //backMasterViewBy03();
+                    break;
+                case "IN04":
+                    //backMasterViewBy04();
+                    break;
+                case "IN05":
+                    //backMasterViewBy05();
+                    break;
+            }
+        }
+
+        //全局厂房最佳视图
+        function backMasterViewByFac(){
+            if (AutoPlayer.value) {
+                AutoPlayer.value=false;
+                try {
+                    player.Native.CameraAnimation.stop();
+                } catch (e) {
+                }
+            }
+            // player.Native.Camera.moveTo([235.678127000173, 13.38107286701451, 74.13573809425804], [-1248.3191825020908, -262.59031050373517, -409.93944372657353], [-0.30023176822741604, -0.055832565112502126, 0.9522308596238611], 1);
+            player.Native.Camera.moveTo([286.03479667714066, -369.1462098899696, 250.99077822208548], [-1630.186261661935, 1578.4562059189793, -1508.5247276647053],[-0.3797261858729431, 0.38594484375048804, 0.840746454851163], 1);
+            // 使用异步函数
+            (async () => {
+                setTimeout(function() {
+                    player.Native.Camera.setAnchorPos([-45.87571144104003, -44.632896423339844, 43.90447044372559]);
+                }, 3000);
+            })();
+        }
+
+        //印花 3号楼内部最佳视图
+        function backMasterViewBy03() {
+            if (AutoPlayer.value) {
+                AutoPlayer.value=false;
+                try {
+                    player.Native.CameraAnimation.stop();
+                } catch (e) {
+                }
+            }
+            player.Native.Camera.moveTo([-112.11831605370315, -39.47491915621944, 55.053722411257986], [-111.40213220295327, 103.19683033795573, -21.927318724155974], [0.0023836205084244643, 0.4748435861970737, 0.880066978701493], 1);
+            // 使用异步函数
+            (async () => {
+                setTimeout(function() {
+                    player.Native.Camera.setAnchorPos([-109.86441802978516,37.72066879272461,11.815499305725098]);
+                }, 3000);
+            })();
+        }
+        //前整最佳视图
+        function backMasterViewBy04() {
+            if (AutoPlayer.value) {
+                AutoPlayer.value=false;
+                try {
+                    player.Native.CameraAnimation.stop();
+                } catch (e) {
+                }
+            }
+            player.Native.Camera.moveTo([-165.95599185954217, -45.64071153770574, 51.618717703740046], [-164.97558683415676, 188.00984417962832, -47.631915576574826], [0.0016404996757448046, 0.3909646023491811, 0.9204042527448256], 1);
+            // 使用异步函数
+            (async () => {
+                setTimeout(function() {
+                    player.Native.Camera.setAnchorPos([-179.36495971679688,20.81890106201172,18.464128494262695]);
+                }, 3000);
+            })();
+        }
+        //后整最佳视图
+        function backMasterViewBy05() {
+            if (AutoPlayer.value) {
+                AutoPlayer.value=false;
+                try {
+                    player.Native.CameraAnimation.stop();
+                } catch (e) {
+                }
+            }
+            player.Native.Camera.moveTo([-1.4278872234970912, -35.860292172842726, 45.17447131604416], [-0.9361737274384958, 62.09447832231165, 2.337398320693808], [0.0020112694631236063, 0.40066713694655265, 0.916221479865103], 1);
+            // 使用异步函数
+            (async () => {
+                setTimeout(function() {
+                    player.Native.Camera.setAnchorPos([3.2281014919281006,22.60576629638672,18.464128494262695]);
+                }, 3000);
+            })();
+        }
+
+        onMounted(()=>{
+            window.addEventListener("click", handleBodyClick);
+            ShowLoading();
+            senceInit();
+        });
+        onBeforeUnmount(()=>{
+            EngineContent.value.pause();
+            player.Native.Model.unloadModel('FAC');
+            player.Native.Model.unloadModel('IN02');
+            player.Native.Model.unloadModel('IN03');
+
+        })
+        return {
+            player,
+            facMarkerLClick,
+            isLoaded,
+            currentTargetType,
+            loading_a1,
+            reconnect,
+            EngineContent,
+            AutoPlayer,
+            In02ClickEvent,
+            In03ClickEvent,
+            In04ClickEvent,
+            In05ClickEvent,
+            facModelLoadState,
+            in02modelloadstate,
+            in03modelloadstate,
+            in04modelloadstate,
+            in05modelloadstate,
+            ShowLoading,
+            handleBodyClick,
+            senceInit,
+            getBottomBtnImg,
+            backMasterView,
+            markerLClickObj,
+            loadNavModel,
+        }
+    },    
+}
+</script>
+<style scoped>
+</style>

+ 16 - 7
src/pages/main/index.vue

@@ -5,12 +5,14 @@
         <div v-if="!isLoaded" ref="loading" id="loading">正在加载模型中...</div>
         <div v-if="reconnect" class="reconnect">网络连接中断,正在进行重连...</div>
         <video ref="EngineContent" autoplay muted style="width: 1920px;height:1080px;">浏览器不支持</video>
-        <Fac v-if="currentTargetType=='FAC'" :fac-model-load-state="isLoaded"  @markerLClick="facMarkerLClick"></Fac>
-        <In02 ref="In02Ele" v-if="currentTargetType=='IN02'" :click-event="In02ClickEvent" :in02-model-load-state="in02modelloadstate" :user-timeout="AutoPlayer"></In02>
-        <In03 ref="In03Ele" v-if="currentTargetType=='IN03'" :click-event="In03ClickEvent" :in03-model-load-state="in03modelloadstate" :user-timeout="AutoPlayer"></In03>
+        <Fac v-if="currentTargetType=='FAC'" user-role="index" :fac-model-load-state="isLoaded"  @markerLClick="facMarkerLClick"></Fac>
+        <In02 ref="In02Ele" v-if="currentTargetType=='IN02'" user-role="index" :click-event="In02ClickEvent" :in02-model-load-state="in02modelloadstate" :user-timeout="AutoPlayer"></In02>
+        <In03 ref="In03Ele" v-if="currentTargetType=='IN03'" user-role="index" :click-event="In03ClickEvent" :in03-model-load-state="in03modelloadstate" :user-timeout="AutoPlayer"></In03>
+        <!--
         <In04 v-if="currentTargetType=='IN04'" :click-event="In04ClickEvent" :in04-model-load-state="in04modelloadstate" :user-timeout="AutoPlayer"></In04>
         <In05 v-if="currentTargetType=='IN05'" :click-event="In05ClickEvent" :in05-model-load-state="in05modelloadstate" :user-timeout="AutoPlayer"></In05>
-        <Bottom @loadNavModel="loadNavModel" :fac-model-load-state="isLoaded"/>
+        -->
+        <Bottom @loadNavModel="loadNavModel" user-role="index" :fac-model-load-state="isLoaded"/>
     </div>
 </template>
 <script>
@@ -64,8 +66,8 @@ export default {
         let  inPoints={
             "IN02":{"Text001_002":1,"x1":-28.07801,"y1":37.95126,"x2":-23.32394,"y2":31.16921},
             "IN03":{"Text001_006":1,"x1":46.86921,"y1":24.87041,"x2":51.91054,"y2":17.87417},
-            "IN04":{"Text001_004":1,"x1":-38.46275,"y1":35.65208,"x2":-44.94122,"y2":28.22142},
-            "IN05":{"Text001_005":1,"x1":102.43050,"y1":38.96248,"x2":108.99212,"y2":30.86295}
+            //"IN04":{"Text001_004":1,"x1":-38.46275,"y1":35.65208,"x2":-44.94122,"y2":28.22142},
+            //"IN05":{"Text001_005":1,"x1":102.43050,"y1":38.96248,"x2":108.99212,"y2":30.86295}
         };
         function ShowLoading(){
             lottie.loadAnimation({
@@ -278,7 +280,7 @@ export default {
                                 currentTargetType.value=inTxt;
                                 backMasterView();
                             }else{
-                                moveFacAnything("LClick", event);
+                               // moveFacAnything("LClick", event);
                             }
                         },200,event);
                         return;
@@ -528,6 +530,13 @@ export default {
             ShowLoading();
             senceInit();
         });
+        onBeforeUnmount(()=>{
+            EngineContent.value.pause();
+            player.Native.Model.unloadModel('FAC');
+            player.Native.Model.unloadModel('IN02');
+            player.Native.Model.unloadModel('IN03');
+
+        })
         return {
             player,
             facMarkerLClick,

+ 7 - 0
src/router/index.js

@@ -25,6 +25,13 @@ const routes = [
         }
     },
     {
+        path:"/datamain",
+        component: () => import("@/pages/main/dataindex.vue"),
+        meta: {
+            name: "main"
+        }
+    },
+    {
         path:"/bpb-fx",
         component: () => import("@/pages/bpb/index.vue"),
         meta: {

+ 5 - 4
src/styles/main.css

@@ -287,7 +287,7 @@
         background-size: contain;
         background-image: url('../assets/image/nav_bg.png')
     }
-    .bottom .btn{
+    .bottom .btn,.tools .btn{
         cursor: pointer;
         display: flex; 
         flex-flow: column;
@@ -295,18 +295,19 @@
         width: 11%;
         background-size: contain;
         background-repeat: no-repeat;
+        background-position: center;
         color: #1eabb7;
-        font-size: 16px;
+        font-size: 18px;
         text-align: center;
         justify-content: center;
         align-items: center;
     }
-    .bottom .btn:hover{
+    .bottom .btn:hover,.tools .btn:hover{
         color: #fff !important;
         font-size: 18px !important;
         font-weight: bold;
     }
-    .bottom .btn.active{
+    .bottom .btn.active,.tools .btn.active{
         color: #fff !important;
         font-size: 18px !important;
         font-weight: bold;