微信小程序即时通讯(融云sdk)

we

记录一下我在使用融云sdk中遇到的问题
使用前要去融云那边注册账号申请appid 然后开通小程序服务,就可以下载小程序案例了
融云的sdk中的
小程序聊天中加载的资源更多的是网络资源(七牛云上的外链地址)
app聊天加载的更多的是类似base64的资源

融云那边有提供比较完整的案例
但是是分开的一个是IM聊天室案例
一个是calllib音视频案例 这两个案例无法同时使用
因为sdk的版本不同会导致冲突(官方说是兼容性还没有做好)
建议使用sdk2版本,这个版本两个都可以使用
1、初始化(这个问题是我最后才解决掉的,一定要初始化好,不然就算能用也会有很多问题)
2、实时获取消息加载到自己的聊天列表中
3、解决首次登录的初始化问题还有第二次登录的初始化问题
(这个问题比较有意思,因为我当时是分开处理化的,先初始化IM聊天室,在链接上之后再次获取那边的token去初始化音视频的sdk,反正就不对的,要一起初始化)
4、在小程序开始运行并且链接上融云那边的服务会后设置全局监听(可以让不管处于哪一个界面都可以,收到消息通知,当然仅限于小程序内,就是小程序处于show状态的时候,切换到后台就收不到了,因为小程序不支持后台强制唤醒,这里的话可以去关联公众号,通过让用户在公众号上绑定用户信息,获取唯一标识,去实现离线推送,关于公众号授权的内容可以参考这个链接),具体关联上怎么推送的话,要去公众平台里申请和设置消息模板,具体咋推送的就要靠后端勒
5、接下来就是判断被聊天的用户是否在线,是否需要被推送
6、现在就是打音视频的界面需要判断是接听方还是呼叫方去通过不同的字段去展示不同的界面,当然聊天室也要判断是当前用户还是对方用户去显示到两侧
7、我们也尝试过微信小程序消息推送(结果就是能退过来,但是次数限制是硬伤,订一次推送一次,不满足需求)
8、在聊天室中发送定位信息时,要使用wx.getLocation和 wx.chooseLocation去选择地址具体的地址表述图片可以使用高德那边的api把经纬度传过去然后返回地址描述图,前端没办法单独处理,我是没有想到办法
参考这个链接去高德api看 https://restapi.amap.com/v3/staticmap?markers=-1,http://www.5imoban.net/view/demoimg/jrzb_position_icon.png,0:${longitude},${latitude}&key=ee95e52bf08006f63fd29bcfbcf21df0&zoom=17&size=360*200&location=${longitude},${latitude}
9、设置用户聊天的时间展示,当然写数据都融云那边的接口给我们的,给我们的是毫秒,不是给用户看的东西,所有要前台处理一下,但使用js对每一条数据都处理总感觉很慢,wxml行间也不允许处理过的内容,所以我使用wxs

var filter = {
  getDateTime: function (value) {
    //不能使用 new Date()
      var now = getDate();
      var time = getDate(value);
      var year = time.getFullYear();
      var month = time.getMonth() + 1;
      var date = time.getDate();
      var hour = time.getHours();
      var minute = time.getMinutes();
      var second = time.getSeconds();
      month = month < 10 ? "0" + month : month;
      date = date < 10 ? "0" + date : date;
      hour = hour < 10 ? "0" + hour : hour;
      minute = minute < 10 ? "0" + minute : minute;
      second = second < 10 ? "0" + second : second;
      if(now.getFullYear() == year){
        if(now.getDate() == date){
          return hour + ":" + minute + ":" + second;
        }else{
          return  month + "-" + date + " " + hour + ":" + minute + ":" + second;
        }
      }else{
        return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
      }
  }
}
// 导出对外暴露的属性
module.exports = {
  getDateTime: filter.getDateTime
}

具体使用

<wxs module="filter" src="./message.wxs"></wxs>
<view style='margin:16rpx 0'>{{filter.getDateTime(message.sentTime)}}</view>

10、 确保每次用户进入到聊天界面时,界面要定位到最后一条信息哪里(因为聊天信息一般都比较多会有滚动条的存在,所以要让滚动条在最后一天数据哪里,这个时候你可能会觉得直接滚到底部就可以了,但是当时图片消息时内容高度较高就显得不合适了)
这里使用小程序那边的scroll-view组件 这个组件有一个scroll-into-view属性可以让滚动条滚动到指定位置,具体操作就是通过获取到消息监听器监听来的数据的唯一标识去修改那个属性的值去实现的
11、还有监听挂断时的重复触发回调的问题

const gotoView = (context,first) => {
  context.setData({
    toView: context.data.messageList[context.data.messageList.length - 1].messageUId
  })
 
}
Page({
	data:{
		toView:null, // 用来定位最后一天的消息的标识
		messageList:[] // 当前的聊天记录
	},
	收到消息后触发的方法:funtion(){
		...这是处理messageList的内容
		gotoView(this)
	},
	我发送某种消息:funtion(){
		...这是处理messageList的内容
		gotoView(this)
	}
})

12、视频通话时切换前后摄像头

this.livePusher = wx.createLivePusherContext()
 this.livePusher.switchCamera({})

以上是我遇到的部分问题

这是我关于初始化和设置的一些方法,为了有更好的拓展性,我写在小程序的app.js中方便全局使用

具体的sdk版本可以参考我的版本去下载

const RongIMLib = require('./libs/RongIMLib.wx-1.2.4.js');
const RongRTC = require('./libs//RongRTC-wechat-minip-3.2.2.js');
const RongCallLib = require('./libs//RongCallLib-wechat-minip-3.2.2.js');
import {
  request
} from './request/index'
// const { co } = require('./helper');
var commandWatcher = function (result) {
  console.log("----------------", result, result.messageType, result.messageType == "InviteMessage")
  if (result.messageType == "InviteMessage") {
    wx.navigateTo({
      url: '/pages/call/call?data=' + JSON.stringify(result)
    })
  }
}
// 
function appletOnLine(type){
  request({
      url:'login/appletOnLine',
      data:{
        token:wx.getStorageSync('token'),
        applet_type:type
      }
  }).then(res => {
    console.log(res)
  })
}
const {
  appkey,
  msUrls,
  apps,
  serverUrl
} = require('./config');
var layout = function () {
  if (userListModle) {
    userListModle.setData({
      conversationList: []
    })
  }
}
var appType = (id,content) => {
  request({
    url: "wechat/selectExpertType",
    data: {
      id
    }
  }).then((res) => {
    console.log(res)
    if (res.data.data.account !== null && (res.data.data.account.applet_type === 0 || res.data.data.account.applet_type === null)) {
      request({
        url: "wechat/sendMessage",
        data: {
          id: id,
          name:wx.getStorageSync('name'),
          mobile: wx.getStorageSync('phone'),
          content
        }
      }).then((res) => {})
    }
  })

}
let RongIMClient = null;
let userListModle = null;
let ChatRoom = null;
let reconnect = () => {
  var callback = {
    onSuccess: function (userId) {
      console.log('Reconnect successfully. ' + userId);
    },
    onTokenIncorrect: async function () {
      let result
      console.log('token无效');
      wx.showToast({
        title: '登录过期,请重新登录',
        icon: "none"
      })
      wx.clearStorageSync()
    },
    onError: function (errorCode) {
      console.log(errorcode);
    }
  };
  var config = {
    // 默认 false, true 启用自动重连,启用则为必选参数
    auto: true,
    // 网络嗅探地址 [http(s)://]cdn.ronghub.com/RongIMLib-2.2.6.min.js 可选
    url: 'cdn.ronghub.com/RongIMLib-2.2.6.min.js',
    // 重试频率 [100, 1000, 3000, 6000, 10000, 18000] 单位为毫秒,可选
    rate: [100, 1000, 3000, 6000, 10000]
  };
  RongIMClient.reconnect(callback, config);
}
var getList = (context) => {
  return new Promise((r, j) => {
    RongIMClient.getInstance().getConversationList({
      onSuccess: function (list) {
        request({
          url: 'index/communicationList',
          data: {
            token: wx.getStorageSync("token"),
            pageNo: context.data.pageNo,
            pageSize: context.data.pageSize,
            name: context.data.name
          }
        }).then(res => {
          if (res.data.status == 1) {
            let ryData;
            let my = [];
            res.data.page.list.forEach(ele => {
              my.push(ele.user_id)
            })
            console.log(my)
            ryData = list.filter(e => {
              if (e.targetId != wx.getStorageSync('userId')) {
                return my.includes(parseInt(e.targetId))
              }
            })
            ryData.forEach(e => {
              e.zj = res.data.page.list.filter((element) => {
                return element.user_id == e.targetId
              })[0]
            })
            r(ryData)
          }
        })
      },
      onError: function (error) {
        j(error)
        getList(context)
      }
    }, null)
  })
}
var getHistory = (targetId, timestrap, count) => {
  console.log(targetId, timestrap, count)
  console.log(RongIMLib.ConversationType)
  var conversationType = RongIMLib.ConversationType.PRIVATE; //单聊, 其他会话选择相应的消息类型即可
  var targetId = targetId; // 想获取自己和谁的历史消息,targetId 赋值为对方的 userId。类型: string
  var timestrap = timestrap; // 默认传 null,若从头开始获取历史消息,请赋值为 0, timestrap = 0;
  var count = Number(count); // 每次获取的历史消息条数,范围 0-20 条,可以多次获取
  if (count == 0) {
    count = 8
  }
  return new Promise((r, j) => {
    RongIMLib.RongIMClient.getInstance().getHistoryMessages(conversationType, targetId, timestrap, count, {
      onSuccess: function (list, hasMsg) {
        // console.log(list, hasMsg)
        r({
          list,
          hasMsg
        })
        // list => Message 数组。
        // hasMsg => 是否还有历史消息可以获取。
      },
      onError: function (error) {
        console.log('GetHistoryMessages, errorcode:' + error);
        getHistory(targetId, timestrap, count)
        j(error)
      }
    });
  })

}
var ImageMessage = (targetId, base64Str, imageUri, extra) => {
  console.log(extra)
  return new Promise((r, j) => {
    extra = {
      ...extra,
      id1: wx.getStorageSync('userId'),
      id2: ChatRoom.data.targetId,
      xm1: ChatRoom.data.my.name,
      xm2: ChatRoom.data.your.name,
      tx1: ChatRoom.data.my.headPortrait,
      tx2: ChatRoom.data.your.headPortrait,
    }
    var msg = new RongIMLib.ImageMessage({
      content: base64Str,
      imageUri: imageUri,
      extra
    });
    var conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊, 其他会话选择相应的会话类型即可
    targetId = String(targetId); // 目标 Id
    RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
      onSuccess: function (message) {
        // message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
        if (message.senderUserId == message.targetId) {
          message.direction = 'receiver'
        } else {
          message.direction = 'sender'
        }
        console.log(message)
        appType(targetId,'您有一条图片消息')
        r(message)
        console.log('Send successfully');
      },
      onError: function (errorCode, message) {
        j(message)
        console.log('发送失败:' + message + errorCode);
      }
    });
  })
}
var LocationMessage = (targetId, latitude, longitude, poi, content) => {
  let extra = {
    id1: wx.getStorageSync('userId'),
    id2: ChatRoom.data.targetId,
    xm1: ChatRoom.data.my.name,
    xm2: ChatRoom.data.your.name,
    tx1: ChatRoom.data.my.headPortrait,
    tx2: ChatRoom.data.your.headPortrait,
  }

  return new Promise((r, j) => {
    var msg = new RongIMLib.LocationMessage({
      latitude: latitude,
      longitude: longitude,
      poi: poi,
      content: content,
      extra
    });

    var conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊, 其他会话选择相应的会话类型即可
    targetId = String(targetId); // 目标 Id
    RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
      onSuccess: function (message) {
        // message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
        console.log(message, 'Send successfully');
        if (message.senderUserId == message.targetId) {
          message.direction = 'receiver'
        } else {
          message.direction = 'sender'
        }
        appType(targetId,'您有一条地理定位消息')
        r(message)
      },
      onError: function (errorCode, message) {
        var info = '';
        j(message)
        switch (errorCode) {
          case RongIMLib.ErrorCode.TIMEOUT:
            info = '超时';
            break;
          case RongIMLib.ErrorCode.UNKNOWN:
            info = '未知错误';
            break;
          case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST:
            info = '在黑名单中,无法向对方发送消息';
            break;
          case RongIMLib.ErrorCode.NOT_IN_DISCUSSION:
            info = '不在讨论组中';
            break;
          case RongIMLib.ErrorCode.NOT_IN_GROUP:
            info = '不在群组中';
            break;
          case RongIMLib.ErrorCode.NOT_IN_CHATROOM:
            info = '不在聊天室中';
            break;
        }
        console.log('发送失败:' + info + errorCode);
      }
    });
  })

}
var RegisterMessage = (targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra, ) => {
  return new Promise((r, j) => {

    extra = {
      ...extra,
      id1: wx.getStorageSync('userId'),
      id2: ChatRoom.data.targetId,
      xm1: ChatRoom.data.my.name,
      xm2: ChatRoom.data.your.name,
      tx1: ChatRoom.data.my.headPortrait,
      tx2: ChatRoom.data.your.headPortrait,
    }
    let content = mediaUrl;
    var messageName = 'VoiceMessage'; // 消息名称
    var objectName = 'RC:VcMsg'; // 消息内置名称,请按照此格式命名
    var isCounted = true; // 消息计数
    var isPersited = true; // 消息保存
    var mesasgeTag = new RongIMLib.MessageTag(isCounted, isPersited); // 消息是否保存是否计数,true true 计数且保存,false false 不计数不保存
    var prototypes = ['content', 'duration', 'extra']; // 消息类中的属性名
    RongIMClient.registerMessageType(messageName, objectName, mesasgeTag, prototypes);
    var conversationType = RongIMLib.ConversationType.PRIVATE; //单聊, 其他会话选择相应的会话类型即可
    targetId = String(targetId); // 想获取自己和谁的历史消息,targetId 赋值为对方的 Id
    var msg = new RongIMClient.RegisterMessage.VoiceMessage({
      content,
      extra,
      duration
    });
    RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
      onSuccess: function (message) {
        console.log(message)
        if (message.senderUserId == message.targetId) {
          message.direction = 'receiver'
        } else {
          message.direction = 'sender'
        }
        appType(targetId,'您收到一条语音消息')
        r(message)
        console.log('发送自定义消息成功');
      },
      onError: function (errorCode) {
        j(errorCode)
        console.log('发送自定义消息失败');
      }
    });
  })

}
var RegisterMessage1 = (targetId, name, sightUrl, fileUrl, fileType, fileSize, duration, extra, ) => {
  return new Promise((r, j) => {

    extra = {
      ...extra,
      id1: wx.getStorageSync('userId'),
      id2: ChatRoom.data.targetId,
      xm1: ChatRoom.data.my.name,
      xm2: ChatRoom.data.your.name,
      tx1: ChatRoom.data.my.headPortrait,
      tx2: ChatRoom.data.your.headPortrait,
    }
    // let content = {
    //   name,
    //   mediaUrl,
    //   fileUrl,
    //   fileType,
    //   fileSize,
    //   duration
    // }
    let content = {
      content: sightUrl,
      sightUrl,
      duration
    };
    var messageName = 'SightMessage'; // 消息名称
    var objectName = 'RC:SightMsg'; // 消息内置名称,请按照此格式命名
    var isCounted = true; // 消息计数
    var isPersited = true; // 消息保存
    var mesasgeTag = new RongIMLib.MessageTag(isCounted, isPersited); // 消息是否保存是否计数,true true 计数且保存,false false 不计数不保存
    var prototypes = ['message', 'duration', 'extra']; // 消息类中的属性名
    RongIMClient.registerMessageType(messageName, objectName, mesasgeTag, prototypes);
    var conversationType = RongIMLib.ConversationType.PRIVATE; //单聊, 其他会话选择相应的会话类型即可
    targetId = String(targetId); // 想获取自己和谁的历史消息,targetId 赋值为对方的 Id
    var msg = new RongIMClient.RegisterMessage.SightMessage({
      message: {
        content
      },
      extra,
      duration
    });
    RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
      onSuccess: function (message) {
        console.log(message)
        if (message.senderUserId == message.targetId) {
          message.direction = 'receiver'
        } else {
          message.direction = 'sender'
        }
        appType(targetId,'您有一条视频消息')
        r(message)
        console.log('发送自定义消息成功');
      },
      onError: function (errorCode) {
        j(errorCode)
        console.log('发送自定义消息失败');
      }
    });
  })

}
var TextMessage = (targetId, content, extra) => {
  return new Promise((r, j) => {
    extra = {
      ...extra,
      id1: wx.getStorageSync('userId'),
      id2: ChatRoom.data.targetId,
      xm1: ChatRoom.data.my.name,
      xm2: ChatRoom.data.your.name,
      tx1: ChatRoom.data.my.headPortrait,
      tx2: ChatRoom.data.your.headPortrait,
    }
    var msg = new RongIMLib.TextMessage({
      content,
      extra
    });
    // request({
    //   url: 'rongyun/pushWx',
    //   data: {
    //     token:wx.getStorageSync("token"),
    //     thing2:content

    //   }
    // })
    var conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊, 其他会话选择相应的会话类型即可
    targetId = String(targetId); // 目标 Id
    RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
      onSuccess: function (message) {
        // message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
        console.log(message)
        appType(targetId,content)
        if (message.senderUserId == message.targetId) {
          message.direction = 'receiver'
        } else {
          message.direction = 'sender'
        }
        r(message)
        console.log('Send successfully');
      },
      onError: function (errorCode, message) {
        j(errorCode)
        console.log('发送失败: ' + message + errorCode);
      }
    });
  })
}
var clearUnreadCount = (targetId) => {

  var conversationType = RongIMLib.ConversationType.PRIVATE;
  var targetId = String(targetId);
  RongIMClient.getInstance().clearUnreadCount(conversationType, targetId, {
    onSuccess: function (message) {
      console.log(message)
      // 清除未读消息成功
      // if (getCurrentPages()[0].route != "pages/conversation/chat" ) {
      getList(userListModle)
      // }
    },
    onError: function (error) {
      console.log(error)

      // error => 清除未读消息数错误码
    }
  });


}
var ReadReceiptMessage = (targetId, messageUId, lastMessageSendTime, type = 1) => {
  console.log(targetId, messageUId, lastMessageSendTime, type)
  var conversationType = RongIMLib.ConversationType.PRIVATE; // 单聊, 其他会话选择相应的会话类型即可
  var msg = new RongIMLib.ReadReceiptMessage({
    messageUId,
    lastMessageSendTime,
    type
  })
  targetId = String(targetId)
  RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
    onSuccess: function (message) {
      // message 为发送的消息对象并且包含服务器返回的消息唯一 Id 和发送消息时间戳
      console.log(message, 'Send successfully');
    },
    onError: function (errorCode, message) {
      var info = '';
      switch (errorCode) {
        case RongIMLib.ErrorCode.TIMEOUT:
          info = '超时';
          break;
        case RongIMLib.ErrorCode.UNKNOWN:
          info = '未知错误';
          break;
        case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST:
          info = '在黑名单中,无法向对方发送消息';
          break;
        case RongIMLib.ErrorCode.NOT_IN_DISCUSSION:
          info = '不在讨论组中';
          break;
        case RongIMLib.ErrorCode.NOT_IN_GROUP:
          info = '不在群组中';
          break;
        case RongIMLib.ErrorCode.NOT_IN_CHATROOM:
          info = '不在聊天室中';
          break;
      }
      console.log('发送失败:' + info + errorCode);
    }
  });
}
// 初始化融云
function connectIM(context, token) {
  RongIMClient = RongIMLib.RongIMClient;
  RongIMLib.RongIMClient.init(appkey);
  // let RongIMClient = RongIMLib.RongIMClient;
  // RongIMLib.RongIMClient.init(appkey);

  // console.log(RongIMClient.Conversation.get)
  // console.log(RongIMClient.getInstance().getFileToken)

  /* 连接状态监听器 */
  RongIMClient.setConnectionStatusListener({
    onChanged: function (status) {
      /* status 标识当前连接状态 */
      switch (status) {
        case RongIMLib.ConnectionStatus.CONNECTED:
          console.log('链接成功');
          wx.showToast({
            title: '链接成功',
            icon: "none"
          })
          break;
        case RongIMLib.ConnectionStatus.CONNECTING:
          console.log('正在链接');
          break;
        case RongIMLib.ConnectionStatus.DISCONNECTED:
          console.log('断开连接');
          wx.showToast({
            title: '断开连接',
            icon: "none"
          })
          break;
        case RongIMLib.ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT:
          console.log('其他设备登录');
          wx.showToast({
            title: '其他设备登录',
            icon: "none"
          })
          break;
        case RongIMLib.ConnectionStatus.DOMAIN_INCORRECT:
          console.log('域名不正确');
          wx.showToast({
            title: '域名不正确',
            icon: "none"
          })
          break;
        case RongIMLib.ConnectionStatus.NETWORK_UNAVAILABLE:
          console.log('网络不可用');

          reconnect()
          wx.showToast({
            title: '网络不可用',
            icon: "none"
          })
          break;
      }
    }
  });

  /* 消息监听器 */
  RongIMClient.setOnReceiveMessageListener({
    onReceived: function (message) {
      console.log(message)
      if (userListModle) {
        userListModle.getList(message)
      }
      if (ChatRoom && ChatRoom.data.targetId == message.targetId) {
        ChatRoom.setNewMessage(message)
      }
    }
  });

  var config = {
    timeout: 20000,
    RongIMLib: RongIMLib,
    RongRTC: RongRTC,
    url: msUrls[0].url
  };
  var rongCallLib = RongCallLib.init(config);
  context.globalData.Service.rongCallLib = rongCallLib
  console.log(111, commandWatcher)
  rongCallLib.commandWatch(commandWatcher);
  console.log(token)
  RongIMClient.connect(token, {
    onSuccess: function (userId) {
      console.log('连接成功, 用户 ID 为', userId);
      // 连接已成功, 此时可通过 getConversationList 获取会话列表并展示
    },
    onTokenIncorrect: function () {
      console.log('连接失败, 失败原因: token 无效');
    },
    onError: function (errorCode) {
      var info = '';
      switch (errorCode) {
        case RongIMLib.ErrorCode.TIMEOUT:
          info = '超时';
          break;
        case RongIMLib.ConnectionState.UNACCEPTABLE_PAROTOCOL_VERSION:
          info = '不可接受的协议版本';
          break;
        case RongIMLib.ConnectionState.IDENTIFIER_REJECTED:
          info = 'appkey不正确';
          break;
        case RongIMLib.ConnectionState.SERVER_UNAVAILABLE:
          info = '服务器不可用';
          break;
      }
      console.log(info);
    }
  });
  context.globalData.Service = {
    ...context.globalData.Service,
    Status: {},
    Conversation: {},
    User: {},
    CONNECTION_STATUS: {},
    RongIMClient: RongIMClient.getInstance(),
    RongIMLib: RongIMLib,
    getList,
    layout,
    getHistory,
    ConversationType: RongIMLib.ConversationType,
    MessageType: RongIMClient.MessageType,
  }

}

App({

  setList(context) {

    userListModle = context
  },
  setChat(context) {
    setChat(context)
  },
 
  setChatRoom(context) {
    ChatRoom = context
  },
  onHide() {
    if(wx.getStorageSync('status') == 2){
      appletOnLine(0)
    }
  },
  onShow(){
    if(wx.getStorageSync('status') == 2){
      appletOnLine(1)
    }
  },
  setConversationList(conversationList) {
    if (chatList) {
    
      chatList.communicationList(conversationList)
    }
  },
  connectIM(token) {
    console.log(token, '开始初始化')
    connectIM(this, token)
  },
  onLaunch: function () {
    // 展示本地存储能力
    let token = wx.getStorageSync('RYtoken')
    if (token) {
      this.connectIM(token)
    }
    if (wx.getStorageSync('userId') && wx.getStorageSync('token')) {}
    const updateManager = wx.getUpdateManager()
    updateManager.onCheckForUpdate(function (res) {
      // 请求完新版本信息的回调
      console.log(res.hasUpdate)
    })
    updateManager.onUpdateReady(function () {
      wx.showModal({
        title: '更新提示',
        content: '新版本已经准备好,是否重启应用?',
        success(res) {
          if (res.confirm) {
            // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
            updateManager.applyUpdate()
          }
        }
      })
    })
    updateManager.onUpdateFailed(function () {
      // 新版本下载失败
    })
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  TextMessage(targetId, content, extra = {}) {
    return TextMessage(targetId, content, extra)
  },
  ImageMessage(targetId, base64Str, imageUri, extra = {}) {
    return ImageMessage(targetId, base64Str, imageUri, extra)
  },
  RegisterMessage(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra = {}) {
    return RegisterMessage(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra)
  },
  RegisterMessage1(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra = {}) {
    return RegisterMessage1(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra)
  },
  ReadReceiptMessage({
    targetId,
    messageUId,
    lastMessageSendTime,
    type
  }) {
    ReadReceiptMessage(targetId, messageUId, lastMessageSendTime, type)
  },
  clearUnreadCount(targetId) {
    clearUnreadCount(targetId)
  },
  LocationMessage(targetId, latitude, longitude, poi, content) {
    return LocationMessage(targetId, latitude, longitude, poi, content)
  },
  reconnect() {
    reconnect()
  },
  onReceiveMessage(message) {
    console.log(message)
    wx.navigateTo({
      url: '../../call/call?data=' + JSON.stringify(message)
    })
    return false
  },
  globalData: {
    Service: {
      Status: {},
      Conversation: {},
      User: {},
      CONNECTION_STATUS: {},
      getList,
      layout,
      getHistory,
      rongCallLib: null,
      ConversationType: RongIMLib.ConversationType,
    },
    userInfo: null,
    statusBarHeight: wx.getSystemInfoSync()['statusBarHeight'],
   
  }
})

这个是我聊天界面的js(在官方案例的基础上修改了,目前还没有整理好)

import {
  request
} from "../../request/index"
let clear = true
let timer = null;
let dangDate = null;
let LTID = null
let timeInt = 4*60*60
const scale = wx.getSystemInfoSync().windowWidth / 750
//  通话配置
const callUtils = require('../../utils/util');
const Config = require('../../config.js');
const common = require('../common');
let newW = false
const {
  co
} = require('../../helper');
const {
  apps,
  serverUrl,
  msUrls
} = Config;
const reg = /^\w{1,15}$/;
let doLogin = false;

//  默认配置
const utils = require('../utils/utils.js');
const {
  adapterHeight
} = utils.getAdapterheight();


const {
  globalData,
  setChatRoom,
  TextMessage,
  ImageMessage,
  LocationMessage,
  RegisterMessage,
  RegisterMessage1,
  clearUnreadCount
} = getApp();
const {
  Service: {
    Status,
    Message,
    File,
    Conversation,
    RongIMClient,
    RongIMLib,
    getHistory
  }
} = globalData;
// 
const RongEmoji = require('../lib/RongIMEmoji-2.2.6.js');
RongEmoji.init();

const softKeyboardHeight = 210;

const getToView = (context) => {
  let {
    messageList
  } = context.data;
  let index = messageList.length - 1;
  let message = messageList[index] || {};
  return message.uId || '';
};
const setNewMessage = (context, newMessage) => {
  console.log(newMessage, 1111111111111, getCurrentPages())
  if (newMessage.senderUserId == newMessage.targetId) {
    newMessage.direction = 'receiver'
  } else {
    newMessage.direction = 'sender'
  }
  context.data.messageList.push(newMessage)
  context.setData({
    messageList: context.data.messageList
  })
  if (clear) {
    console.log('qimhcji')
    clearUnreadCount(newMessage.targetId)
  }
  gotoView(context)
}
const imgBase64 = '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';
const setKeyboardPos = (context, keyboardHeight, adapterHeight) => {
  keyboardHeight = keyboardHeight || 0;
  let data;
  let isScroll = (keyboardHeight > 0);
  if (isScroll) {
    data = {
      bottom: adapterHeight + keyboardHeight,
      isShowEmojiSent: false,
      toView: getToView(context)
    };
  } else {
    data = {
      bottom: adapterHeight + keyboardHeight,
      isShowEmojiSent: false
    };
  }
  context.setData(data);
};

const showSoftKeyboard = (context, display) => {
  context.setData({
    display: display,
    bottom: softKeyboardHeight,
    isShowKeyboard: false,
    toView: getToView(context)
  });
};
const hideSoftKeyboard = (context) => {
  context.setData({
    display: {
      emoji: 'none',
      more: 'none'
    }
  });
};

const hideKeyboard = (context) => {
  let keyboardHeight = 0;
  let {
    adapterHeight
  } = context.data;
  setKeyboardPos(context, keyboardHeight, adapterHeight);
  hideSoftKeyboard(context);
};

const formatEmojis = () => {
  let list = RongEmoji.list;
  return utils.sliceArray(list, {
    size: 24
  });
};

const getMessageList = (context, params) => {
  let {
    position
  } = params;
  let event = params.type == 4 ? Message.getChatRoomMessageList : Message.getList;
  return event(params).then((result) => {
    let messages = result.messageList;
    let hasMore = result.hasMore;

    let {
      messageList,
      playingVoice,
      playingMusicComponent
    } = context.data;
    messageList = messages.concat(messageList);
    let toView = '';
    if (params.position == 0) {
      let index = messageList.length - 1;
      let message = messageList[index] || {};
      toView = message.uId || '';
    }
    let isFirst = (position == 0);
    if (!hasMore && !isFirst) {
      // 灰条提示
      toView = 'message-notify-without';
      context.setData({
        hasMore: hasMore
      });
    }

    if (isFirst) {
      context.setData({
        messageList: messageList,
        isAllowScroll: true,
        toView: toView
      });
    } else {
      context.setData({
        messageList: messageList,
        isAllowScroll: true
      });
    }

  });
};

const updatePlayStatus = (context, {
  newMusicComponent,
  isPlaying
}, callback) => {
  let {
    data: {
      messageList,
      playingMusicComponent
    }
  } = context;
  callback = callback || utils.noop;
  messageList.map((message) => {
    callback(message);
    return message;
  });
  if (playingMusicComponent) {
    playingMusicComponent.setData({
      isPlaying
    });
  }
  if (newMusicComponent) {
    context.setData({
      playingMusicComponent: newMusicComponent,
      messageList
    });
  } else {
    context.setData({
      messageList
    });
  }

};

const stopPlayMusic = (context) => {
  let newMusicComponent = null,
    isPlaying = false;
  updatePlayStatus(context, {
    newMusicComponent,
    isPlaying
  }, (message) => {
    utils.extend(message, {
      isPlaying
    });
  });
};

const getImageUrls = (context) => {
  let {
    messageList
  } = context.data;
  return messageList.filter(message => {
    return message.name == 'ImageMessage';
  }).map(message => {
    return message.content.imageUri;
  });
};
const byAccount = (context, type) => {
  request({
    url: 'my/byAccount',
    data: {
      accountId: type == 'my' ? wx.getStorageSync('userId') : context.data.userId
    }
  }).then(e => {
    if (e.data.status == 1) {
      context.setData({
        [type]: e.data.data
      })
    }
  })
}
const mygetHistory = (context, first) => {
  console.log(context.data.targetId, context.data.timestrap, context.data.count)
  getHistory(context.data.targetId, context.data.timestrap, context.data.count).then(({
    list,
    hasMsg
  }) => {
    list = [...list, ...context.data.messageList]
    console.log(list, hasMsg)
    list.forEach(element => {
      if (element.senderUserId == element.targetId) {
        element.direction = 'receiver'
      } else {
        element.direction = 'sender'
      }
    })
    context.setData({
      messageList: list,
      hasMsg: hasMsg,
      timestrap: list[0].sentTime
    })
    if (first) {
      gotoView(context,true)
    }
  })
}
const onLoad = (context, query) => {
  clear = true
  newW = true
  setChatRoom(context)
  let {
    title,
    type,
    targetId
  } = query;
  wx.setNavigationBarTitle({
    title
  });
  context.setData({
    adapterHeight: adapterHeight,
    type,
    targetId,
    userId: targetId
  });
  mygetHistory(context, true);
  byAccount(context, 'my');
  byAccount(context, 'your');
  let keyboardHeight = 0;

  setKeyboardPos(context, keyboardHeight, adapterHeight);
  // app.setChat(context)
  let position = 0;
  let count = 15;
  // getMessageList(context, { type, targetId, position, count });

  // Message.watch((message) => {
  //   if (message.isOffLineMessage) {
  //     return;
  //   }
  //   if (message.type == type && message.targetId === targetId) {
  //     let { messageList } = context.data;
  //     // console.log(message,1111111111111111111111111111)
  //     messageList.push(message);
  //     context.setData({
  //       messageList,
  //       toView: message.uId
  //     });
  //     Conversation.clearUnreadCount({
  //       type, targetId
  //     });
  //   }
  // });
};

const onUnload = (context) => {
  clear = false
  newW = false
  let {
    playingVoice,
    playingMusicComponent
  } = context.data;
  if (playingVoice) {
    playingMusicComponent.stop();
  }
  if (playingMusicComponent) {
    playingMusicComponent.stop();
  }
  // Message.unwatch();
};

const showVoice = (context) => {
  let {
    adapterHeight
  } = context.data;
  context.setData({
    isShowKeyboard: false
  });
  hideKeyboard(context);
};

const showKeyboard = (context) => {
  context.setData({
    isShowKeyboard: true
  });
  hideKeyboard(context);
};
  const gotoView = (context,first) => {

    context.setData({
      toView: context.data.messageList[context.data.messageList.length - 1].messageUId
    })
    if (timer === null && !first && newW) {
      console.log("Start")
      timer = setInterval(() => {
        dangDate = parseInt(dangDate) + 1
        // console.log(dangDate)
        if (dangDate > timeInt) {
          context.showpjPopup()
          dangDate = 0
          wx.setStorageSync(LTID, 0)
          clearInterval(timer)
          timer = null
        }
      }, 1000);
    }
  }
const recorderManager = wx.getRecorderManager()

const startRecording = (context) => {

  wx.getSetting({
    success(res) {
      console.log(res.authSetting)
      // res.authSetting = {
      //   "scope.userInfo": true,
      //   "scope.userLocation": true
      // }
      wx.authorize({
        scope: 'scope.record',
        success() {
          // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
          wx.startRecord()
        }
      })
    }
  })
  // setTimeout(function () {
  //   wx.stopRecord() // 结束录音
  // }, 1000)
  context.setData({
    isRecording: true
  });
  let record = () => {
    recorderManager.start({
      format: 'aac'
    });
  };
  wx.getSetting({
    success(res) {
      if (!res.authSetting['scope.record']) {
        wx.authorize({
          scope: 'scope.record',
          success: record
        })
      } else {
        record();
      }
    }
  })
};

const stopRecording = (context) => {
  context.setData({
    isRecording: false
  });
  let {
    type,
    targetId,
    messageList
  } = context.data
  recorderManager.onStop((res) => {
    console.log('recorder stop', res)
    var {
      tempFilePath,

      fileSize
    } = res;
    console.log(tempFilePath, duration);
    var duration = res.duration
    duration = Math.ceil(duration / 1000)
    var fileType = RongIMLib.FileType.IMAGE;
    RongIMClient.getFileToken(fileType, {
      onSuccess: function (data) {
        console.log('上传 token 为', data.token);
        return wxUpload({
          path: tempFilePath,
          name: 'voice.aac'
        }, data.token).then(result => {
          console.log(result)
          let content = {
            // remoteUrl: file.downloadUrl,
            // duration: Math.ceil(duration / 1000)
          };
          let qiniuHash, qiniuName;
          const {
            data
          } = result;
          const {
            hash,
            name
          } = JSON.parse(data);
          qiniuHash = hash, qiniuName = name;
          console.log(RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, res))
          return RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, {
            onSuccess: (e) => {
              console.log(e.downloadUrl)
              var mediaUrl = e.downloadUrl
              var fileUrl = e.downloadUrl
              let extra = {}
              RegisterMessage(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra).then((e) => {
                messageList.push(e)
                context.setData({
                  messageList: messageList
                })
                gotoView(context)
              })
              // ImageMessage(targetId,tempFilePath,e.downloadUrl, extra ).then(e => {
              //   messageList.push(e)
              //   context.setData({
              //     messageList: messageList
              //   })
              //   gotoView(context)
              // }).catch(e => {
              //   wx.showToast({
              //     title: '发送失败~',
              //     icon: "none"
              //   })
              // })
            },
            onError: (e) => {
              console.log(e)
            }
          });

          // Message.sendImage({
          //   type,
          //   targetId,
          //   imageUri,
          //   extra,
          //   content: imgBase64
          // }).then(message => {});
        });

      },
      onError: function (error) {
        console.log('get file token error', error);
      }
    })
    //   File.upload({
    //     path: tempFilePath,
    //     name: 'voice.aac'
    //   }, 2).then(file => {
    //     console.log(file)
    //     let content = {
    //       remoteUrl: file.downloadUrl,
    //       duration: Math.ceil(duration / 1000)
    //     };
    //     let {
    //       type,
    //       targetId,
    //       messageList
    //     } = context.data;
    //     Message.sendVoice({
    //       type,
    //       targetId,
    //       content
    //     }).then(message => {
    //       messageList.push(message);
    //       context.setData({
    //         messageList,
    //         toView: message.uId
    //       });
    //     });
    //   });
  })
  recorderManager.stop();
};
const uploadBos = (url, fileInfo, header) => {
  return new Promise((resolve, reject) => {
    const fileData = wx.getFileSystemManager().readFileSync(fileInfo.path);
    wx.request({
      url: url,
      header: header,
      method: 'POST',
      data: fileData,
      success: function (res) {
        console.log(res);
        let data = {
          downloadUrl: url, //上传成功的 url 即为下载 url
          isBosRes: true // 判断是否是百度返回
        }
        resolve(data);
      },
      fail: reject
    })
  })

}
const wxUpload = (fileInfo, token) => {
  return new Promise((resolve, reject) => {
    const uploadTask = wx.uploadFile({
      url: Config.qiniuHost,
      filePath: fileInfo.path,
      name: 'file',
      formData: {
        token: token
      },
      success: resolve,
      fail: function (err) {
        console.log(err)
        // console.log('upload qiniu failed', err);
        // uploadBos(bosUrl, fileInfo, bosHeaders).then(function(res) {
        //   resolve(res);
        // },function(err) {
        //   reject(err)
        // });
      }
    })
    wx.showLoading({
      title: '上传中',
    })
    uploadTask.onProgressUpdate(res => {
      if (res.progress == 100) {
        wx.hideLoading({
          complete: (res) => { },
        })
      }
      console.log('上传进度', res.progress)
      console.log('已经上传的数据长度', res.totalBytesSent)
      console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
    })
  });
};

const showEmojis = (context) => {
  showSoftKeyboard(context, {
    emoji: 'block',
    more: 'none'
  });
};

const showMore = (context) => {
  showSoftKeyboard(context, {
    emoji: 'none',
    more: 'block'
  });
};

const selectEmoji = (context, event) => {
  var content = context.data.content;
  var {
    emoji
  } = event.target.dataset;
  content = content + emoji;
  context.setData({
    content: content,
    isShowEmojiSent: true
  });
};

const sendText = (context) => {
  let {
    content,
    type,
    targetId,
    messageList
  } = context.data;
  // console.log(content)
  // console.log(content, type, targetId, messageList)
  
  context.setData({
    content: '',
    isShowEmojiSent: false
  });

  TextMessage(targetId, content).then(e => {
    messageList.push(e)
    context.setData({
      messageList: messageList
    })
    gotoView(context)
  }).catch(e => {
    wx.showToast({
      title: '发送失败~',
      icon: "none"
    })
  })
  // content = {
  //   content,
  //   extra
  // }
  // console.log(content)
  // content = JSON.stringify(content)
  // if (content.length == 0) {
  //   return;
  // }
  // Message.sendText({
  //   type,
  //   targetId,
  //   content,
  // }).then(message => {
  //   message.content.extra = extra
  //   message.extra = extra
  //   messageList.push(message);
  //   context.setData({
  //     messageList,
  //     toView: message.uId
  //   });
  // });
};

const getMoreMessages = (context) => {
  let {
    type,
    targetId,
    hasMore,
    messageList
  } = context.data;
  messageList = messageList || [];
  let firstMessage = messageList[0] || {};
  let position = firstMessage.sentTime || 0;
  let count = 5;
  if (context.data.hasMsg) {
    // context.data.timestrap ++ ;
    context.setData({
      isAllowScroll: false,
    });
    mygetHistory(context);
    // , { type, targetId, position, count }
  } else {
    context.setData({
      isAllowScroll: false,
    });
    wx.showToast({
      title: '没有更多消息了',
      icon: "none",
    })
  }
};

const sendImage = (context) => {
  wx.chooseImage({
    count: 1,
    sizeType: ['original'],
    sourceType: ['album', 'camera'],
    success: (res) => {
      let {
        tempFilePaths,
        tempFiles
      } = res;
      let tempFilePath = tempFilePaths[0];
      console.log('tempFilePath', tempFilePath)
      // ImageMessage
      wx.getImageInfo({
        src: tempFilePath,
        success: (res) => {
          let extra = utils.compress(res);
          let {
            type,
            targetId,
            messageList
          } = context.data;

          let name = 'RC:ImgMsg';
          let content = {
            imageUri: tempFilePath,
            extra
          };
          console.log(res, content)
          var fileType = RongIMLib.FileType.IMAGE;
          RongIMClient.getFileToken(fileType, {
            onSuccess: function (data) {
              console.log('上传 token 为', data.token);
              return wxUpload({
                path: tempFilePath,
                name: 'image.png'
              }, data.token).then(result => {
                console.log(result)
                let qiniuHash, qiniuName;
                const {
                  data
                } = result;
                const {
                  hash,
                  name
                } = JSON.parse(data);
                qiniuHash = hash, qiniuName = name;
                console.log(RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, res))
                return RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, {
                  onSuccess: (e) => {
                    ImageMessage(targetId, tempFilePath, e.downloadUrl, extra).then(e => {
                      messageList.push(e)
                      context.setData({
                        messageList: messageList
                      })
                      gotoView(context)
                    }).catch(e => {
                      wx.showToast({
                        title: '发送失败~',
                        icon: "none"
                      })
                    })
                  },
                  onError: (e) => {
                    console.log(e)
                  }
                });
              });
            },
            onError: function (error) {
              console.log('get file token error', error);
            }
          })
        }
      })
    }
  })
};

const sendFile = (context) => {
  let {
    type,
    targetId,
    messageList
  } = context.data;

  wx.chooseMessageFile({
    count: 1,
    type: 'file',
    success: function (res) {
      let {
        tempFiles
      } = res;
      let {
        name,
        size,
        type: fileType
      } = tempFiles[0];
      File.upload(tempFiles[0], 4).then(result => {
        const {
          downloadUrl: fileUrl
        } = result;
        console.log(fileUrl)
        let content = {
          name,
          size,
          type: fileType,
          fileUrl
        };
        let message = Message.create({
          type: 4,
          targetId,
          name: 'RC:FileMsg',
          content
        });
        messageList.push(message);
        context.setData({
          messageList,
          toView: message.uId
        });
        Message.sendFile({
          type,
          targetId,
          name,
          size,
          fileUrl
        })
      });
    }
  })
}
const sendAudio = (context) => {
  let {
    type,
    targetId,
    messageList
  } = context.data;
  context.login()
}
const sendVideo = (context) => {
  wx.chooseVideo({
    count: 1,
    sourceType: ['album', 'camera'],
    success: (res) => {
      console.log('tempFilePath', res)
      let extra = utils.compress(res);
      let {
        type,
        targetId,
        messageList
      } = context.data;
      let content = {
        imageUri: tempFilePath,
      };
      var {
        tempFilePath,
        fileSize,
        duration
      } = res;
      console.log(tempFilePath, duration);
      var fileType = RongIMLib.FileType.IMAGE;
      RongIMClient.getFileToken(fileType, {
        onSuccess: function (data) {
          console.log('上传 token 为', data.token);
          return wxUpload({
            path: tempFilePath,
            name: 'voice.mp'
          }, data.token).then(result => {
            console.log(result)
            let content = {
              // remoteUrl: file.downloadUrl,
              // duration: Math.ceil(duration / 1000)
            };
            let qiniuHash, qiniuName;
            const {
              data
            } = result;
            const {
              hash,
              name
            } = JSON.parse(data);
            qiniuHash = hash, qiniuName = name;
            console.log(RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, res))
            return RongIMClient.getFileUrl(fileType, qiniuHash, qiniuName, {
              onSuccess: (e) => {
                console.log(e.downloadUrl)
                var mediaUrl = e.downloadUrl
                var fileUrl = e.downloadUrl
                let extra = {}
                RegisterMessage1(targetId, name, mediaUrl, fileUrl, fileType, fileSize, duration, extra).then((e) => {
                  messageList.push(e)
                  context.setData({
                    messageList: messageList
                  })
                  gotoView(context)
                })

              },
              onError: (e) => {
                console.log(e)
              }
            });
          });
        },
        onError: function (error) {
          console.log('get file token error', error);
        }
      })
    }
  })
}
const sendMusic = (context) => {
  let {
    content,
    type,
    targetId,
    messageList
  } = context.data;
  Message.sendMusic({
    type,
    targetId
  }).then(message => {
    messageList.push(message);
    context.setData({
      messageList,
      toView: message.uId
    });
  });
};

const playVoice = (context, event) => {
  let voiceComponent = event.detail;
  let {
    playingVoice
  } = context.data;
  if (playingVoice) {
    let playingId = playingVoice.__wxExparserNodeId__;
    let voiceId = voiceComponent.__wxExparserNodeId__;
    // 两次播放为同个音频,状态保持不变 
    if (playingId == voiceId) {
      return;
    }
    let {
      innerAudioContext
    } = playingVoice.data;
    playingVoice.setData({
      isPlaying: false
    });
    innerAudioContext.stop();
  }
  context.setData({
    playingVoice: voiceComponent
  });
};

const playMusic = (context, event) => {
  let newMusicComponent = event.detail;
  let {
    playingMusicComponent,
    messageList
  } = context.data;
  let {
    properties: {
      message: {
        messageUId: newPlayId
      }
    }
  } = newMusicComponent
  let playingId = '';

  // 连续点击播放不同音乐
  if (playingMusicComponent) {
    let {
      properties: {
        message
      }
    } = playingMusicComponent;
    playingId = message.messageUId;
    //先停止上一个,再播放
    let isDiffMusic = (playingId != newPlayId);
    if (isDiffMusic) {
      let {
        innerAudioContext
      } = playingMusicComponent.data;
      playingMusicComponent.setData({
        isPlaying: false
      });
      innerAudioContext.stop();
    }
  }
  let isPlaying = false;
  updatePlayStatus(context, {
    newMusicComponent,
    isPlaying
  }, (message) => {
    let {
      messageUId
    } = message;
    // 默认为未播放状态
    isPlaying = false;
    if (messageUId == newPlayId) {
      isPlaying = true;
    }
    utils.extend(message, {
      isPlaying
    });
  });
};

const previewImage = (context, event) => {
  let currentImageUrl = event.detail;
  let urls = getImageUrls(context);
  if (utils.isEmpty(urls)) {
    urls.push(currentImageUrl);
  }
  wx.previewImage({
    current: currentImageUrl,
    urls: urls
  })
};

const stopMusic = (context, event) => {
  let musicComponent = event.detail;
  let {
    properties: {
      message: {
        messageUId
      }
    }
  } = musicComponent;

  let {
    messageList,
    playingMusicComponent
  } = context.data;
  if (playingMusicComponent) {
    let {
      data: {
        innerAudioContext
      }
    } = playingMusicComponent;
    innerAudioContext.stop();
  }
  musicComponent.setData({
    isPlaying: false
  });
  stopPlayMusic(context);
};
// call用到的方法
const expertRecord = (context) => {
  if (context.data.count == 0) {
    request({
      url: 'index/expertRecord',
      data: {
        token: wx.getStorageSync("token"),
        id: context.data.userId
        // 
      }
    }).then((e) => {
      if (e.data.status === 1) {
        context.setData({
          count: 1
        })
      }
    })
  }

}
Page({
  data: {
    count: 8,
    timestrap: 0,
    hasMsg: true,
    my: {},
    your: {},
    pjvalue: 0,
    // call中用到的data
    userId: '',
    isHiddenTip: true,
    pjshow: false,
    apps,
    appkeys: apps.map(item => item.appkey),
    appkeyIndex: 0,
    msUrls: msUrls.map(item => item.title),
    msUrl: msUrls[0],
    // 默认data
    content: '',
    messageList: [],
    bottom: 0,
    adapterHeight: 0,
    display: {
      emoji: 'none',
      more: 'none'
    },
    emojis: formatEmojis(),
    isShowEmojiSent: false,
    isRecording: false,
    isShowKeyboard: false,
    hasMore: true,
    toView: '',
    playingVoice: null,
    playingMusicComponent: null,
    isAllowScroll: true,
    scrollTop: 0
  },
  evaluateExpert() {
    request({
      url: "index/evaluateExpert",
      data: {
        token: wx.getStorageSync('token'),
        id: this.data.userId,
        level: this.data.pjvalue
      }
    }).then(res => {
      if (res.data.status == 1) {
        wx.showToast({
          title: res.data.msg,
        })
        this.onpjClose()
      }
    })
  },
  onpjChange(event) {
    this.setData({
      pjvalue: event.detail,
    });
  },
  showpjPopup() {
    if (wx.getStorageSync('status') == 1) {
      this.setData({ pjshow: true });
    }
  },

  onpjClose() {
    this.setData({ pjshow: false, pjvalue: 0 });
  },
  expertRecord: function () {
    expertRecord(this)
  },
  hideKeyboard: function () {
    hideKeyboard(this);
  },
  selectEmoji: function (event) {
    selectEmoji(this, event);
  },
  sendText: function () {
    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     console.log(dangDate)
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);
    // }
    sendText(this);
  },
  getMoreMessages: function (event) {
    getMoreMessages(this);
  },
  sendImage: function () {

    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);
    // }

    sendImage(this);
  },
  sendFile: function () {
    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);
    // }
    sendFile(this);
  },
  sendAudio: function () {
    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);
    // }
    sendAudio(this)
  },
  sendVideo: function () {

    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);

    // }
    sendVideo(this)
  },
  sendMusic: function () {

    // if (timer === null) {
    //   timer = setInterval(() => {
    //     dangDate = parseInt(dangDate) + 1
    //     if (dangDate > timeInt) {
    //       this.showpjPopup()
    //       dangDate = 0
    //       clearInterval(timer)
    //       timer = null
    //     }
    //   }, 1000);

    // }
    sendMusic(this);
  },
  showVoice: function () {

    showVoice(this);
  },
  showKeyboard: function () {
    showKeyboard(this);
  },
  startRecording: function () {
    startRecording(this);
  },
  stopRecording: function () {
    stopRecording(this);
  },
  showEmojis: function () {
    showEmojis(this);
  },
  showMore: function () {
    showMore(this);
  },
  gotoView(){
    gotoView(this)
  },
  // 以下是事件
  onLoad: function (query) {
    onLoad(this, query)
    LTID = wx.getStorageSync('LT' + wx.getStorageSync('userId') + query.targetId)
    console.log()
    if (dangDate === null) {
      if (LTID) {
        dangDate = LTID ? LTID : 0
      } else {
        wx.setStorageSync('LT' + wx.getStorageSync('userId') + query.targetId, 0)
        dangDate = 0
      }
    }
    console.log('LT' + wx.getStorageSync('userId') + query.targetId,LTID,dangDate)
    query.count && this.setData({
      count: query.count
    })
  },
  onUnload: function () {
    onUnload(this);
    console.log(LTID, LTID !== null)
    if (LTID !== null) {
      console.log('LT' + wx.getStorageSync('userId') + this.data.targetId, dangDate)
      wx.setStorageSync('LT' + wx.getStorageSync('userId') + this.data.targetId, dangDate)
      LTID = null
      dangDate = null
    }
    clearTimeout(timer)
    timer = null
  },
  onInput: function (event) {
    this.setData({
      content: event.detail.value
    });
  },
  onFocus: function (event) {
    let {
      height
    } = event.detail;
    let adapterHeight = 0;
    setKeyboardPos(this, height, adapterHeight);
    hideSoftKeyboard(this);
  },
  onPlayVoice: function (event) {
    playVoice(this, event);
  },
  setNewMessage(newMessage) {
    setNewMessage(this, newMessage)
  },
  onPlayMusic: function (event) {
    playMusic(this, event);
  },
  onMusicStop: function (event) {
    stopMusic(this, event);
  },
  onPreviewImage: function (event) {
    previewImage(this, event);
  },
  onHide: function () {
    hideKeyboard(this);
    stopPlayMusic(this);
  },
  // call的方法
  async login() {
    if (doLogin) {
      return;
    }
    doLogin = true;
    let context = this;
    let {
      data: {
        userId,
        msUrl,
        appkeyIndex
      }
    } = context;
    console.log(userId, msUrl, appkeyIndex)
    let isUserEmpty = callUtils.isEmpty(userId);
    if (isUserEmpty) {
      context.setData({
        isHiddenTip: !isUserEmpty
      });
      doLogin = false;
      return;
    }

    const {
      appkey,
      secret
    } = apps[appkeyIndex];

    wx.showLoading({
      title: '登录中',
      mask: true
    })
    let result;
    try {
      result = await co(wx.request)({
        url: serverUrl,
        method: 'POST',
        data: {
          appkey,
          secret,
          userId,
          name: userId,
          portrait: `portrait-${userId}`,
        },
      });
    } catch (error) {
      doLogin = false;
      wx.hideLoading();
      common.showToast(`获取 Token 失败 ${error.statusCode}`);
      return;
    }

    wx.hideLoading();

    const {
      token,
      code,
      msg
    } = result.data;
    if (code !== 200) {
      console.error(code, msg);
      return;
    }

    // app.setServiceConf(appkey, msUrl.url);

    wx.navigateTo({
      url: `../main/main?token=${encodeURIComponent(token)}&userId=${userId}&appkey=${appkey}`,
    });

    doLogin = false;
  },
  call1() {
    if (timer === null) {
      console.log("Start")
      timer = setInterval(() => {
        dangDate = parseInt(dangDate) + 1
        // console.log(dangDate)
        if (dangDate > timeInt) {
          this.showpjPopup()
          dangDate = 0
          clearInterval(timer)
          timer = null
        }
      }, 1000);
    }
    wx.navigateTo({
      url: '../call/call?type=2&targetId=' + this.data.targetId,
    })
  },
  call2() {
    if (timer === null) {
      console.log("Start")
      timer = setInterval(() => {
        dangDate = parseInt(dangDate) + 1
        // console.log(dangDate)
        if (dangDate > timeInt) {
          this.showpjPopup()
          dangDate = 0
          clearInterval(timer)
          timer = null
        }
      }, 1000);
    }
    wx.navigateTo({
      url: '../call/call?type=0&targetId=' + this.data.targetId,
    })
  },

  selectLocation() {
    let that = this
    let {
      messageList
    } = that.data;
    wx.getLocation({
      type: 'gcj02',
      altitude: 'true',
      success(res) {
        const latitude = res.latitude
        const longitude = res.longitude
        const speed = res.speed
        const accuracy = res.accuracy
        let context = `https://restapi.amap.com/v3/staticmap?markers=-1,http://www.5imoban.net/view/demoimg/jrzb_position_icon.png,0:${longitude},${latitude}&key=ee95e52bf08006f63fd29bcfbcf21df0&zoom=17&size=360*200&location=${longitude},${latitude}`

        wx.chooseLocation({
          latitude,
          longitude,
          complete: (res) => {
            console.log(res)
            if (res.latitude) {
              LocationMessage(that.data.targetId, res.latitude, res.longitude, res.address, context).then(ele => {
                console.log(ele)
                messageList.push(ele)
                that.setData({
                  messageList: messageList
                })
                gotoView(that)
              })
            }
          }
        })
      }
    })

  },
  onShow(){
    // let context = this
    // mygetHistory(context, true);
  }

})

这个是我打电话界面的js(也是还没整理)优化的余地还是很多的,奈何没有时间)

// pages/call/call.js
import {
  request
} from "../../request/index"
let count = true;
let timer;
// const { TextMessage } = getApp()
const common = require('../common');
const utils = require('../../utils/util.js');
let TextMessage = null;
let rongCallLib = null;
let RongIMLib = null;

// const {Service:{rongCallLib,RongIMLib}} = getApp().globalData
// console.log(getApp().globalData)
// console.log(Call,ConversationType,MessageType,Connection)
// const  rongCallLib
let hungupCount = false
function backNav() {
  console.log(hungupCount)
  if (hungupCount) {
    console.log('执行')
    wx.navigateBack({
      complete: (res) => { },
    })
    hungupCount = false
  }

}
const conversationTypes = [
  { type: 1, label: '单聊' },
  { type: 3, label: '群聊' }
];
const MediaTypes = [
  { type: 2, label: '视频通话' },
  { type: 1, label: '音频通话' },
];
const Status = {
  // 空闲
  FREE: 0,
  // 等待接听或挂断,暂未加入房间,包含呼入、呼出场景
  WAITING: 1,
  // 通话中,即已经加入房间,群聊状态下有一人曾接通过即进入到通话中状态
  TALKING: 2,
}
let that;
Page({

  /**
   * 页面的初始数据
   */
  desc: '',
  back: true,
  data: {
    crtUserId: '',

    // 通话状态
    status: Status.FREE,
    // 根据 status 变化修改,computed
    free: true,
    waiting: false,
    talking: false,
    // 群呼中途邀请标记
    inviting: false,
    // 被邀请人
    inviteUserIds: '',
    // 是否为呼入
    callin: false,
    // 当前通话的 targetId,单聊为对方 userId,群聊为 groupId
    crtTargetId: '',
    // 当前的通话类型
    crtConversationType: 0,
    // 当前通话中的人员,不包含自己,单聊时长度为 1,群聊时长度 >= 1,当长度为 0 时需挂断当前通话
    // 某些条件下,对方可能无法发送 hungupMessage 信息,如直接关闭应用、杀进程
    crtMembers: [],
    statusCall: true,
    // 输入选项
    conversationTypeOptions: conversationTypes.map(item => item.label),
    mediaTypeOptions: MediaTypes.map(item => item.label),
    message: null,
    // 输入表单
    userId: '',
    groupId: '',
    conversationTypeIndex: 0,
    conversationType: conversationTypes[0].type,
    mediaTypeIndex: 0,
    mediaType: '',
    player: null,
    // 推送视频流
    pusher: null,
    targetId: '',
    // 拉取视频流:{ [userId]: mediaStream }
    streams: {
    },
    type: '',
    back: true,
    showUser: {},
    senderUserId: '',
    show: true,
    hungupfalse: false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  // 接听
  inputUserId(e) {
    const userId = e.detail.value;
    this.setData({ userId });
  },
  onLoad: function (options) {
    TextMessage = getApp().TextMessage
    rongCallLib = getApp().globalData.Service.rongCallLib
    RongIMLib = getApp().globalData.Service.RongIMLib
    console.log(rongCallLib)
    count = true
    that = this
    hungupCount = true
    // Connection.watch((status) => {
    //   console.log('status:', status);
    // });
    this.audioCtx = wx.createInnerAudioContext()
    this.audioCtx.src = '/image/1.mp3'
    this.audioCtx.loop = true
    this.audioCtx.play()
    console.log(options.data && JSON.parse(options.data))

    if (options.data) {
      // timer = setTimeout(() => {
      //   if(that.data.back){
      //     wx.showToast({
      //       title: '超时,未接通',
      //       icon:"none",
      //       success(){

      //         setTimeout(() => {
      //           wx.navigateBack({
      //             complete: (res) => {},
      //           })
      //         },200)
      //       }
      //     })
      //   }
      // },12000)
      this.setData({
        message: JSON.parse(options.data),
        senderUserId: JSON.parse(options.data).senderUserId
      })
      console.log(this.data.senderUserId, 11111111)
      this.setData({
        mediaType: this.data.message.content.mediaType
      })
      request({
        url: 'my/byAccount',
        data: {
          accountId: this.data.message.senderUserId,
        }
      }).then(e => {
        if (e.data.status == 1) {
          that.setData({
            showUser: e.data.data
          })
        }
      })
    }
    if (options.targetId) {
      console.log('我拨打')
      this.setData({
        mediaType: options.type == 0 ? 1 : 2
      })
      request({
        url: 'my/byAccount',
        data: {
          accountId: options.targetId
        }
      }).then(e => {
        if (e.data.status == 1) {
          that.setData({
            showUser: e.data.data
          })
        }
      })
      that.setData({
        userId: options.targetId,
        type: options.type
      }, () => {
        that.call()
      })
    }

    rongCallLib.videoWatch(this.onVideoChange1.bind(this));
    // this.onReceiveMessage(JSON.parse(options.data))
    rongCallLib.commandWatch(this.onVideoChange.bind(this));

  },
  onReceiveMessage(message) {
    // const { MessageType, ConversationType } = app.getService();
    console.log(message)
    const { messageType, conversationType, targetId, senderUserId, content } = message;
  },
  onVideoChange1(video) {
    const { type, userId, data } = video;
    if (type === 'added') {
      // 添加音视频节点
      console.log(userId == that.data.userId, userId, that.data.userId)
      this.setData({
        hungupfalse: true
      })
      if (userId == wx.getStorageSync('userId')) {
        that.setData({
          pusher: video
        })
      } else {

        that.setData({
          back: false,
          show: false,
          player: video
        })
      }

    } else if (type === 'removed') {
      // 删除对应音视频节点
      this.audioCtx.pause()
      wx.showToast({
        title: '通话结束',
        icon: "none"
      })
      this.setData({
        pusher: null,
        player: null
      })
      setTimeout(() => {
        backNav()
      }, 400);
    } else if (type === 'leave') {
      // 删除对应音视频节点
      this.audioCtx.pause()
      this.setData({
        pusher: null,
        player: null
      })

      if (that.data.back) {
        this.audioCtx.pause()
        wx.showToast({
          title: '通话结束',
          icon: "none"
        })
        setTimeout(() => {
          backNav()

        }, 400);
      }

    }
  },
  getSummaryText(status) {
    var text;
    switch (status) {
      // case 1:
      //   text = '己方已取消';
      //   break;
      // case 2:
      //   text = '己方已拒绝';
      //   break;
      // case 3:
      //   text = '己方挂断';
      //   break;
      case 4:
        text = `己方忙碌中, 不处理`;
        break;
      case 5:
        text = '己方未接听';
        break;
      // default:
      //   text = '未知原因';
    }
    return text;
  },
  onVideoChange(video) {
    const { type, userId, data } = video;
    const { streams } = this.data;
    console.log('commandWatch =>', video, video.content);
    if (video.messageType == "SummaryMessage") {
      var status = video.content.status;
      var promptText = this.getSummaryText(status);
      console.log(promptText)
      if (promptText) {
        wx.showToast({
          title: promptText,
          icon: "none"
        })
      }

      // if (status === 5) { // 自己未接听, 回到初始状态
      //   context.callStep = CallStep.READY_TO_CALL;
      // }
    }
    if (video.messageType == "HungupMessage" && video.content && video.content.reason) {
      let data = {
        1: '己方取消已发出的通话请求',
        2: '己方拒绝收到的通话请求',
        3: '己方挂断',
        4: '己方忙碌',
        5: '己方未接听',
        6: '当前引擎不支持',
        7: '己方网络出错',
        8: '其他端已经接听',
        11: '对方取消已发出的通话请求',
        12: '对方拒绝收到的通话请求',
        13: '通话过程对方挂断',
        14: '对方忙碌',
        15: '对方未接听',
        16: '对方引擎不支持',
        17: '对方网络错误',
        18: 'im ipc服务已断开',
      }
      console.log(data[video.content.reason])
      this.setData({
        desc: data[video.content.reason]
      })
      // this.hungup()
      wx.showToast({
        title: data[video.content.reason],
        icon: "none",
        success() {
          setTimeout(() => {
            backNav()

          }, 300)
        },
        complete(res) {
        }
      })
    }
    // if(this.data.hungupfalse && video.content && video.content.reason == 13 ){
    //   console.log('未接通被挂断')
    //   wx.showToast({
    //     title: data[video.content.reason],
    //     icon:"none",
    //     success(){
    //       setTimeout(() => {
    //         wx.navigateBack({
    //           complete: (res) => {},
    //         })
    //       },200)
    //     }
    //   })
    // }
    if (that.data.message && video.content && video.content.messageName == "HungupMessage") {
      console.log()

      this.audioCtx.pause()
      // if(this.data.player){
      //   wx.showToast({
      //     title: '对方已取消',
      //     icon:"none",
      //     success(){
      //       setTimeout(() => {
      //         wx.navigateBack({
      //           complete: (res) => {},
      //         })
      //       },200)
      //     }
      //   })
      // }

    }
    if (video.content && video.content.messageName == "AcceptMessage") {
      wx.hideLoading({
        complete: (res) => { },
      })
      this.audioCtx.pause()
      wx.showToast({
        title: '已接听',
      })
    }
    console.log(video.content && video.content.messageName == "InviteMessage")
    if (video.content && video.content.messageName == "InviteMessage") {
      console.log(video)
      that.setData({
        callin: true,
      })
      console.log(that.data)
    }
    function getSeconds(s) {
      var sTime = parseInt(s);// 秒
      var mTime = 0;// 分
      var hTime = 0;// 时
      if (sTime > 60) {//如果秒数大于60,将秒数转换成整数
        //获取分钟,除以60取整数,得到整数分钟
        mTime = parseInt(sTime / 60);
        //获取秒数,秒数取佘,得到整数秒数
        sTime = parseInt(sTime % 60);
        //如果分钟大于60,将分钟转换成小时
        if (mTime > 60) {
          //获取小时,获取分钟除以60,得到整数小时
          hTime = parseInt(mTime / 60);
          //获取小时后取佘的分,获取分钟除以60取佘的分
          mTime = parseInt(mTime % 60);
        }
      }
      var result = '';
      if (sTime >= 0 && sTime < 10) {
        result = "0" + parseInt(sTime) + "";
      } else {
        result = "" + parseInt(sTime) + "";
      }
      if (mTime >= 0 && mTime < 10) {
        result = "0" + parseInt(mTime) + ":" + result;
      } else {
        result = "" + parseInt(mTime) + ":" + result;
      }
      if (hTime >= 0 && hTime < 10) {
        result = "0" + parseInt(hTime) + ":" + result;
      } else {
        result = "" + parseInt(hTime) + ":" + result;
      }
      return result;
    }
    if (video.messageType == "SummaryMessage") {
      that.setData({
        player: null,
        pusher: null
      })
      // wx.showToast({
      //   icon:"none",
      //   title: '语音超时未接通',
      // })
      // wx.navigateBack({
      //   complete: (res) => {
      //     console.log("挂断")
      //   },
      // })
      backNav()
      this.audioCtx.pause()
      console.log(video.senderUserId, '-----------------')
      if (video.senderUserId == wx.getStorageSync('userId') && count) {
        count = false
        let targetId = video.targetId
        let content = getSeconds(video.content.duration / 1000)
        console.log('取消时呼叫方', video.content)
        if (video.content.duration > 0) {
          content = '通话结束:' + content
        } else {
          content = '[语音未接通]'
        }
        console.log(content)
        TextMessage(targetId, content).then(e => {
          console.log(e)
          let pages = getCurrentPages()[getCurrentPages().length - 1]
          pages.data.messageList.push(e)
          pages.setData({
            messageList: pages.data.messageList
          }, () => {
            pages.gotoView()
          })
          // wx.navigateBack({
          //   complete: (res) => {},
          // })
        }).catch(e => {
          console.log(e)
          wx.showToast({
            title: '发送失败~',
            icon: "none"
          })
        })
      }

    }

  },
  setStatus(status) {
    const free = status === Status.FREE;
    const data = {
      status,
      free,
      talking: status === Status.TALKING,
      waiting: status === Status.WAITING,
    };
    if (free) {
      data.crtTargetId = '';
      data.crtConversationType = 0;
      data.crtMembers = [];
      data.pusher = null;
      data.streams = {};
    }
    this.setData(data);
  },
  async call() {
    var CallType = RongIMLib.VoIPMediaType;
    console.log('222222222222', CallType, this.data.type == 0 ? CallType.MEDIA_AUDIO : CallType.MEDIA_VIDEO)
    this.setData({
      mediaType: this.data.type == 0 ? CallType.MEDIA_AUDIO : CallType.MEDIA_VIDEO
    })
    var params = {
      conversationType: RongIMLib.ConversationType.PRIVATE,
      targetId: this.data.userId,
      inviteUserIds: [this.data.userId],
      mediaType: this.data.type == 0 ? CallType.MEDIA_AUDIO : CallType.MEDIA_VIDEO
      // RongIMLib.VoIPMediaType.MEDIA_VEDIO
    };
    console.log(this.data.type, params)
    wx.showLoading({
      title: '呼叫中...',
    })
    rongCallLib.call(params, (error) => {
      console.log(error)
      wx.hideLoading({
        complete: (res) => { },
      })

      if (error) {
        if (error.code == 4) {
          that.setData({
            back: false
          })
          this.hungup(1)
        } else {
          that.setData({
            back: true
          })
          this.hungup()
        }
        // wx.showToast({
        //   title: error.info,
        //   icon:"none"
        // })
        wx.hideLoading({
          complete: (res) => { },
        })
        // wx.showToast({
        //   title: '呼叫失败',
        //   icon:"none"
        // })
        this.audioCtx.pause()
        console.error('发起通话失败', error);
      }
    });
  },
  accept() {
    //  setTimeout(()=>{
    //   console.log(that,that.data)
    //  })
    console.log(this.data.mediaType)
    var params = {
      conversationType: that.data.message.conversationType,
      targetId: that.data.message.targetId,
      mediaType: this.data.mediaType
    };
    console.log(params)
    this.audioCtx.pause()
    rongCallLib.accept(params, function (error) {
      that.setData({
        senderUserId: that.data.message.senderUserId,
        message: null
      })
      if (error) {
        console.error('接听通话失败', error);
        wx.showToast({
          title: '接听通话失败',
          icon: "none",
          success: () => {
            setTimeout(() => {
              backNav()


            }, 300)
          }
        })
      }
    });
  },
  async reject() {
    var params = {
      conversationType: RongIMLib.ConversationType.PRIVATE,
      targetId: this.data.senderUserId
    };
    rongCallLib.reject(params, function (error) {
      if (error) {
        console.error('拒绝通话失败', error);
      }
    });
  },
  async hungup(a) {
    wx.hideLoading()
    console.log(11111, '挂断', this.data.type, this.data.userId, this.data.senderUserId)
    var params = {
      conversationType: RongIMLib.ConversationType.PRIVATE,
      targetId: this.data.type ? this.data.userId : this.data.senderUserId
    };
    console.log(212, params)

    if (a.currentTarget) {
      this.setData({
        statusCall: false
      })
    }
    rongCallLib.hungup(params, function (error) {
      console.log(error)
      if (a != 1) {
        console.log(error)

        setTimeout(() => {
          backNav()

        }, 400);
      } else {
        // that.call()
      }

      if (error) {
        console.error('挂断通话失败', error);
        // wx.showToast({
        //   title: error.msg,
        //   icon:"none"
        // })
        setTimeout(() => {
          backNav()

        }, 400);
      }
    });
  },
  onUnload() {
    // clearTimeout(timer)
    this.audioCtx.pause()
    if (this.data.statusCall) {
      this.hungup(1)
      this.data.message ? console.log("拒接") : console.log("挂断")
      // this.data.message ?  '' :  this.data.pusher ? this.hungup(1) : ''
      that.setData({
        player: null,
        pusher: null
      })
    }
  }
})  

w

你可能感兴趣的:(微信小程序,微信小程序即时通讯)