2 Incheckningar 9d8e95bdf8 ... a4441ca0a7

Upphovsman SHA1 Meddelande Datum
  t_finder a4441ca0a7 优化 点击云机列表可以切换云机 4 dagar sedan
  t_finder 884429ab3b 优化组件获取userCardId参数 4 dagar sedan

+ 2 - 2
pages/rtcEngine/components/CloudGroupDropdown.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="group-dropdown pt-2 pb-2">
     <!-- 设备分组下拉 -->
-    <Dropdown key="deviceList" v-model="activeGroup" :isActvie="true" @visible="(visible)=>($emit('dropdownVisibleChange', visible))" :list="groupList" :prop="{value: 'id'}" :dropdownMenuStyle="{ left: '0', top: '30px' }" :activeStyle="activeStyle">
+    <Dropdown key="deviceList" v-model="activeGroup" :isActvie="true" @visible="(visible)=>($emit('dropdownVisibleChange', visible))" :list="groupList" :prop="{value: 'id'}" :dropdownMenuStyle="{ left: '0', top: '40px' }" :activeStyle="activeStyle">
       <!-- 触发下拉 -->
       <div class="menu-trigger"><div class="device-trigger-ex">{{ groupList.find(g => g.id === activeGroup).label }}</div><van-icon class="icon-arrow rotate-down" name="play" color="#fff" size="10" /></div>
     </Dropdown>
 
     <!-- 清晰度下拉 -->
-    <Dropdown key="definition" ref="definitionDropdown" @visible="(visible)=>($emit('dropdownVisibleChange', visible))" :dropdownMenuStyle="{ left: '0', top: '30px' }">
+    <Dropdown key="definition" ref="definitionDropdown" @visible="(visible)=>($emit('dropdownVisibleChange', visible))" :dropdownMenuStyle="{ left: '0', top: '40px' }">
       <!-- 触发下拉 -->
       <div class="menu-trigger">
         <div class="definition-trigger-ex">

+ 12 - 7
pages/rtcEngine/components/CloudList.vue

@@ -2,7 +2,7 @@
   <!-- 云机列表 -->
   <div class="cloud-list-wrap" >
     <van-list :style="listStyle" :finished="false">
-      <div v-for="item in list" :key="item.userCardId" class="cloud-list-item-wrap flex" :class="{'cloud-list-item-active': activeId === item.userCardId}" @click="activeId = item.userCardId">
+      <div v-for="item in list" :key="item.userCardId" class="cloud-list-item-wrap flex" :class="{'cloud-list-item-active': userCardId === item.userCardId}" @click="changeCloud(item)">
         <!-- 云机套餐头像 -->
         <div class="cloud-id-avatar-wrap items-center pr-2">
           <van-image
@@ -30,7 +30,7 @@ export default {
       type: String,
       default: '50px'
     },
-    // 云机列表的选中项
+    // 当前云机id
     userCardId: {
       type: [String, Number],
       default: ''
@@ -51,11 +51,6 @@ export default {
       default: () => () => {}
     }
   },
-  data() {
-    return {
-      activeId: +this.userCardId,
-    }
-  },
   computed: {
     // 云机列表高度
     listStyle() {
@@ -70,6 +65,16 @@ export default {
       return this.cloudList.filter(item => item.groupId === this.activeGroupId);
     }
   },
+  methods: {
+    // 切换云机
+    changeCloud(item) {
+      // 如果当前云机id和选中的云机id相同, 则不做任何操作
+      if(+this.userCardId === item.userCardId) return;
+      this.$emit('changeCloud', item);
+      // 关闭popup
+      this.$emit('update:levitatedSphereVisible', false);
+    }
+  }
 }
 </script>
 

+ 0 - 1
pages/rtcEngine/components/CloudMainPanel.vue

@@ -65,7 +65,6 @@ export default {
     },
     // 当前云机套餐的图标
     iconUrl() {
-      console.log(this.cloudInfo);
       return this.imgFun(this.cloudInfo.buyVipType, this.cloudInfo.androidVersion);
       
     }

+ 5 - 0
pages/rtcEngine/components/FunctionMenu.vue

@@ -98,12 +98,17 @@ export default {
         this.$nextTick(() => {
           // 切换状态
           item.status = !item.status;
+
+          // 关闭popup
+          this.$emit('update:levitatedSphereVisible', false);
         });
         return;
       }
       
       // 触发父组件事件
       this.$emit('funcHandle', item);
+      // 关闭popup
+      this.$emit('update:levitatedSphereVisible', false);
     }
   }
 }

+ 1 - 13
pages/rtcEngine/components/LeftMenuPopup.vue

@@ -8,7 +8,7 @@
         <CloudMainPanel id="pupop-header" v-bind="$attrs" v-on="$listeners" :userCardId="userCardId" :cloudList="cloudList" />
 
         <!-- 功能区域 -->
-        <FunctionMenu id="function-menu" @functionMenuVisible="scrollHeight" @funcHandle="funcHandle"/>
+        <FunctionMenu id="function-menu" @functionMenuVisible="scrollHeight" v-bind="$attrs" v-on="$listeners" />
 
         <!-- 包一层是为了获取区域的height计算云机列表滚动高度 -->
         <div id="select-wrap">
@@ -91,11 +91,6 @@ export default {
           '流畅': { width: 360, height: 640, fps: 20 },
       })
     },
-    // url中获取的参数, 父组件传递
-    parametersData: {
-      type: Object,
-      default: () => ({})
-    },
   },
   components: {
     CloudMainPanel,
@@ -162,13 +157,6 @@ export default {
         this.cloudListScrollHeight = 100;
       }
     },
-    // 处理功能菜单的事件
-    funcHandle(val){
-      // 关闭popup
-      this.$emit('update:levitatedSphereVisible', false);
-      // 触发父组件事件
-      this.$emit('funcHandle', val);
-    },
     /**
 		 * 根据卡套餐获取对应图标
 		 * @method imgFun 

+ 16 - 8
pages/rtcEngine/components/TimeBalance.vue

@@ -52,6 +52,16 @@
 export default {
   name: 'TimeBalance',
   props: {
+    // 当前云机id
+    userCardId: {
+      type: [String, Number],
+      default: ''
+    },
+    // 云机的类型  0 普通套餐 1、2、3:年卡、普通计时、自动续费普通计时 
+    userCardType: {
+      type: [String, Number],
+      default: ''
+    },
     // url中获取的参数, 父组件传递
     parametersData: {
       type: Object,
@@ -83,13 +93,13 @@ export default {
     // 获取云机剩余时长
     async getResidueTime() {
         clearInterval(this.countdownTimeInterval)
-        const { userCardType, isShowCountdown, isShowRule, userCardId } = this.parametersData;
-        if (![1, 2, 3].includes(+userCardType)) return;
-        const res = await this.$axios.get(`/resources/yearMember/getResidueTime?userCardId=${userCardId}`);
+        const { isShowCountdown, isShowRule } = this.parametersData;
+        if (![1, 2, 3].includes(+this.userCardType)) return;
+        const res = await this.$axios.get(`/resources/yearMember/getResidueTime?userCardId=${this.userCardId}`);
         let time = res.data;
         if (!res.status) {
           this.countdownTime = this.residueTimeStamp(time);
-          await this.$axios.get(`/resources/yearMember/startTime?userCardId=${userCardId}`);
+          await this.$axios.get(`/resources/yearMember/startTime?userCardId=${this.userCardId}`);
           // 计时卡显示
           if (+isShowCountdown) this.timingVisible = true;
           // 计费规则显示
@@ -109,8 +119,7 @@ export default {
     },
     // 关闭倒计时弹窗
     handlecountdownTimeClose() {
-      const { userCardId } = this.parametersData;
-      this.$axios.get(`/resources/yearMember/closeRemind?userCardId=${userCardId}`).then(res => {
+      this.$axios.get(`/resources/yearMember/closeRemind?userCardId=${this.userCardId}`).then(res => {
         if (!res.status) {
           clearInterval(this.countdownTimeInterval);
           this.timingVisible = false;
@@ -121,8 +130,7 @@ export default {
     },
     // 获取推荐列表
     getRecommend() {
-      const { userCardId } = this.parametersData;
-      this.$axios.get(`/public/v1/market/get/recommend?userCardId=${userCardId}`).then(res => {
+      this.$axios.get(`/public/v1/market/get/recommend?userCardId=${this.userCardId}`).then(res => {
         if (!res.status) {
           this.billingRulesVisible = false;
           this.recommendList = res.data;

+ 117 - 40
pages/rtcEngine/rtc.vue

@@ -17,7 +17,7 @@
     <LeftMenuPopup
       ref="leftMenuPopupRef"
       :engine="engine"
-      :userCardId="this.parametersData.userCardId"
+      :userCardId="activeCloud.userCardId"
       :levitatedSphereVisible.sync="levitatedSphereVisible"
       :latency="rtcNetwork.currentRoundTripTime"
       :groupList="groupList"
@@ -25,11 +25,12 @@
       :mealTypeObj="mealTypeObj"
       :imgFun="imgFun"
       @funcHandle="funcHandle"
+      @changeCloud="changeCloudHandle"
       @exit="exit"
     />
     
     <!-- 右侧popup -->
-    <!-- <RightPopup ref="rightPopupRef" :engine="engine" :userCardId="this.parametersData.userCardId" :levitatedSphereVisible.sync="levitatedSphereVisible" @shearplate="shearplate" @exit="exit"/> -->
+    <!-- <RightPopup ref="rightPopupRef" :engine="engine" :userCardId="activeCloud.userCardId" :levitatedSphereVisible.sync="levitatedSphereVisible" @shearplate="shearplate" @exit="exit"/> -->
 
     <!-- 输入并复制到粘贴板 -->
     <InputCopy ref="inputCopyRef" @openPasteboard="openPasteboard"/>
@@ -41,7 +42,7 @@
     <TimeoutNoOps ref="timeoutNoOpsRef" />
 
     <!-- 计时卡计时 | 计费规则 | 应用推荐 -->
-    <TimeBalance ref="timeBalanceRef" :parametersData="parametersData" @downline="$refs.rightPopupRef.downline()"/>
+    <TimeBalance ref="timeBalanceRef" :parametersData="parametersData" :userCardId="activeCloud.userCardId" :userCardType="parametersData.userCardType" @downline="$refs.rightPopupRef.downline()"/>
   </div>
 </template>
 
@@ -153,10 +154,10 @@ export default {
         /**
          * @description: 传递的参数
          * @param {String} record 数据id
-         * @param {Number} userCardId 云机的id
+         * @param {Number} userCardId 必传 云机的id
          * @param {String} mealType 云机套餐类型 eg: VIP、STARBALL...
          * @param {Number} sourceType 云机来源: 0:购买  1试用 2:免费激活码 3:免费活动抽奖 4:ar app注册 5:9.9元套餐年卡 ',
-         * @param {Number} userCardType 云机的类型  0 普通套餐 1、2、3:年卡、普通计时、自动续费普通计时 
+         * @param {Number} userCardType 必传 云机的类型  0 普通套餐 1、2、3:年卡、普通计时、自动续费普通计时 
          * @param {Number} validTime 卡的有效期
          * @param {String} rm 卡所在的机房
          * @param {Number} isShowCountdown 是否显示倒计时 0:否 1:是
@@ -165,19 +166,24 @@ export default {
          * @param {String} isFirstConnect 是否是首次连接
          * @param {Number} authPhone  0自身购买的云手机 1获取得到的云手机
          * @param {String} username 用户名
-         * @param {String} token token
-         * @param {Number} isTips 是否显示提示 0:否 1:是
-         * @param {Number} isWeixin 是否是微信小程序环境 0:否 1:是
-         * @param {String} merchantSign 商户标识
+         * @param {String} token 必传 token
+         * @param {Number} isTips 必传 是否显示提示 0:否 1:是
+         * @param {Number} isWeixin 必传 是否是微信小程序环境 0:否 1:是
+         * @param {String} merchantSign 必传 商户标识
          */
       },
+
+      // 当前使用的云机数据
+      activeCloud: {},
+
       // 卡的连接信息
       connectData: {},
       // 云手机引擎 播放器实例
       engine: {},
+      // webRtc网络分析数据
       rtcNetwork: {
         currentRoundTripTime: 0, // 当前往返时间(网络延迟)
-      }, // webRtc网络分析数据
+      },
       doConnectDirectivesWs: null, // 云手机指令通道
       doConnectDirectivesIntervalerPing: null, // 业务通道定时标识 云手机指令通道心跳
       doConnectDirectivesRequestNum: 1, // 业务通道重连次数
@@ -193,11 +199,22 @@ export default {
     this.parametersData = this.$route.query;
 
     // 获取用户所有云机列表
-    this.getCloudList();
+    await this.getCloudList();
+
+    // 获取当前云机信息
+    this.activeCloud = this.cloudList.find(item => item.userCardId === +this.parametersData.userCardId);
+
     // 获取所有云机套餐信息
-    this.getMealIconInfo();
+    await this.getMealIconInfo();
     // 获取云机分组
-    this.getCloudGroupId();
+    await this.getCloudGroupId();
+
+    if(this.sdkLoadStatus === 'success') {
+      // 开始运行程序
+      this.start(this.activeCloud);
+    }else {
+      console.log('SDK加载失败');
+    }
   },
   computed: {
     // 是否为微信浏览器环境
@@ -206,10 +223,6 @@ export default {
     },
   },
   created() {
-    this.$toast.loading({
-        duration: 0, // 持续展示 toast
-        message: '数据加载中...',
-    });
     // 设置html标签的背景为黑色
     document.body.style.background = '#000';
 
@@ -217,21 +230,8 @@ export default {
     window.$_script_loadHandler = async ()=> {
       console.log('$_script_loadHandler: SDK加载成功');
       this.sdkLoadStatus = 'success';
-
-      // 初始化日志上报
-      this.initLogReport();
-
-      // 调用接口获取卡连接数据
-      const cardData = await this.getConnectData(this.parametersData);
-      
-      // 判断卡的连接方式
-      const connectData = await this.judgeConnectType(cardData);
-
-      // 保存卡连接信息
-      this.connectData = connectData;
-
-      this.initWebRtc();
     };
+
     window.$_script_errHandler = ()=> {
       console.log('SDK加载失败');
       this.sdkLoadStatus = 'error';
@@ -329,14 +329,13 @@ export default {
       }
     },
     // 获取卡的信息
-    async getConnectData(params) {
-      let userCardId = params.userCardId;
+    async getConnectData({isWeixin, merchantSign}) {
+      let userCardId = this.activeCloud.userCardId;
       try {
         // 设置上报参数
         this.logReportObj.setParams({userCardId});
 
         let isWx = this.$userAgent.isWx;
-        let { isWeixin } = params;
         let clientType = (+isWeixin || isWx) ? 'wx' : undefined;
 
         // 设置上报参数
@@ -345,7 +344,7 @@ export default {
 
         const res = await this.$axios.$post('/resources/user/cloud/connect', { userCardId }, {
           headers: {
-            merchantSign: params.merchantSign,
+            merchantSign,
           },
         });
         if (!res.success) {
@@ -476,7 +475,7 @@ export default {
             `webRtc连接,获取请求中转地址为空:
             url: /api/resources/user/cloud/connect
             method: post
-            参数: ${JSON.stringify({ userCardId: this.parametersData.userCardId })}
+            参数: ${JSON.stringify({ userCardId: this.activeCloud.userCardId })}
             响应: ${JSON.stringify(res)}`
           );
           return Promise.reject(new Error('网络分析请求地址不存在'));
@@ -535,7 +534,7 @@ export default {
           isMuted: false, // 是否静音
           isAllowedOpenCamera: true, // 是否允许打开摄像头
           sendFollow: true, // 是否允许主控转发文本到实例
-          callback: (event)=> {}
+          callback: (event)=> {console.log('webRTC回调', event);}
         };
 
         // 设置日志参数 推流质量 
@@ -563,6 +562,9 @@ export default {
       engine.on('CONNECT_SUCCESS', (r) => {
         console.log("webrtc连接成功====★★★★★", r);
         if (r.code === 1005) { // 1005: 拉流鉴权成功
+          // 清除loading
+          this.$toast.clear();
+
           // 设置日志 推流状态为成功
           let now = new Date();
           this.logReportObj.setParams({plugFowStatus: 1, linkWay: 1, timeConsuming: now.getTime() - this.logReportObj.timeStartTime, linkEndTime: this.logReportObj.formatDate(now)});
@@ -586,6 +588,7 @@ export default {
       
       // 网络连接统计信息监听
       engine.on('NETWORK_STATS', (r) => {
+        console.log("webrtc网络连接统计信息监听====★★★★★", r);
         this.rtcNetwork = r;
       });
 
@@ -644,9 +647,6 @@ export default {
           // 日志上报
           this.logReportObj.collectLog( `消息: 业务通道连接成功` );
 
-          // 清除loading
-          this.$toast.clear();
-
           // 重置重连次数
           this.doConnectDirectivesRequestNum = 1;
 
@@ -750,6 +750,34 @@ export default {
           break;
       }
     },
+    // 切换云机
+    async changeCloudHandle(cloudData) {
+      try {
+        // 保存当前云机数据
+        this.activeCloud = cloudData;
+
+        // 重置相关数据
+        // 关闭日志上报
+        this.logReportObj.destroy();
+        // 关闭webRTC
+        this.engine.disconnect && this.engine.disconnect();
+        // 关闭业务指令通道
+        this.doConnectDirectivesWs && this.doConnectDirectivesWs.close();
+        // 重置重连次数
+        this.doConnectDirectivesRequestNum = 1;
+        // 重置 end
+
+
+        if(this.sdkLoadStatus === 'success') {
+          // 开始运行程序
+          this.start(cloudData);
+        }else {
+          console.log('SDK加载失败');
+        }
+      } catch (error) {
+        console.log('changeCloud error', error);
+      }
+    },
     // 重新设置视频尺寸
     changeVideoStyle() {
       this.$nextTick(() => {
@@ -818,6 +846,32 @@ export default {
         this.logReportObj.setParams({ clientType: Object.keys(res)[0] });
       })
     },
+    // 开始运行程序
+    async start(activeCloud) {
+      try {
+        this.$toast.loading({
+          className: 'rtc-loading',
+          duration: 0, // 持续展示 toast
+          message: `设备(${activeCloud.userCardId})正在获取...`,
+        });
+
+        // 初始化日志上报
+        this.initLogReport();
+
+        // 调用接口获取卡连接数据
+        const cardData = await this.getConnectData(this.parametersData);
+        
+        // 判断卡的连接方式
+        const connectData = await this.judgeConnectType(cardData);
+
+        // 保存卡连接信息
+        this.connectData = connectData;
+
+        this.initWebRtc();
+      } catch (error) {
+        console.log('start error', error);
+      }
+    },
   }
 }
 </script>
@@ -879,4 +933,27 @@ $-bg-yellow: rgb(255, 253, 241);
   align-items: center;
   color: #fff;
 }
+
+.rtc-page >>> .van-toast.rtc-loading{
+  white-space: nowrap;
+}
+// 样式穿透的常用方法
+
+// 在SCSS中,样式穿透可以通过以下几种方式实现:
+
+// 使用>>>操作符: 这是一个深度选择器,它可以穿透scoped样式,使得样式可以作用于子组件。在SCSS中,你可以这样写: .parent >>> .child { color: red; } 这段代码会被编译成.parent[data-v-f3f3eg9] .child { color: red; },从而实现样式穿透。
+
+// 使用/deep/或::v-deep: 这两个操作符是>>>的别名,它们在不同的预处理器中有不同的应用。在SCSS中,你可以使用::v-deep来实现样式穿透: .parent ::v-deep .child { color: red; } 在LESS中,你可以使用/deep/来实现相同的效果: .parent /deep/ .child { color: red; }
+
+// 直接在<style>标签中写入: 如果你不使用预处理器,可以直接在<style>标签中使用>>>操作符: .parent >>> .child { color: red; }
+
+// 注意事项
+
+// 使用样式穿透时,需要注意选择器的具体写法,以确保样式能够正确应用。
+
+// 在不同的预处理器中,样式穿透的写法可能会有所不同。例如,在LESS中使用/deep/,而在SCSS中使用::v-deep。
+
+// 有些预处理器可能无法正确解析>>>操作符,这时可以使用/deep/或::v-deep作为替代。
+
+// 通过上述方法,我们可以在保持样式封装的同时,对第三方组件库中的样式进行定制化修改,实现更加精细的样式控制。
 </style>