jinx 4 лет назад
Родитель
Сommit
1bc61f7a8a
40 измененных файлов с 1117 добавлено и 71 удалено
  1. 3 1
      apps/RealtorEasier/app.json
  2. 2 1
      apps/RealtorEasier/components/detail-components/detail-scroll/detail-scroll.js
  3. 3 2
      apps/RealtorEasier/components/detail-components/detail-scroll/detail-scroll.wxml
  4. 1 1
      apps/RealtorEasier/components/house-item/house-item.wxml
  5. 1 1
      apps/RealtorEasier/components/trtc-room/common/constants.js
  6. 1 1
      apps/RealtorEasier/components/trtc-room/trtc-room.js
  7. 1 1
      apps/RealtorEasier/pages/city/city.wxml
  8. 1 1
      apps/RealtorEasier/pages/index/index.js
  9. 240 0
      apps/RealtorEasier/pages/room/room.js
  10. 7 0
      apps/RealtorEasier/pages/room/room.json
  11. 3 0
      apps/RealtorEasier/pages/room/room.wxml
  12. 1 0
      apps/RealtorEasier/pages/room/room.wxss
  13. 62 0
      apps/RealtorEasier/pages/room/unit/GenerateTestUserSig.js
  14. 2 0
      apps/RealtorEasier/pages/room/unit/lib-generate-test-usersig-es.min.js
  15. 29 2
      apps/RealtorEasier/pages/web/web.js
  16. 2 1
      apps/RealtorEasier/utils/imSend.js
  17. 47 13
      apps/RealtorEasier/utils/socket-handle.js
  18. 3 2
      apps/agent/apis/agent.js
  19. 1 0
      apps/agent/app.json
  20. 3 1
      apps/agent/components/client-item/client-item.js
  21. 1 1
      apps/agent/components/detail-components/detail-scroll/detail-scroll.js
  22. 2 2
      apps/agent/components/detail-components/detail-scroll/detail-scroll.wxml
  23. 1 1
      apps/agent/components/house-item/house-item.wxml
  24. 2 1
      apps/agent/components/tabs-house-list/tabs-house-list.wxml
  25. 1 1
      apps/agent/components/trtc-room/trtc-room.js
  26. 7 6
      apps/agent/pages/add-client/add-client.js
  27. 3 2
      apps/agent/pages/add-client/add-client.wxml
  28. 7 4
      apps/agent/pages/client-detail/client-detail.js
  29. 2 2
      apps/agent/pages/client-detail/client-detail.wxml
  30. 8 8
      apps/agent/pages/index/index.js
  31. 62 0
      apps/agent/pages/room/GenerateTestUserSig.js
  32. 2 0
      apps/agent/pages/room/lib-generate-test-usersig-es.min.js
  33. 337 0
      apps/agent/pages/room/room.js
  34. 6 0
      apps/agent/pages/room/room.json
  35. 53 0
      apps/agent/pages/room/room.wxml
  36. 145 0
      apps/agent/pages/room/room.wxss
  37. 26 3
      apps/agent/pages/web/web.js
  38. 2 1
      apps/agent/utils/imSend.js
  39. 35 11
      apps/agent/utils/socket-handle.js
  40. 2 0
      apps/agent/utils/utils.js

+ 3 - 1
apps/RealtorEasier/app.json

@@ -1,6 +1,9 @@
 {
   "pages": [
+
     "pages/index/index",
+    "pages/room/room",
+
     "pages/detail/detail",
     "pages/contact/contact",
     "pages/my/my",
@@ -19,7 +22,6 @@
     "pages/detail-intro/detail-intro",
     "pages/view-history/view-history",
     "pages/shared/shared"
-    
   ],
   "usingComponents": {
     "search-bar": "components/searchbar/searchbar",

+ 2 - 1
apps/RealtorEasier/components/detail-components/detail-scroll/detail-scroll.js

@@ -327,7 +327,8 @@ Component({
         house_type: house.house_type,
         house_area: house.area,
         orientation: house.orientation,
-        price: `${(house.price/10000).toFixed(0)}万`,
+        // price: `${(house.price/10000).toFixed(0)}万`,
+        price: `${house.price}`,
         vr_link: is_vr_invite ? `${house.vrLink}${encodeURIComponent(`&room_id=${room_id}`)}` : '',
         house_id: house.house_id
       }

+ 3 - 2
apps/RealtorEasier/components/detail-components/detail-scroll/detail-scroll.wxml

@@ -34,7 +34,8 @@
         <view class="house-parameter">
             <view class="parameter-item">
                 <!-- <view class="price">${{ house.price / 10000 }}万</view> -->
-                <view class="price">${{ house.price/10000 }}万</view>
+                <!-- <view class="price">${{ house.price/10000 }}万</view> -->
+                <view class="price">${{ house.price }}</view>
                 <view class="parameter-name">售价</view>
             </view>
             <view class="parameter-item">
@@ -54,7 +55,7 @@
                 <text class="value"> <text class="value" wx:if="{{item.name=='unit_price' }}"> $</text>{{ item.value
                     }}</text>
                 <text class="value" wx:if="{{item.name=='bedroomAmount' ||item.name=='showerroomAmount' }}"></text>
-                <text class="value" wx:if="{{item.name=='unit_price' }}"></text>
+                <text class="value" wx:if="{{item.name=='unit_price' }}"></text>
                 <text class="value" wx:if="{{item.name=='area' ||item.name=='floorSpace' }}">平方英尺</text>
             </view>
         </view>

+ 1 - 1
apps/RealtorEasier/components/house-item/house-item.wxml

@@ -20,7 +20,7 @@
       </view>
     <view class="price-w">
         <!-- <text class="price text-bold">${{ house.price/10000 }}万</text> -->
-        <text class="price text-bold">${{ house.price /10000}}</text>
+        <text class="price text-bold">${{ house.price }}</text>
         <!-- <text class="price-tip">{{ house.unit_price }}元/平</text> -->
       </view>
     </view>

+ 1 - 1
apps/RealtorEasier/components/trtc-room/common/constants.js

@@ -30,7 +30,7 @@ export const DEFAULT_COMPONENT_CONFIG = {
   userID: '',
   userSig: '',
   template: '',
-  debugMode: false, // 是否开启调试模式
+  debugMode: true, // 是否开启调试模式
   enableIM: false, // 是否开启 IM
 }
 

+ 1 - 1
apps/RealtorEasier/components/trtc-room/trtc-room.js

@@ -25,7 +25,7 @@ Component({
         userID: '',
         userSig: '',
         template: '',
-        debugMode: false, // 是否开启调试模式
+        debugMode: true, // 是否开启调试模式
         enableIM: false, // 是否开启 IM
       },
       observer: function(newVal, oldVal) {

+ 1 - 1
apps/RealtorEasier/pages/city/city.wxml

@@ -9,7 +9,7 @@
 </view>
 
 <view class="location-w">
-    <view class="city-label">选择城市</view>
+    <view class="city-label">默认城市</view>
     <view class="search-input" bindtap="selectLocation">
         <text>{{ city }}</text>
         <view class="refresh-btn " animation="{{animation}}" catchtap="getLocation"></view>

+ 1 - 1
apps/RealtorEasier/pages/index/index.js

@@ -231,7 +231,7 @@ Page({
     onShareAppMessage: function (res) {
         var path = '/pages/index/index'
         return {
-            title: '四维看看,海量复刻真房源',
+            title: '美房理,海量复刻真房源',
             path: path,
             imageUrl: 'https://4d-tjw.oss-cn-shenzhen.aliyuncs.com/4dHouse/share.png', // 分享的封面图
         }

+ 240 - 0
apps/RealtorEasier/pages/room/room.js

@@ -0,0 +1,240 @@
+import {
+  genTestUserSig
+} from './unit/GenerateTestUserSig.js'
+import * as SocketHandle from '../../utils/socket-handle'
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+    userSig:'',
+    userID: '',
+    roomID: '1234567',
+    userList: [], // 主播list
+    trtcConfig: {
+      // scene: 'rtc',
+      // sdkAppID: '1400433526', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      sdkAppID: '1400537003', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      // userID: '1', // 用户 ID,可以由您的帐号系统指定
+      // userSig: '', // 身份签名,相当于登录密码的作用
+      // template: 'custom', // 画面排版模式
+      // debugMode: true,
+    }
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+   
+    this.setData({
+      userID : this.random(1,100).toString()
+    })
+    let opts = {
+      roomId: this.data.roomID,
+      userId: this.data.userID,
+      role: 'customer',
+      scene_num: '1'
+    }
+    this.socket = SocketHandle.initSocket(this, opts)
+    this.trtcComponent = this.selectComponent('#trtcroom')
+    this.bindTRTCRoomEvent()
+
+  },
+  bindUserID: function(e) {
+    this.setData({
+      userID: e.detail.value,
+    })
+  },
+
+  joinRoom() {
+    if(this.data.userID==""){
+      wx.showToast({
+        title: '输入用户id',
+      })
+      return
+    }
+    this.initRoom()
+    // this.getSignature()
+  
+  },
+  getSignature(userSig){
+    console.log('***********************')
+    console.log(userSig)
+    this.setData({
+      userSig:userSig
+    })
+  // this.data.userSig = userSig
+  },
+  random(lower, upper) {
+    return Math.floor(Math.random() * (upper - lower)) + lower;
+  },
+  initRoom() {
+    
+    const Signature = genTestUserSig(this.data.userID)
+    
+    this.enterRoom({
+      sdkAppID: Signature.sdkAppID,
+      userSig: this.data.userSig,
+    })
+  },
+  enterRoom({sdkAppID,userSig}) {
+    const template = 'custom'
+    const roomID = this.data.roomID
+  
+    this.setData({
+      trtcConfig:{
+        sdkAppID: sdkAppID, // 您的实时音视频服务创建应用后分配的 sdkAppID
+        userID: this.data.userID,
+        userSig: userSig,
+        template: template, // 1v1 grid custom
+        debugMode: true, // 非必要参数,打开组件的调试模式,开发调试时建议设置为 true
+        // audioVolumeType: this.data.audioVolumeType,
+      }
+    }, () => {
+      
+    
+      this.trtcComponent.enterRoom({
+        roomID: roomID
+      }).then((res) => {
+        console.log(res)
+        wx.showToast({
+          title: '成功进入房间',
+        })
+      }).catch((res) => {
+       
+        console.error('room  进房失败:', res)
+      })
+    })
+  },
+  bindTRTCRoomEvent: function() {
+    const TRTC_EVENT = this.trtcComponent.EVENT
+    // 初始化事件订阅
+    this.trtcComponent.on(TRTC_EVENT.LOCAL_JOIN, (event)=>{
+      console.log('* room LOCAL_JOIN', event)
+      this.trtcComponent.publishLocalAudio()
+      wx.showToast({
+        title: 'LOCAL_JOIN',
+      })
+      // 进房成功,触发该事件后可以对本地视频和音频进行设置
+      // if (this.data.role === 'presenter') {
+      //   this.trtcComponent.publishLocalAudio()
+      // }
+    })
+    // this.trtcComponent.on(TRTC_EVENT.LOCAL_LEAVE, (event)=>{
+    //   console.log('*本地用户离开', event)
+    // })
+    // this.trtcComponent.on(TRTC_EVENT.ERROR, (event)=>{
+    //   console.log('* room ERROR', event)
+    // })
+    // 远端用户进房
+    // this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_JOIN, (event)=>{
+    //   wx.showToast({
+    //     title: '远端用户进房',
+    //   })
+    //   console.log('* room REMOTE_USER_JOIN', event, this.trtcComponent.getRemoteUserList())
+    //   const userList = this.trtcComponent.getRemoteUserList()
+    //   // this.handleOnUserList(userList).then(() => {
+    //   //   console.log(this.data.userList)
+    //   // })
+    // })
+    // // 远端用户退出
+    // this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_LEAVE, (event)=>{
+    //   console.log('远端用户退出', event, this.trtcComponent.getRemoteUserList())
+    //   const userList = this.trtcComponent.getRemoteUserList()
+    //   // this.handleOnUserList(userList).then(() => {
+    //   //   console.log(this.data.userList)
+    //   // })
+    // })
+    // 远端用户推送音频
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event)=>{
+      wx.showToast({
+        title: '远端用户推送音频',
+      })
+      // if (this.data.userList.length < 6) {
+        // 订阅音频
+        const data = event.data
+        // 如果不订阅就不会自动播放音频
+        const userList = this.trtcComponent.getRemoteUserList()
+        // this.handleOnUserList(userList).then(() => {
+        //   console.log(this.data.userList)
+        // })
+        console.log('* room REMOTE_AUDIO_ADD', event, this.trtcComponent.getRemoteUserList())
+        this.trtcComponent.subscribeRemoteAudio({ userID: data.userID })
+      // }
+    })
+    this.trtcComponent.on('ERROR',(event)=>{
+      console.log('ERRORERRORERRORERRORERROR')
+      console.log(event)
+    })
+    // 远端用户取消推送音频
+    // this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, (event)=>{
+    //   console.log('远端用户取消推送音频', event, this.trtcComponent.getRemoteUserList())
+    //   const userList = this.trtcComponent.getRemoteUserList()
+    //   // this.handleOnUserList(userList).then(() => {
+    //   //   console.log(this.data.userList)
+    //   // })
+    // })
+    // this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_VOLUME_UPDATE, (event)=>{
+    //   const userID = event.data.target.dataset.userid
+    //   const volume = event.data.detail.volume
+    //   this.data.userList.forEach((item) =>{
+    //     if (item.userID === userID) {
+    //       item.volume = volume
+    //     }
+    //   })
+    //   this.setData({
+    //     userList: this.data.userList,
+    //   })
+    // })
+  },
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {
+
+  }
+})

+ 7 - 0
apps/RealtorEasier/pages/room/room.json

@@ -0,0 +1,7 @@
+{
+  "usingComponents": {
+    "trtc-room": "/components/trtc-room/trtc-room"
+  },
+  "navigationBarTitleText": "美房理",
+  "pageOrientation": "auto"
+}

+ 3 - 0
apps/RealtorEasier/pages/room/room.wxml

@@ -0,0 +1,3 @@
+<trtc-room id="trtcroom" config="{{trtcConfig}}"></trtc-room>
+<input value="{{userID}}" maxlength="20" bindinput='bindUserID' placeholder="请输入用户id" placeholder-style="color:#000;opacity: 0.55;"/>
+<button class="btn" bindtap="joinRoom" hover-class="none">进入房间</button>

+ 1 - 0
apps/RealtorEasier/pages/room/room.wxss

@@ -0,0 +1 @@
+/* pages/room/room.wxss */

+ 62 - 0
apps/RealtorEasier/pages/room/unit/GenerateTestUserSig.js

@@ -0,0 +1,62 @@
+import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js'
+
+/**
+ * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
+ *
+ * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
+ * 它是腾讯云用于区分客户的唯一标识。
+ */
+const SDKAPPID = 1400537003
+
+
+/**
+ * 签名过期时间,建议不要设置的过短
+ * <p>
+ * 时间单位:秒
+ * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
+ */
+const EXPIRETIME = 604800
+
+
+/**
+ * 计算签名用的加密密钥,获取步骤如下:
+ *
+ * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
+ * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
+ * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
+ *
+ * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
+ * 文档:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+const SECRETKEY = 'ab2efa0dae0be766759a2af26b8e81b4996af5909f0b4339026a162767094252'
+
+/*
+ * Module:   GenerateTestUserSig
+ *
+ * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
+ *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
+ *
+ * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
+ *
+ *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
+ *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
+ *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
+ *
+ *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
+ *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
+ *
+ * Reference:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+function genTestUserSig(userID) {
+  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME)
+  const userSig = generator.genTestUserSig(userID)
+
+  return {
+    sdkAppID: SDKAPPID,
+    userSig: userSig,
+  }
+}
+
+module.exports = {
+  genTestUserSig,
+}

Разница между файлами не показана из-за своего большого размера
+ 2 - 0
apps/RealtorEasier/pages/room/unit/lib-generate-test-usersig-es.min.js


+ 29 - 2
apps/RealtorEasier/pages/web/web.js

@@ -28,7 +28,15 @@ Page({
     hasBeLogin: false,
     vr_link: '',
     showLogin: false,
-    delegationShow: false
+    delegationShow: false,
+    trtcConfig: {
+      scene: 'rtc',
+      // sdkAppID: '1400433526', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      sdkAppID: '1400537003', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      userID: '', // 用户 ID,可以由您的帐号系统指定
+      userSig: '', // 身份签名,相当于登录密码的作用
+      template: 'custom', // 画面排版模式
+    }
   },
   /**
    * 生命周期函数--监听页面加载
@@ -210,6 +218,7 @@ Page({
   enterAudioRoom(user) {
     this.hasEnter = true
     getApp().globalData.audioUser = user
+    console.log(user, 'user')
     this.setData({
       trtcConfig: {
         scene: 'rtc',
@@ -218,13 +227,20 @@ Page({
         userID: user.userId, // 用户 ID,可以由您的帐号系统指定
         userSig: user.sig, // 身份签名,相当于登录密码的作用
         template: 'custom', // 画面排版模式
+        debugMode:true,
       }
     }, () => {
       this.trtcRoomContext = this.selectComponent('#trtcroom')
       let EVENT =this.trtcRoomContext.EVENT
-
+      console.log(EVENT)
       if (this.trtcRoomContext) {
+        this.publishLocalAudio()
+        console.log('**************')
+        console.log(EVENT.LOCAL_JOIN)
         this.trtcRoomContext.on(EVENT.LOCAL_JOIN, (event) => {
+          // wx.showToast({
+          //   title: '进房',
+          // })
           this.publishLocalAudio()
         })
 
@@ -232,6 +248,11 @@ Page({
        this.trtcRoomContext.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
           // 订阅(即播放)远端用户的音频流
           let userID = event.data.userID
+          // console.log('&&&&&&&&&&&')
+          // console.log(event)
+          // wx.showToast({
+          //   title: '订阅',
+          // })
          this.trtcRoomContext.subscribeRemoteAudio({
             userID: userID
           })
@@ -242,8 +263,11 @@ Page({
        this.trtcRoomContext.enterRoom({
           roomID: this.roomId
         }).then(() => {
+        
           console.log('成功进入房间')
+          console.log(this.roomId)
         }).catch((res) => {
+         
           console.error('room joinRoom 进房失败:', res)
         })
       }
@@ -254,5 +278,8 @@ Page({
   },
   publishLocalAudio () {
     this.trtcRoomContext && this.trtcRoomContext.publishLocalAudio()
+    // wx.showToast({
+    //   title: '推流',
+    // })
   }
 })

+ 2 - 1
apps/RealtorEasier/utils/imSend.js

@@ -7,7 +7,8 @@ export default {
       house_type: house.house_type,
       house_area: house.area,
       orientation: house.orientation,
-      price: `${(house.price/10000).toFixed(0)}万`,
+      // price: `${(house.price/10000).toFixed(0)}万`,
+      price: `${house.price}`,
       vr_link: is_vr_invite ? `${house.vrLink}${encodeURIComponent(`&room_id=${room_id}`)}` : '',
       house_id: house.house_id
     }

+ 47 - 13
apps/RealtorEasier/utils/socket-handle.js

@@ -1,21 +1,24 @@
 const socket_io = require('./socket.io-mp')
-const { IM_HOST } = require('../config/config')
+const {
+  IM_HOST
+} = require('../config/config')
 
 let io = ''
 export function initSocket(page, options) {
   const defaultOpts = {
     customerId: '',
     agentId: '',
-    role:'agent',
+    role: 'agent',
     nickName: '',
-    roomId:'',
+    roomId: '',
     isClient: true
   }
-  
+
   io = socket_io(IM_HOST, {
     path: '/vr-node',
     query: Object.assign(defaultOpts, options)
   })
+  
   const eventName = {
     startPlay: 'answer', // 开始语音
     someoneInRoom: 'vr_request', // 有人加入房间
@@ -27,15 +30,46 @@ export function initSocket(page, options) {
     console.log(data, 'startplay')
     page.startPlay(data)
   })
-
+  io.on('test', function (data) {
+    // console.log('********************')
+    // page.getSignature(data)
+  })
+  // let user = data.persons.find(item => item.userId === getApp().globalData.userinfo.user_id)
+  // console.log(user)
+  // page.enterAudioRoom(getApp().globalData.userinfo.user_id)
   io.on(eventName.someoneInRoom, function (data) {
+ 
     if (data.persons.length < 2) {
       return
     }
+ 
     let user = data.persons.find(item => item.userId === getApp().globalData.userinfo.user_id)
-    console.log('&&&&&&&&&&&&&&&&&')
-    console.log(user)
-    page.enterAudioRoom(user)
+    // page.getSignature(user)
+    // console.log(user)
+    // page.enterAudioRoom(user)
+    wx.getSetting({
+      success: (res) => {
+        if (!res.authSetting['scope.record']) {
+          wx.authorize({
+            scope: 'scope.record',
+            success: (res) => {
+              // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
+              console.log('同意', res);
+             
+              page.enterAudioRoom(user)
+            },
+            fail: res => {
+              console.log('拒绝', res);
+              // cbError && cbError();
+            }
+          })
+        } else {
+        
+          page.enterAudioRoom(user)
+        }
+      }
+    })
+
   })
 
   io.on(eventName.someoneLeaveRoom, function (data) {
@@ -50,7 +84,7 @@ export function initSocket(page, options) {
   return io
 }
 
-export function emitSendMsg (target_id) {
+export function emitSendMsg(target_id) {
   let app = getApp()
   io.emit('sendMsg', {
     user_id: app.globalData.userinfo.user_id,
@@ -58,7 +92,7 @@ export function emitSendMsg (target_id) {
   })
 }
 
-export function emitInRoom () {
+export function emitInRoom() {
   let app = getApp()
   io.emit('inRoom', {
     user_id: app.globalData.userinfo.user_id,
@@ -66,7 +100,7 @@ export function emitInRoom () {
   })
 }
 
-export function emitLeaveRoom () {
+export function emitLeaveRoom() {
   let app = getApp()
   io.emit('leaveRoom', {
     user_id: app.globalData.userinfo.user_id,
@@ -74,6 +108,6 @@ export function emitLeaveRoom () {
   })
 }
 
-export function disconnect () {
+export function disconnect() {
   return io.disconnect()
-}
+}

+ 3 - 2
apps/agent/apis/agent.js

@@ -8,8 +8,9 @@ export default {
     })
   },
   // 客户详情
-  fetchCustomerDetail ({ agency_user_id, user_id }) {
-    return request.get('agency/customer/detail', { agency_user_id, user_id })
+  // fetchCustomerDetail ({ agency_user_id, user_id }) {
+  fetchCustomerDetail ({ id  }) {
+    return request.get('agency/customer/detail', { id })
   },
   // 获取客源列表
   fetchCustomers (data) {

+ 1 - 0
apps/agent/app.json

@@ -3,6 +3,7 @@
 
     "pages/index/index",
     "pages/my/my",
+    "pages/room/room",
 
     "pages/detail/detail",
     "pages/city/city",

+ 3 - 1
apps/agent/components/client-item/client-item.js

@@ -19,10 +19,12 @@ Component({
   /**
    * 组件的方法列表
    */
+
   methods: {
     toDetail () {
       wx.navigateTo({
-        url: `/pages/client-detail/client-detail?agency_user_id=${this.properties.client.agency_user_id}&user_id=${this.properties.client.user_id}`
+        // url: `/pages/client-detail/client-detail?agency_user_id=${this.properties.client.agency_user_id}&user_id=${this.properties.client.user_id}`
+        url: `/pages/client-detail/client-detail?id=${this.properties.client.id}`
       })
     },
     makePhoneCall(){

+ 1 - 1
apps/agent/components/detail-components/detail-scroll/detail-scroll.js

@@ -326,7 +326,7 @@ Component({
         house_type: house.house_type,
         house_area: house.area,
         orientation: house.orientation,
-        price: `${(house.price/10000).toFixed(0)}`,
+        price: `${house.price}`,
         vr_link: is_vr_invite ? `${house.vrLink}${encodeURIComponent(`&room_id=${room_id}`)}` : '',
         house_id: house.house_id
       }

+ 2 - 2
apps/agent/components/detail-components/detail-scroll/detail-scroll.wxml

@@ -34,7 +34,7 @@
         <view class="house-parameter">
             <view class="parameter-item">
                 <!-- <view class="price">${{ house.price / 10000 }}万</view> -->
-                <view class="price">${{ house.price/10000 }}</view>
+                <view class="price">${{ house.price }}</view>
                 <view class="parameter-name">售价</view>
             </view>
             <view class="parameter-item">
@@ -54,7 +54,7 @@
                 <text class="value"> <text class="value" wx:if="{{item.name=='unit_price' }}"> $</text>{{ item.value
                     }}</text>
                 <text class="value" wx:if="{{item.name=='bedroomAmount' ||item.name=='showerroomAmount' }}"></text>
-                <text class="value" wx:if="{{item.name=='unit_price' }}"></text>
+                <text class="value" wx:if="{{item.name=='unit_price' }}"></text>
                 <text class="value" wx:if="{{item.name=='area' ||item.name=='floorSpace' }}">平方英尺</text>
             </view>
         </view>

+ 1 - 1
apps/agent/components/house-item/house-item.wxml

@@ -20,7 +20,7 @@
       </view>
     <view class="price-w">
         <!-- <text class="price text-bold">${{ house.price/10000 }}万</text> -->
-        <text class="price text-bold">${{ house.price /10000}}</text>
+        <text class="price text-bold">${{ house.price }}</text>
         <!-- <text class="price-tip">{{ house.unit_price }}元/平</text> -->
       </view>
     </view>

+ 2 - 1
apps/agent/components/tabs-house-list/tabs-house-list.wxml

@@ -1,11 +1,12 @@
 <!-- <van-tabs active="{{ active }}" line-width="20" color="#1FE4DC" bind:change="onChange">
   <van-tab title="{{ tabs.name }}" wx:for="{{tabs}}" wx:for-item="tabs" wx:key="index"> -->
     <view >
-      <view class="no-data" wx:if="{{tabs.house_list.length === 0}}">暂无数据</view>
+      <view class="no-data" wx:if="{{tabs[0].house_list.length === 0}}">暂无数据</view>
       <view class="house-list" wx:else>
         <house-item wx:for="{{ tabs[0].house_list }}" house="{{ item }}" wx:key="id" />
       </view>
       <no-more-bar wx:if="{{tabs[0].house_list.length !== 0}}" />
     </view>
+    <view>{{tabs.house_list.length }}</view>
   <!-- </van-tab>
 </van-tabs> -->

+ 1 - 1
apps/agent/components/trtc-room/trtc-room.js

@@ -25,7 +25,7 @@ Component({
         userID: '',
         userSig: '',
         template: '',
-        debugMode: false, // 是否开启调试模式
+        debugMode: true, // 是否开启调试模式
         enableIM: false, // 是否开启 IM
       },
       observer: function(newVal, oldVal) {

+ 7 - 6
apps/agent/pages/add-client/add-client.js

@@ -76,14 +76,15 @@ Page({
         }
     },
     onLoad: function(options) {
-        const { customer_id, agency_user_id } = options
+        // const { customer_id, agency_user_id } = options
+        const { id } = options
         console.log(options)
-        if (customer_id && agency_user_id) {
-            this.fetchCustomerDetail(agency_user_id, customer_id)
-        }
+        // if (customer_id && agency_user_id) {
+            this.fetchCustomerDetail(id)
+        // }
     },
-    fetchCustomerDetail (agency_user_id,user_id) {
-        agentApi.fetchCustomerDetail({agency_user_id,user_id}).then(res => {
+    fetchCustomerDetail (id) {
+        agentApi.fetchCustomerDetail({id}).then(res => {
             if (res.data) {
                 const exg = /(\d*)-(\d*)/
               this.setData({

+ 3 - 2
apps/agent/pages/add-client/add-client.wxml

@@ -49,8 +49,9 @@
 
   <view class="c-more">
     <view class="add-item">
-      <text>客户需求1(选填)</text>
-      <text style="color:#1FE4DC">添加</text>
+      <!-- <text>客户需求1(选填)</text> -->
+      <text>客户需求</text>
+      <!-- <text style="color:#1FE4DC">添加</text> -->
     </view>
 
     <view class="add-item">

+ 7 - 4
apps/agent/pages/client-detail/client-detail.js

@@ -69,13 +69,16 @@ Page({
   onLoad: function (options) {
     app.wxshowloading('拼命加载中...');
     let {agency_user_id,user_id} = options
+    let {id} = options
+   
+    this.id = id
     this.user_id = user_id
     this.agency_user_id = agency_user_id
   },
 
 
-  getClientDetail (agency_user_id,user_id) {
-    agentApi.fetchCustomerDetail({agency_user_id,user_id}).then(res => {
+  getClientDetail (id) {
+    agentApi.fetchCustomerDetail({id}).then(res => {
       if (res.data) {
         this.setData({
           agent_user: res.data
@@ -101,7 +104,7 @@ Page({
    * 生命周期函数--监听页面显示
    */
   onShow: function () {
-    this.getClientDetail(this.agency_user_id, this.user_id)
+    this.getClientDetail(this.id)
   },
 
   /**
@@ -139,7 +142,7 @@ Page({
   },
   toEdit () {
     wx.navigateTo({
-      url: `/pages/add-client/add-client?customer_id=${this.user_id}&agency_user_id=${this.agency_user_id}`,
+      url: `/pages/add-client/add-client?id=${this.id}`,
     })
   }
 })

+ 2 - 2
apps/agent/pages/client-detail/client-detail.wxml

@@ -36,8 +36,8 @@
 
   </view>
   <view class="hover-btn">
-    <view class="btn" bindtap="toChat">发消息</view>
-    <view bindtap="makePhoneCall" class="btn tocontract">去联系</view>
+    <!-- <view class="btn" bindtap="toChat">发消息</view> -->
+    <view bindtap="makePhoneCall" style="width:100%;" class="btn tocontract">去联系</view>
   </view>
     
 </view>

+ 8 - 8
apps/agent/pages/index/index.js

@@ -59,16 +59,16 @@ const panelData={
                 name:'不限',
                 id:''
             },{
-                name:'1',
+                name:'1',
                 id:'1'
             },{
-                name:'2',
+                name:'2',
                 id:'2'
             },{
-                name:'3',
+                name:'3',
                 id:'3'
             },{
-                name:'4',
+                name:'4',
                 id:'4'
             }]
     }],
@@ -79,16 +79,16 @@ const panelData={
             name:'不限',
             id:''
         },{
-            name:'1',
+            name:'1',
             id:'1'
         },{
-            name:'2',
+            name:'2',
             id:'2'
         },{
-            name:'3',
+            name:'3',
             id:'3'
         },{
-            name:'4',
+            name:'4',
             id:'4'
         }]
 }]

+ 62 - 0
apps/agent/pages/room/GenerateTestUserSig.js

@@ -0,0 +1,62 @@
+import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js'
+
+/**
+ * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
+ *
+ * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
+ * 它是腾讯云用于区分客户的唯一标识。
+ */
+const SDKAPPID = 1400537003
+
+
+/**
+ * 签名过期时间,建议不要设置的过短
+ * <p>
+ * 时间单位:秒
+ * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
+ */
+const EXPIRETIME = 604800
+
+
+/**
+ * 计算签名用的加密密钥,获取步骤如下:
+ *
+ * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
+ * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
+ * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
+ *
+ * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
+ * 文档:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+const SECRETKEY = 'ab2efa0dae0be766759a2af26b8e81b4996af5909f0b4339026a162767094252'
+
+/*
+ * Module:   GenerateTestUserSig
+ *
+ * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
+ *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
+ *
+ * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
+ *
+ *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
+ *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
+ *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
+ *
+ *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
+ *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
+ *
+ * Reference:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+function genTestUserSig(userID) {
+  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME)
+  const userSig = generator.genTestUserSig(userID)
+
+  return {
+    sdkAppID: SDKAPPID,
+    userSig: userSig,
+  }
+}
+
+module.exports = {
+  genTestUserSig,
+}

Разница между файлами не показана из-за своего большого размера
+ 2 - 0
apps/agent/pages/room/lib-generate-test-usersig-es.min.js


+ 337 - 0
apps/agent/pages/room/room.js

@@ -0,0 +1,337 @@
+import { genTestUserSig } from './GenerateTestUserSig.js'
+const app = getApp()
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+    roomID: 1, // 房间号
+    role: '',
+    userList: [], // 主播list
+    userID: '',
+    debugMode: false,
+    initialRole: '',
+    showRolePanel: false,
+    presenterConfig: {
+      enableMic: true,
+      muteAllAudio: false,
+    },
+    headerHeight: app.globalData.headerHeight,
+    statusBarHeight: app.globalData.statusBarHeight,
+    rtcConfig: {
+      sdkAppID: '1400537003', // 必要参数 开通实时音视频服务创建应用后分配的 sdkAppID
+      userID: '', // 必要参数 用户 ID 可以由您的帐号系统指定
+      userSig: '', // 必要参数 身份签名,相当于登录密码的作用
+      template: '', // 必要参数 组件模版,支持的值 1v1 grid custom ,注意:不支持动态修改, iOS 不支持 pusher 动态渲染
+    },
+  },
+  enterRoom: function({ sdkAppID, userSig }) {
+    const template = 'custom'
+    const roomID = this.data.roomID
+    console.log('* room enterRoom', roomID, template)
+    this.data.rtcConfig = {
+      sdkAppID: sdkAppID, // 您的实时音视频服务创建应用后分配的 sdkAppID
+      userID: '2',
+      userSig: userSig,
+      template: template, // 1v1 grid custom
+      debugMode: this.data.debugMode, // 非必要参数,打开组件的调试模式,开发调试时建议设置为 true
+      audioVolumeType: this.data.audioVolumeType,
+    }
+    this.setData({
+      rtcConfig: this.data.rtcConfig,
+    }, () => {
+      // 进房前决定是否推送视频或音频
+      if (this.data.role === 'presenter') {
+        this.trtcComponent.publishLocalAudio()
+      }
+      // roomID 取值范围 1 ~ 4294967295
+      this.trtcComponent.enterRoom({ roomID: roomID })
+    })
+  },
+  getSignature: function(userID) {
+    console.log('* room getSignature', userID)
+    const Signature = genTestUserSig(userID)
+   
+    this.enterRoom({
+      sdkAppID: Signature.sdkAppID,
+      userSig: Signature.userSig,
+    })
+  },
+  bindTRTCRoomEvent: function() {
+    const TRTC_EVENT = this.trtcComponent.EVENT
+    // 初始化事件订阅
+    this.trtcComponent.on(TRTC_EVENT.LOCAL_JOIN, (event)=>{
+      console.log('* room LOCAL_JOIN', event)
+      // 进房成功,触发该事件后可以对本地视频和音频进行设置
+      // if (this.data.role === 'presenter') {
+      //   this.trtcComponent.publishLocalAudio()
+      // }
+    })
+    this.trtcComponent.on(TRTC_EVENT.LOCAL_LEAVE, (event)=>{
+      console.log('* room LOCAL_LEAVE', event)
+    })
+    this.trtcComponent.on(TRTC_EVENT.ERROR, (event)=>{
+      console.log('* room ERROR', event)
+    })
+    // 远端用户进房
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_JOIN, (event)=>{
+      console.log('* room REMOTE_USER_JOIN', event, this.trtcComponent.getRemoteUserList())
+      const userList = this.trtcComponent.getRemoteUserList()
+      this.handleOnUserList(userList).then(() => {
+        console.log(this.data.userList)
+      })
+    })
+    // 远端用户退出
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_LEAVE, (event)=>{
+      console.log('* room REMOTE_USER_LEAVE', event, this.trtcComponent.getRemoteUserList())
+      const userList = this.trtcComponent.getRemoteUserList()
+      this.handleOnUserList(userList).then(() => {
+        console.log(this.data.userList)
+      })
+    })
+    // 远端用户推送音频
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event)=>{
+      if (this.data.userList.length < 6) {
+        // 订阅音频
+        const data = event.data
+        // 如果不订阅就不会自动播放音频
+        const userList = this.trtcComponent.getRemoteUserList()
+        this.handleOnUserList(userList).then(() => {
+          console.log(this.data.userList)
+        })
+        console.log('* room REMOTE_AUDIO_ADD', event, this.trtcComponent.getRemoteUserList())
+        this.trtcComponent.subscribeRemoteAudio({ userID: data.userID })
+      }
+    })
+    // 远端用户取消推送音频
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, (event)=>{
+      console.log('* room REMOTE_AUDIO_REMOVE', event, this.trtcComponent.getRemoteUserList())
+      const userList = this.trtcComponent.getRemoteUserList()
+      this.handleOnUserList(userList).then(() => {
+        console.log(this.data.userList)
+      })
+    })
+    this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_VOLUME_UPDATE, (event)=>{
+      const userID = event.data.target.dataset.userid
+      const volume = event.data.detail.volume
+      this.data.userList.forEach((item) =>{
+        if (item.userID === userID) {
+          item.volume = volume
+        }
+      })
+      this.setData({
+        userList: this.data.userList,
+      })
+    })
+  },
+  handleOnUserList: function(userList) {
+    return new Promise((resolve, reject) => {
+      const newUserList = []
+      let index = 0
+      const oldUserList = this.data.userList
+      userList.forEach((item) => {
+        if (item.hasMainAudio) {
+          const user = this.judgeWhetherExist({ userID: item.userID, streamType: 'main' }, oldUserList)
+          index += 1
+          if (user) {
+            // 已存在
+            newUserList.push(Object.assign(user, { index: index }))
+          } else {
+            newUserList.push({
+              userID: item.userID,
+              streamType: 'main',
+              index: index,
+              hasMainAudio: item.hasMainAudio,
+              volume: 0,
+            })
+          }
+        }
+      })
+      this.setData({
+        userList: newUserList,
+      }, () => {
+        console.log('handleOnUserList newUserList', newUserList)
+        resolve()
+      })
+    })
+  },
+  judgeWhetherExist: function(target, userList) {
+    userList.forEach( (item) => {
+      if (target.userID === item.userID && target.streamType === item.streamType) {
+        return item
+      }
+    })
+    return false
+  },
+  handlePublishAudio() {
+    if (this.data.presenterConfig.enableMic) {
+      this.trtcComponent.unpublishLocalAudio()
+      const config = this.data.presenterConfig
+      config.enableMic = false
+      this.setData({
+        presenterConfig: config,
+      }, () => {
+        wx.showToast({
+          title: '您已关闭麦克风',
+          icon: 'none',
+          duration: 500,
+        })
+      })
+    } else {
+      this.trtcComponent.publishLocalAudio()
+      const config = this.data.presenterConfig
+      config.enableMic = true
+      this.setData({
+        presenterConfig: config,
+      }, () => {
+        wx.showToast({
+          title: '您已开启麦克风',
+          icon: 'none',
+          duration: 500,
+        })
+      })
+    }
+  },
+  handleMuteAllAudio() {
+    if (this.data.presenterConfig.muteAllAudio) {
+      this.data.userList.forEach((item) => {
+        this.trtcComponent.subscribeRemoteAudio({ userID: item.userID })
+      })
+      const config = this.data.presenterConfig
+      config.muteAllAudio = false
+      this.setData({
+        presenterConfig: config,
+      }, () => {
+        wx.showToast({
+          title: '取消禁音成功',
+          icon: 'none',
+          duration: 500,
+        })
+      })
+    } else {
+      this.data.userList.forEach((item) => {
+        this.trtcComponent.unsubscribeRemoteAudio({ userID: item.userID })
+      })
+      const config = this.data.presenterConfig
+      config.muteAllAudio = true
+      this.setData({
+        presenterConfig: config,
+      }, () => {
+        wx.showToast({
+          title: '禁音成功',
+          icon: 'none',
+          duration: 500,
+        })
+      })
+    }
+  },
+  /**
+   * 返回上一页
+   */
+  onBack: function() {
+    wx.navigateBack({
+      delta: 1,
+    })
+  },
+  handleRoleChange() {
+    if (this.data.initialRole !== 'presenter' ) {
+      this.setData({
+        showRolePanel: !this.data.showRolePanel,
+      })
+    }
+  },
+  confirmRoleChange() {
+    if (this.data.role === 'audience') {
+      this.trtcComponent.publishLocalAudio().then(() => {
+        this.setData({
+          role: 'presenter',
+          showRolePanel: false,
+        })
+      }).catch(() => {
+        wx.showToast({
+          icon: 'none',
+          title: '上麦失败',
+        })
+      })
+    } else {
+      this.trtcComponent.unpublishLocalAudio().then(() => {
+        this.setData({
+          role: 'audience',
+          showRolePanel: false,
+        })
+      }).catch(() => {
+        wx.showToast({
+          icon: 'none',
+          title: '下麦失败',
+        })
+      })
+    }
+  },
+  /**
+   * 生命周期函数--监听页面加载
+   * @param {*} options 配置项
+   */
+  onLoad: function(options) {
+    console.log('room onload', options)
+    wx.setKeepScreenOn({
+      keepScreenOn: true,
+    })
+    // 获取 rtcroom 实例
+    this.trtcComponent = this.selectComponent('#trtc-component')
+    Object.getOwnPropertyNames(options).forEach((key) => {
+      if (options[key] === 'true') {
+        options[key] = true
+      }
+      if (options[key] === 'false') {
+        options[key] = false
+      }
+    })
+    // 监听TRTC Room 关键事件
+    this.bindTRTCRoomEvent()
+    this.setData({
+      roomID: 1,
+      // role: 1,
+      // initialRole: 1,
+      userID: '2',
+      debugMode:true,
+      // audioVolumeType: options.audioVolumeType,
+    }, () => {
+      this.getSignature('2')
+    })
+  },
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function() {
+    console.log('room ready')
+    wx.setKeepScreenOn({
+      keepScreenOn: true,
+    })
+  },
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function() {
+    console.log('room show')
+    wx.setKeepScreenOn({
+      keepScreenOn: true,
+    })
+  },
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function() {
+    console.log('room hide')
+  },
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function() {
+    console.log('room unload')
+    wx.setKeepScreenOn({
+      keepScreenOn: false,
+    })
+  },
+})
+

+ 6 - 0
apps/agent/pages/room/room.json

@@ -0,0 +1,6 @@
+{
+  "usingComponents": {
+    "trtc-room": "/components/trtc-room/trtc-room"
+  },
+  "disableScroll": true
+}

+ 53 - 0
apps/agent/pages/room/room.wxml

@@ -0,0 +1,53 @@
+<!--miniprogram/pages/room/room.wxml-->
+<!-- 在模版上放置标签 -->
+<view class="page-room">
+<text>{{nickname}}</text>
+  <!-- <view class="bg">
+    <view class='title' style='padding-top:{{(headerHeight + statusBarHeight)/2 - 12}}px'>
+      <text>房间号:{{roomID}}</text>
+    </view>
+    <view class="user-container">
+      <view class="own" wx:if="{{role === 'presenter'}}" bindtap="handleRoleChange">
+        <view class="avatar">
+          <image src="../../../images/avatar0_100.png" class="avatar-image"></image>
+        </view>
+        <view class="userID">{{userID}}(自己)</view>
+      </view>
+      <view class="own" wx:if="{{role === 'audience'}}">
+        <view class="avatar" bindtap="handleRoleChange">
+        </view>
+        <view class="userID">虚位以待</view>
+      </view>
+      <view class="users">
+        <view class="user"  wx:for="{{userList}}"  wx:key="userID" wx:if="{{item.hasMainAudio}}">
+          <view wx:if="role === 'presenter'" class="avatar" style="border: 4px solid rgba(0, 110, 255, {{item.volume / 100}})">
+            <image src="{{'../../../images/avatar' + (index + 1) + '_100.png'}}" class="avatar-image"></image>
+          </view>
+          <view class="userID">{{item.userID}}</view>
+        </view>
+        <view class="user" wx:for="{{[1,2,3,4,5,6]}}"  wx:key="index" wx:if="{{index < 6 - userList.length}}">
+          <view class="avatar-fake"></view>
+          <view class="userID">虚位以待</view>
+        </view>
+      </view>
+    </view>
+    <view class="role-choose" wx:if="{{showRolePanel}}">
+      <view class="role-panel-text" wx:if="{{role === 'presenter'}}">确定下麦吗?</view>
+      <view class="role-panel-text" wx:if="{{role === 'audience'}}">确定上麦吗?</view>
+      <view class="handle-btn">
+        <view class="role-btn confirm" bindtap="confirmRoleChange">确认</view>
+        <view class="role-btn" bindtap="handleRoleChange">取消</view>
+      </view>
+    </view>
+    <view class="setting">
+      <view class="btn-normal" bindtap="handlePublishAudio" wx:if="{{role === 'presenter'}}">
+        <image src="{{presenterConfig.enableMic? '../../../images/audio-true.png': '../../../images/audio-false.png'}}"></image>
+      </view>
+      <view class="btn-normal" bindtap="handleMuteAllAudio">
+        <image src="{{!presenterConfig.muteAllAudio? '../../../images/voice.png': '../../../images/voice-false.png'}}"></image>
+      </view>
+    </view>
+  </view> -->
+  <trtc-room id="trtc-component" config="{{rtcConfig}}"></trtc-room>
+</view>
+<!-- <cover-image class='close' style="top:{{(headerHeight + statusBarHeight) - 34}}rpx" src="../../../images/back.png" bindtap="onBack"></cover-image> -->

+ 145 - 0
apps/agent/pages/room/room.wxss

@@ -0,0 +1,145 @@
+/* miniprogram/pages/room/room.wxss */
+.page-room{
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+  /* background-image: url(https://mc.qcloudimg.com/static/img/7da57e0050d308e2e1b1e31afbc42929/bg.png); */
+  background-color: #fff;
+  background-repeat:no-repeat;
+  background-size: cover;
+}
+.title{
+  color: #FFFFFF;
+  padding-top: 65rpx;
+  line-height: 60rpx;
+  text-align: center;
+}
+.page-room .avatar {
+  height: 100rpx;
+  width: 100rpx;
+  border-radius: 50%;
+  background: #999;
+  overflow: hidden;
+}
+.user-container {
+  box-sizing: border-box;
+  padding: 80rpx 60rpx 0 60rpx;
+  height: 900rpx;
+  overflow: hidden;
+  color: white;
+}
+.own {
+  height: 180rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.avatar-image {
+  width: 100%;
+  height: 100%;
+}
+.users {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  padding-top: 40rpx;
+}
+.user {
+  height: 200rpx;
+  width: 33.3%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  font-size: 24rpx;
+}
+.userID {
+  padding-top: 20rpx;
+}
+.avatar-fake {
+  height: 100rpx;
+  width: 100rpx;
+  border-radius: 50%;
+  background: #999;
+}
+.bg {
+  width: 100vw;
+  height: 100vh;
+}
+.close {
+  position:absolute;
+  padding-left:5vw;
+  padding-right:5vw;
+  width:50rpx;
+  height:60rpx;
+}
+.back {
+  font-size: 32rpx;
+  line-height: 32rpx;
+  padding-left: 5vw;
+  padding-right: 5vw;
+  width: 50rpx;
+}
+.title {
+  color: white;
+  font-size: 32rpx;
+  font-weight: 500;
+}
+.role-choose {
+  position: absolute;
+  width: 90vw;
+  background: white;
+  border: 1px solid #bfbfbf;
+  border-radius: 12rpx;
+  top: 40vh;
+  left: 5vw;
+  padding: 40rpx;
+  box-sizing: border-box;
+}
+.role-panel-text {
+  font-size: 32rpx;
+  font-weight: 500;
+}
+.handle-btn {
+  display: flex;
+  flex-direction: row-reverse;
+  margin-top: 20rpx;
+}
+.role-btn {
+  margin-left: 20rpx;
+  padding: 10rpx 20rpx;
+  border-radius: 12rpx;
+}
+.confirm {
+  background: #006eff;
+  color: white;
+}
+.setting {
+  height: 100%;
+  padding: 100rpx 60rpx;
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+}
+.btn-normal {
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 50%;
+  background: white;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.btn-normal image {
+  width: 50rpx;
+  height: 50rpx;
+}
+.close {
+  position:absolute;
+  padding-left:5vw;
+  padding-right:5vw;
+  width:50rpx;
+  height:60rpx;
+}

+ 26 - 3
apps/agent/pages/web/web.js

@@ -20,7 +20,15 @@ Page({
     pushUrl: '',
     live_base_url: "rtmp://120.24.85.77:1935/hls",
     socketOpts: {},
-    room_id: 'test1'
+    room_id: 'test1',
+    trtcConfig: {
+      scene: 'rtc',
+      // sdkAppID: '1400433526', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      sdkAppID: '1400537003', // 开通实时音视频服务创建应用后分配的 SDKAppID
+      userID: '', // 用户 ID,可以由您的帐号系统指定
+      userSig: '', // 身份签名,相当于登录密码的作用
+      template: 'custom', // 画面排版模式
+    }
   },
   /**
    * 生命周期函数--监听页面加载
@@ -33,7 +41,8 @@ Page({
       roomId: options.room_id || getQueryString(vr_link, 'room_id') || randomString(18),
       userId: getApp().globalData.userinfo.user_id,
       customerId: getApp().globalData.userinfo.user_id,
-      nickname: getApp().globalData.userinfo.name,
+      // nickname: getApp().globalData.userinfo.name,
+      nickname: getApp().globalData.userinfo.nickname,
       role: 'agent',
       scene_num: this.scene
     }
@@ -141,20 +150,28 @@ Page({
         userID: user.userId, // 用户 ID,可以由您的帐号系统指定
         userSig: user.sig, // 身份签名,相当于登录密码的作用
         template: 'custom', // 画面排版模式
+        debugMode:true,
       }
     }, () => {
       this.trtcRoomContext = this.selectComponent('#trtcroom')
       let EVENT =this.trtcRoomContext.EVENT
-
+    
       if (this.trtcRoomContext) {
+        // this.publishLocalAudio()
         this.trtcRoomContext.on(EVENT.LOCAL_JOIN, (event) => {
           this.publishLocalAudio()
+          // wx.showToast({
+          //   title: '进房',
+          // })
         })
 
         // 监听远端用户的音频流的变更事件
        this.trtcRoomContext.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
           // 订阅(即播放)远端用户的音频流
           let userID = event.data.userID
+          // wx.showToast({
+          //   title: '订阅',
+          // })
          this.trtcRoomContext.subscribeRemoteAudio({
             userID: userID
           })
@@ -165,8 +182,11 @@ Page({
        this.trtcRoomContext.enterRoom({
           roomID: this.roomId
         }).then(() => {
+         
           console.log('成功进入房间')
+          console.log(this.roomId)
         }).catch((res) => {
+         
           console.error('room joinRoom 进房失败:', res)
         })
       }
@@ -177,5 +197,8 @@ Page({
   },
   publishLocalAudio () {
     this.trtcRoomContext && this.trtcRoomContext.publishLocalAudio()
+    // wx.showToast({
+    //   title: '推流',
+    // })
   }
 })

+ 2 - 1
apps/agent/utils/imSend.js

@@ -7,7 +7,8 @@ export default {
       house_type: house.house_type,
       house_area: house.area,
       orientation: house.orientation,
-      price: `${(house.price/10000).toFixed(0)}万`,
+      // price: `${(house.price/10000).toFixed(0)}万`,
+      price: `${house.price}`,
       vr_link: is_vr_invite ? `${house.vrLink}${encodeURIComponent(`&room_id=${room_id}`)}` : '',
       house_id: house.house_id
     }

+ 35 - 11
apps/agent/utils/socket-handle.js

@@ -1,17 +1,19 @@
 const socket_io = require('./socket.io-mp')
-const { IM_HOST } = require('../config/config')
+const {
+  IM_HOST
+} = require('../config/config')
 
 let io = ''
 export function initSocket(page, options) {
   const defaultOpts = {
     customerId: '',
     agentId: '',
-    role:'agent',
+    role: 'agent',
     nickName: '',
-    roomId:'',
+    roomId: '',
     isClient: true
   }
-  
+
   io = socket_io(IM_HOST, {
     path: '/vr-node',
     query: Object.assign(defaultOpts, options)
@@ -27,13 +29,35 @@ export function initSocket(page, options) {
     console.log(data, 'startplay')
     page.startPlay(data)
   })
-
+  
   io.on(eventName.someoneInRoom, function (data) {
+   
     if (data.persons.length < 2) {
       return
     }
+    console.log(data)
     let user = data.persons.find(item => item.userId === getApp().globalData.userinfo.user_id)
-    page.enterAudioRoom(user)
+    // page.enterAudioRoom(user)
+    wx.getSetting({
+      success: (res) => {
+        if (!res.authSetting['scope.record']) {
+          wx.authorize({
+            scope: 'scope.record',
+            success: (res) => {
+              // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
+              console.log('同意', res);
+              page.enterAudioRoom(user)
+            },
+            fail: res => {
+              console.log('拒绝', res);
+              cbError && cbError();
+            }
+          })
+        } else {
+          page.enterAudioRoom(user)
+        }
+      }
+    })
   })
 
   io.on(eventName.someoneLeaveRoom, function (data) {
@@ -48,7 +72,7 @@ export function initSocket(page, options) {
   return io
 }
 
-export function emitSendMsg (target_id) {
+export function emitSendMsg(target_id) {
   let app = getApp()
   io.emit('sendMsg', {
     user_id: app.globalData.userinfo.user_id,
@@ -56,7 +80,7 @@ export function emitSendMsg (target_id) {
   })
 }
 
-export function emitInRoom () {
+export function emitInRoom() {
   let app = getApp()
   io.emit('inRoom', {
     user_id: app.globalData.userinfo.user_id,
@@ -64,7 +88,7 @@ export function emitInRoom () {
   })
 }
 
-export function emitLeaveRoom () {
+export function emitLeaveRoom() {
   let app = getApp()
   io.emit('leaveRoom', {
     user_id: app.globalData.userinfo.user_id,
@@ -72,6 +96,6 @@ export function emitLeaveRoom () {
   })
 }
 
-export function disconnect () {
+export function disconnect() {
   return io.disconnect()
-}
+}

+ 2 - 0
apps/agent/utils/utils.js

@@ -1,7 +1,9 @@
 export function bindInput(event) {
   var obj = {},
     key = event.target.dataset['key'];
+   
   obj[key] = event.detail.value;
+  obj[key]= obj[key].replace(/[^0-9]/g,'');
   console.log(obj)
   this.setData(obj);
 }