当前位置:   article > 正文

uniapp使用腾讯im 无ui集成方案写法_腾讯im uniapp

腾讯im uniapp

页面显示
在这里插入图片描述
在这里插入图片描述

1.无ui集成方案

1.1 首先下来依赖
//初始化
npm init
// IM Web SDK
// 从v2.11.2起,SDK 支持了 WebSocket,推荐接入;v2.10.2及以下版本,使用 HTTP
npm install tim-js-sdk --save
// 发送图片、文件等消息需要腾讯云即时通信 IM 上传插件
npm install tim-upload-plugin --save
// 拦截或替换敏感词需要本地审核插件
npm install tim-profanity-filter-plugin --save
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
1.2 创建tim.js
import TIM from 'tim-js-sdk/tim-js-friendship.js'
import TIMUploadPlugin from 'tim-upload-plugin';
import TIMProfanityFilterPlugin from 'tim-profanity-filter-plugin';

// import COS from "cos-js-sdk-v5";
  • 1
  • 2
  • 3
  • 4
  • 5


​ const options = {
​ SDKAppID: 1600024346
​ // 接入时需要将0替换为您的即时通信应用的 SDKAppID
​ };
​ // 创建 SDK 实例,TIM.create() 方法对于同一个 SDKAppID 只会返回同一份实例
​ const tim = TIM.create(options); // SDK 实例通常用 tim 表示
​ // tim.setLogLevel(0);
​ const TIMData = TIM
​ // 注册腾讯云即时通信 IM 上传插件
​ tim.registerPlugin({
​ ‘tim-upload-plugin’: TIMUploadPlugin
​ });

// 注册腾讯云即时通信 IM 本地审核插件
tim.registerPlugin({
	'tim-profanity-filter-plugin': TIMProfanityFilterPlugin
});

// 注册 COS SDK 插件
// tim.registerPlugin({'cos-js-sdk': COS});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7



​ /* eslint-disable require-jsdoc */
​ function genTestUserSig(userID) {
​ const SDKAPPID = 1600024346;
​ const EXPIRETIME = 604800;
​ const SECRETKEY = ‘a03e633a7f9e49784a8f1b1d87ebc4d930be70544e13822bdd8f9a0af40acc1’;

const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
const userSig = generator.genTestUserSig(userID);

	return {
		sdkAppId: SDKAPPID,
		userSig: userSig
	};
}

export default {
	tim,
	TIMData,
	genTestUserSig
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
1.3 在main.js导入
import tim from './utils/tim.js'
import TIM from 'tim-js-sdk/tim-js-friendship.js'

Vue.prototype.tim = tim.tim //tim sdk 引入后生成的tim服务
Vue.prototype.$TIM = TIM //tim 的状态/事件 常量
  • 1
  • 2
  • 3
  • 4
  • 5
2.1 在登录接口存储用户信息
//用户信息
		user() {
			this.$helper.apiPost(this.$api.tab.user).then(ret => {
				if (ret.data.code == 200) {
					this.info = ret.data.data
					//根据返回的userID 以及 userSig 登录tim
					uni.setStorageSync('uid', ret.data.data.username)
					//这里我叫后端返回了一个userSing
					uni.setStorageSync('uid_sig', ret.data.data.user_sig)
					console.log(this.info, '122332211');
					this.tim.login({
						userID: this.info.username,
						userSig: this.info.user_sig
					}).then((imResponse) => {
						this.$helper.showToast('登录成功')
						setTimeout(() => {
							uni.switchTab({
								url: '/pages/tab/home'
							})
						}, 500)
					})
				}
			})
		},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
2.2 进入首页
 data() {
		return {
			userID: uni.getStorageSync('uid'),
			userSig: uni.getStorageSync('uid_sig'),
		};
	},
 onLoad() {
		this.cosImLogin()
	},
 methods: {
	 cosImLogin() {
		console.log(this.userID, 'this.userID');
		console.log(this.userSig, 'this.userSig');
		if (!this.userID.length || !this.userSig.length) return
			this.tim.login({
				userID: this.userID,
				userSig: this.userSig
			}).then((res) => {
				this.loginTUICallKit()
			}).catch((err) => {
				console.log("报错", err)
			})
		},
	 loginTUICallKit() {
			const options = {
				SDKAppID: 1600024346, // 请替换为步骤一取到的 SDKAppID
				userID: this.userID, // 请替换为您的 UserID
				userSig: this.userSig, // 您可以在控制台中计算一个 UserSig 并填在这个位置
			};
			this.$TUICallKit.login(options, (res) => {
				if (res.code === 0) {
					console.log('login success');
					this.$TUICallKit.enableFloatWindow(true); // 开启小浮窗
				} else {
					console.log(`login failed, error message = ${res.msg}`);
				  }
				});
			},
		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
2.3 我的好友列表
export default {
	data() {
		return {
			friends: []
		};
	},

	onLoad() {
		this.friendList();
	},
	methods: {
		openConversation(name, userID) {
		// userID:电话号码  username:昵称 
		//跳转到聊天页面(聊天页面自定义头部所以要携带昵称)
		this.$helper.toPage('/pages/active/chat?name=' + name + '&userID=' + userID);
	 },
	    //我的好友
		async friendList() {
			let res = await this.$helper.apiPost(this.$api.user.friend_list);
			this.friends = res.data.data;
			console.log(this.friends);
		}
	}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
3.1 聊天页面

3.1.1 对话内容

3.1.1 对话内容
<view class="msg-content-list">
   <mescroll-uni ref="mescrollRef" :fixed="false" :down="downOption" @init="mescrollInit" @down="downCallback"	@up="upCallback">
	 <view>
		<view class="msg-content-item" v-for="(item, index) in msgList">
		  <view class="time-slot" v-if="item.isShowTime || index == 0">
			{{getShowTimePipe(item.time) || ''}}
		  </view>
  <!-- 个人开始 -->
	      <view>
		<view class="content-from msg" v-if="item.flow == 'in'">
		<image class="msg-image left-head" :src="item.avatar" />
  <!-- 每条消息内容 -- left -->
		<view class="content-my-left-box">
  <!-- 展示文本 -->
		<view class="content-my-left-text" v-if="item.type == 'TIMTextElem'">
		   <rich-text :nodes="nodesFliter(item.payload.text)"></rich-text>
		</view>
  <!-- 展示图片 -->
	<image class="content-my-left-img" :style="`height:${item.payload.imageInfoArray[1].height}px; width: ${item.payload.imageInfoArray[1].width}px;`" :src="item.payload.imageInfoArray[1].imageUrl" mode="widthFix" v-else-if="item.type == 'TIMImageElem'" @click="onPreviewImg(item.payload.imageInfoArray[1].imageUrl)"></image>
  <!-- 展示视频 -->
	<MyVideo class="content-my-video" v-else-if="item.type == 'TIMVideoFileElem'" :videoUrl="item.payload.remoteVideoUrl" />
	</view>
<!-- 每条消息内容 -- left -->
	</view>
	<view class="content-my msg" v-else-if="item.flow == 'out'">
<!-- 每条消息内容 -- right -->
	<view class="content-my-right-box">
<!-- 展示文本 -->
	<view class="content-my-right-text" v-if="item.type == 'TIMTextElem'">
		rich-text :nodes="nodesFliter(item.payload.text)"></rich-text>
	</view>
<!-- 展示图片 -->
<image class="content-my-right-img"	:style="`height: ${item.payload.imageInfoArray[1].height*2}rpx; width: ${item.payload.imageInfoArray[1].width*2}rpx;`":src="item.payload.imageInfoArray[1].imageUrl" mode="widthFix" v-else-if="item.type == 'TIMImageElem'" @click="onPreviewImg(item.payload.imageInfoArray[1].imageUrl)"></image>
<!-- 展示视频 -->
<MyVideo class="content-my-video" v-else-if="item.type == 'TIMVideoFileElem'" :videoUrl="item.payload.remoteVideoUrl" />
</view>
<!-- 每条消息内容 -- right -->
	      <image class="msg-image right-head" :src="item.avatar " />
        </view>
      </view>
<!-- 个人结束 -->
					</view>
				</view>
			</mescroll-uni>
		</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
3.2 底部输入框
3.2 底部输入框

<view class="bottom fixed" @click="getBottomHeight()" :style="{bottom: changeBottomVal}">
	<view class="flex-center-between">
		<image @click="imgBtn" src="/static/images/home/1086.png" mode=""></image>
		// @keyboardheightchange 监听键盘高度
			<input :adjust-position="false" @keyboardheightchange="keyboardheightchange" class="save-inp" v-model="msgText" :focus="focus" type="text" @confirm="sendBtn">
		<view class="send" @click="sendBtn">发送</view>
	 </view>
	</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.1.2 js代码

3.1.2 js代码

	data() {
			return {
				top: uni.getStorageSync('safeArea').top,
				name: '',
				bottomImg: false,
				username: '',
				changeBottomVal: '',//键盘高度
				bottomHeight: '', //底部高度
				msgList: [], // 会话消息列表		
				msgText: '', // 文字消息
				message: {}, // 发送消息对象
				timUserInfo: {}, // 会话对象用户信息
				msgUserData: {}, // 会话对象信息
				focus: false,
				downOption: {
					auto: false,
					textInOffset: '拉取历史记录',
					textOutOffset: '',
					textLoading: '拉取中...'
				},
			};
		},
		onShow() {
			this.getTimeSlot()
			// 获取会话数据
			this.getListMsg()

		},
		onLoad(e) {

			this.tim.on(this.$TIM.EVENT.MESSAGE_RECEIVED, (event) => {

				if (event.data[0].type == "TIMSoundElem") {
					this.getListMsg()
					this.getTimeSlot()
				} else {
					let arr = event.data.filter((res) => res.conversationID == (this.isGroup ? `GROUP${this.msgData.groupID}` :
						`C2C${this.msgUserData.userID}`))
					this.msgList.push(...arr)
					this.getTimeSlot()
					// 获取底部高度
					this.getBottomHeight(false)
				}
			})

			this.name = e.name;
			this.username = e.username;
			this.msgUserData = e

			// 已读会话
			this.inRead()
			// 获取底部高度
			this.getBottomHeight(false)
		},
		methods: {
		//键盘高度
			keyboardheightchange(e) {
				this.changeBottomVal = e.detail.height + 'px'
			},
			getBottomHeight() {
				this.$nextTick(() => {
					const query = uni.createSelectorQuery().in(this);
					query.select('.bottom').boundingClientRect(data => {
						this.bottomHeight = data.height

						console.log(data.height, 'data.height');
					}).exec();
					this.$nextTick(() => {
						uni.pageScrollTo({
							scrollTop: 9999,
							duration: 100
						})
					})
				})
			},

			// 预览图片
			onPreviewImg(image) {
				uni.previewImage({
					urls: [image],
					fail: function(err) {}
				})
			},
			imgBtn() {
				this.bottomImg = !this.bottomImg
			},
			// 发送拍摄或者上传视频
			sendMsgVideo() {
				uni.chooseVideo({
					success: (res) => {
						this.message = this.tim.createVideoMessage({
							to: this.msgUserData.userID,
							conversationType: 'C2C',
							payload: {
								file: res
							},
							onProgress: (event) => {}
						});
						this.tim.sendMessage(this.message).then((res) => {
							this.msgList.push(res.data.message)
							// 获取底部高度
							this.getBottomHeight(false)
						})
					}
				})
			},
			// 发送拍摄或者上传图片
			sendMsgImage() {
				uni.chooseImage({
					count: 1,
					mediaType: ['image'], // 图片
					sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
					success: (res) => {
						this.message = this.tim.createImageMessage({
							to: this.msgUserData.userID,
							conversationType: 'C2C',
							payload: {
								file: res
							},
							onProgress: function(event) {}
						});
						this.tim.sendMessage(this.message).then((res) => {
							this.msgList.push(res.data.message)
							// 获取底部高度
							this.getBottomHeight(false)
						})
					}
				});
			},
			// 判断是否有十分钟的时间间隔
			getTimeSlot() {
				setTimeout(() => {
					this.msgList.forEach((res, index) => {
						let i = this.msgList.length - (index + 2) <= 0 ? 0 : this.msgList.length - (index + 2)
						let j = this.msgList.length - (index + 1) <= 0 ? 0 : this.msgList.length - (index + 1)
						let time1 = this.$time.getNowDate(this.msgList[i].time * 1000)
						let time2 = this.$time.getNowDate(this.msgList[j].time * 1000)
						if (this.$time.GetDateDiff(time2, time1, 'minute') <= -5) {
							this.$set(this.msgList[j], 'isShowTime', true)
						}
					})
				}, 300)
			},
			// 获取会话列表
			getListMsg(isDown = false) {
				// 用于拉取历史聊天数据
				let parmas = {
					conversationID: `C2C${this.msgUserData.userID}`,
					nextReqMessageID: this.nextReqMessageID
				}
				// 用于拉取目前聊天数据
				let data = {
					conversationID: `C2C${this.msgUserData.userID}`,
				}
				this.tim.getMessageList(isDown ? parmas : data).then((res) => {

					this.nextReqMessageID = res.data.nextReqMessageID
					console.log(res, '11122111221');
					if (!this.nextReqMessageID.length || this.nextReqMessageID == '-1') this.mescroll.lockDownScroll(true)
					if (isDown) {
						this.msgList = res.data.messageList.concat(this.msgList)
						this.mescroll.endDownScroll()
					} else {
						this.msgList = res.data.messageList
					}

				});
				this.timeOut = setTimeout(() => {
					uni.hideLoading()
					if (!isDown) {
						uni.pageScrollTo({
							scrollTop: 9999,
							duration: 100
						})
					}
					this.$forceUpdate()
				}, 800)
			},
			inRead() {
				// 将某会话下所有未读消息已读上报
				this.tim.setMessageRead({
					conversationID: `C2C${this.msgUserData.userID}`
				})
			},
			//聊天的节点加上外层的div
			nodesFliter(str) {
				let nodeStr = '<div style="display: flex; align-items: center;word-wrap:break-word; width: auto;">' + str +
					'</div>'
				return nodeStr
			},
			getShowTimePipe(time) {
				return this.$time.showTimePipe(time * 1000)
			},
			// 发送文本
			sendMsgText() {
				this.msgText = this.msgText.trim()
				console.log(this.msgText, '111111');
				if (this.msgText.length == '') {
					uni.showToast({
						title: "发送消息不能为空",
						icon: "none"
					})
					return
				}
				// 1. 创建消息实例,接口返回的实例可以上屏
				this.message = this.tim.createTextMessage({
					to: this.msgUserData.userID,
					conversationType: 'C2C',
					payload: {
						text: this.msgText
					},
				});
				this.tim.sendMessage(this.message).then((res) => {
					this.msgList.push(res.data.message)
					this.focus = true
					this.msgText = ""
					// 获取底部高度
					this.getBottomHeight(false)
				})
			},
			sendBtn() {
				this.sendMsgText()
			}
		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
4.1 消息列表
4.1.1 html
<view>
	<view v-for="(item, index) in list" :key="index" @click="goToMessage(item.userProfile.nick,item.userProfile.userID,index)">
				<view class="pop flex-center-between">
					<view class="name flex">
						<image :src="item.userProfile.avatar" mode=""></image>
						<view class="tian">
							<view>{{item.userProfile.nick}}</view>
							<span>
								<rich-text :nodes="nodesFliter(item.lastMessage.messageForShow)"></rich-text>
							</span>
						</view>
					</view>
					//未读消息
				<view class="red" v-if="item.unreadCount">{{item.unreadCount}}</view>
			</view>
		<view class="line"></view>
	</view>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
4.2.2 js
export default {
		data() {
			return {
				top: uni.getStorageSync('safeArea').top,
				list: [],
				isTips: true
			};

		},
		onLoad() {
			this.getList()
		},
		onShow() {
			this.getList()
		},
		methods: {
			//聊天的节点加上外层的div
			nodesFliter(str) {
				let nodeStr = '<div style="align-items: center;word-wrap:break-word;">' + str + '</div>'
				return nodeStr
			},
			goToMessage(name, userID, index) {
				this.$helper.toPage('/pages/active/chat?name=' + name + '&userID=' + userID );
				// this.list[index].unreadCount = 0
			},
			getList() {
				// 获取全量的会话列表
				this.tim.getConversationList().then((res) => {

					this.list = res.data.conversationList
					// console.log(this.list, '1111');
					console.log(this.list, '1111');
					this.list = this.list.filter((res) => res.type != "@TIM#SYSTEM")

					this.getFriend()
				})
			},
			getFriend() {
				this.tim.getFriendApplicationList().then(res => {
					this.friendNum = res.data.unreadCount
				})
			},
		}
	};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/545931
推荐阅读