**实现功能:**文字、图片、语音聊天、聊天记录本地存储(只存储发送端,接收端未存储,思想一致)
在这里插入图片描述

项目聊天页面为vue开发,所以直接选用Web sdk,选用的sdk版本为:NIM_Web_SDK_weixin_v7.2.0.js

网易云信提供的web sdk 为js文件,使用时直接放在某个目录文件夹下即可.

sdk 文件位置

初始化登录IM

这里我们项目需求是需要在用户打开App时,就默认登录到网易云信IM。所以我直接将登录注册IM方法放在Vuex actions 内,当App打开获取到用户的本地个人信息之后,直接登录到IM。


```javascript

```javascript
actions: {
		nimInit: function ({state}) {
			if(state.userInfo == null){
				console.warn('当前不存在用户信息,无法登陆网易Im')
			}else{
				let userInfo = state.userInfo
				let nim = SDK.NIM.getInstance({
				  debug: true,   // 是否开启日志,将其打印到console。集成开发阶段建议打开。
				  appKey: '7c4a2xxxxxx',// 自行网易云信获取
				  account: userInfo.userId,
				  token: state.userSig, //token是在网易云信获取
				  db:true, //若不要开启数据库请设置false。SDK默认为true。
				  // privateConf: {}, // 私有化部署方案所需的配置
				  onconnect: onconnect, // 连接成功回调
				  onwillreconnect: onWillReconnect, // 重连回调
				  ondisconnect: onDisconnect, // 掉线回调
				  onerror: onError // 错误回调
				});
                                // 直接挂载到Vue原型链上
				Vue.prototype.nim = nim
			}
		},

如果配置成功,初始化登录IM成功如图:

文本消息发送:

this.nim.sendText({
  scene: 'p2p',
  to: this.toUserId, //收信息人的id
  text: this.textInput,
  done: () => {
   console.log('发送成功!')
   let msg = {
	avatar: this.$store.state.userInfo.avatar,
	text: this.textInput,
	image: null,
	radio: null,
        msgType: 'text',
	userType: 0,											 
        fromId: Number(this.userId),
        userId: Number(this.toUserId),
	date: new Date()
    }
    this.messageList.push(msg)
    this.postChatRecord(msg)
    this.$nextTick(() => {
         this.textInput = ''; //清空输入框
	 uni.hideKeyboard()
	 this.textareaStyle = 'bottom: 0px;';
    })
  }
})
			

done为成功的回调,在这个可以写发送成功之后,EXP: 将聊天消息,放入本地的聊天记录sqlite数据库

图片消息发送

图片发送:拍照、从本地相册获取两种类型

调用的是Uni-app的 uni.chooseImage方法,回调内返回的是图片的本地地址,所以在网易云信的图片发送时,选择参数filePath,值为图片的地址url,不是一个数组,不要将整个返回的图片数组传递给filePath

getImage(type) {
   this.drawerShow = false
   uni.chooseImage({
	sourceType:[type], // type 为camera 调用摄像头 album调用本地相册
	sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
	success: (res) => {	
              // res.tempFilePaths为本地图片地址array
              this.sendImage(res.tempFilePaths, 'image')
	}
    });
},
sendImage(urls, type) {
// urls为本地图片的Array
				let _this = this
				for (let i = 0; i < urls.length; i++) {
					this.nim.sendFile({
						scene: 'p2p',
						to: _this.toUserId,
						type: 'image',
						filePath: urls[i],
						fastPass: '{"w":200,"h":110,"md5":"898D9SADHSAUDHAS8989"}',
						beginupload: function(upload) {
							// - 如果开发者传入 fileInput, 在此回调之前不能修改 fileInput
							// - 在此回调之后可以取消图片上传, 此回调会接收一个参数 `upload`, 调用 `upload.abort();` 来取消文件上传
						},
						uploadprogress: function(obj) {
							// console.log('文件总大小: ' + obj.total + 'bytes');
							// console.log('已经上传的大小: ' + obj.loaded + 'bytes');
							// console.log('上传进度: ' + obj.percentage);
							// console.log('上传进度文本: ' + obj.percentageText);
						},
						uploaddone: function(error, file) {
							console.log(error);
							console.log(file);
							if (!error) {
								console.log('上传成功', file.url)
								let msg = {
									avatar: _this.$store.state.userInfo.avatar,
									text: null,
									image: file.url,
									radio: null,
									msgType: 'image',
									userType: 0,
									fromId: Number(_this.userId),
									userId: Number(_this.toUserId),
									date: new Date()
								}
								console.log('图片上传',msg)
								_this.messageList.push(msg)
								_this.postChatRecord(msg)
								console.log('图片上传完毕ok', _this.messageList.length)
								// _this.$nextTick(() => {
								// 	uni.hideKeyboard()
								// 	_this.textareaStyle = 'bottom: 0px;';
								// })
							} else {
								console.warn(error)
							}
						},
						beforesend: function(msg) {
							console.log('正在发送p2p image消息, id=' + msg.idClient);
						},
						done: function(res) {
							console.log(res, '上传图片结果')
						}
					});
}

本地sqlite数据库方法:

/* 数据操作
	creted by hjl 2020/9/24
 */
// 打开本地的localStorage.db数据库
function openComDB() {  
    return new Promise((resolve, reject) => {
		plus.sqlite.openDatabase({
			name: 'localStorage',
			path: '_doc/localStorage.db',
			success: function(e) {
				console.log('打开数据库localStorage.db成功 ');
				resolve(e);
			},
			fail: function(e) {
				console.log('打开数据库localStorage.db失败: ' + JSON.stringify(e));
				reject(e);
			}
		});
	})
}  
// 新增表
function executeSQL(name, sql) {  
    return new Promise( (resolve, reject) => {
		plus.sqlite.selectSql({
		    name: name,  
		    sql: sql,  
		    success: function(e) {  
		        console.log("查询数据库:" + name + ",表:" + sql + ";的");  
		        resolve(e) 
		    },  
		    fail: function(e) {  
		        console.log("查询数据库失败:" + JSON.stringify(e));   
				reject(e)
		    }  
		})  
	}).then(res => {
		let msg = {
			code: 0,
			msg: '查询或新增数据库成功',
			data: res
		}
		return msg
	}).catch(error => {
		let msg = {
			code: 200,
			msg: '查询或新增数据库失败',
			data: error
		}
		return msg
	})
}  
// 新增数据
function newAddData (name,sql) {
	return new Promise( (resolve,reject) => {
		plus.sqlite.executeSql({
			name: name,
			sql: sql,
			success(e){
				console.log('成功',e)
				resolve(e)
			},
			fail(e) {
				console.log('错误',e)
				reject(e)
			}
		})
	}).then( res => {
		let msg = {
			code: 0,
			msg: '数据写入数据库成功',
			data: res
		}
		return msg
	}).catch(error => {
		let msg = {
			code: 200,
			msg: '数据写入数据库失败',
			data: error
		}
		return error
	})
}
// 数据库查询
function querySql (name,sql) {
	return new Promise( (resolve,reject) => {
		plus.sqlite.selectSql({
			name: name,
			sql: sql,
			success(e){
				resolve(e)
			},
			fail(e) {
				reject(e)
			}
		})
	}).then( res => {
		let msg = {
			code: 0,
			msg: '数据库查询成功',
			data: res
		}
		return msg
	}).catch(error => {
		let msg = {
			code: 200,
			msg: '数据库查询失败',
			data: error
		}
		return msg
	})
}

// 清空表数据 聊天记录
function clearChatRecord (name,sql) {
	return new Promise( (resolve,reject) => {
		plus.sqlite.selectSql({
			name: 'localStorage',
			sql: 'delete from chatRecord',
			success(e){
				resolve(e)
			},
			fail(e) {
				reject(e)
			}
		})
	}).then( res => {
		let msg = {
			code: 0,
			msg: '聊天记录清空成功',
			data: res
		}
		return msg
	}).catch(error => {
		let msg = {
			code: 200,
			msg: '聊天记录清空失败',
			data: error
		}
		return msg
	})
}
export{  
openComDB,  
executeSQL,
querySql,
newAddData,
clearChatRecord
}

完整DEMO: 见Gitee

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐