背景
随着企业的发展,企业事务管理系统如OA、CRM、PM、KM等将会越来越多。企业员工每天需要花大量的时间去各个系统查看与操作相关事务。尽管如此,各项信息还是无法第一时间得到处理,各项工作的执行效率大打折扣。因此,睿信IM产品应运而生,它可以:
1、为企业提供私有的IM系统,防止商业信息泄露
2、整合企业办公生态,汇总多端消息通知,防止消息漏接漏审。
3、便捷企业办公,在IM中可完成多个办公系统的操作。简化办公流程操作。
而通讯作为睿信IM最基本的功能,怎么少得了表情、图片、文件之间的通讯呢?那么问题来了,它是如何实现IM表情、图片、文件之间的通讯呢?
睿信IM表情是如何实现的呢:
在使用IM产品时,我们接收到的表情不会是一张图片,而是类似:face[微笑] 、[微笑]、/微笑这样的字符串,那么如何将字符串转换为对应的表情就是问题的关键。毋庸置疑,通过对相应的字符串作匹配替换,从而将对应的表情显示出来是比较好的一个方法。
首先,本地要有一个表情图片库,类似 睿信IM表情库:
本地表情文件的不同,对应的处理方法也会不一样。 有了这样的一个表情库文件,接下来就是对相应的表情字符串进行匹配。
其次:针对不同的表情字符串,需要写不同的匹配规则。如需匹配[微笑]或者/微笑格式的表情,对应的规则如下:
A.循环遍历,用字符串赋予一个图片路径,最后用来发送的表情实际上是 face+下面的字符串标识,如 face[微笑]:
private insertFace(item: any) { this.sendMessageValue = this.sendMessageValue + "face" + item; this.showFace = false; } export let faceUtils = { alt: [ "[微笑]", "[得意]", "[泪]", "[哈哈]", "[色]", "[伤心]", "[害羞]", "[疑问]", "[闭嘴]", "[怒]", "[偷笑]", "[困]", "[汗]", "[吐血]", "[拜拜]", "[笑哭]", "[晕]", "[嘘]", "[衰]", "[敲打]", "[可怜]", "[赞]", "[差]", "[握手]", "[耶]", "[抱拳]", "[OK]", "[抱抱]", "[玫瑰]", "[晚安]" ], faces: function () { let self = this; let arr: any = {}; for (let i = 0; i < self.alt.length; i++) { arr[self.alt[i]] = "./static/newFace/" + i + ".png"; } return arr; } };
B.上一步的每一个字符串(如face[微笑])都有一个与之对应的图片路径(如 ”./static/newFace/0.png”),接下来把每个图片路径放到img表情里,实现表情的渲染(如下图):
<ul class="faces"> <li v-for="(item, index) in faceList" :key="index"> <img :src="faceMap[item]" :alt="item" :title="item" @click="insertFace(item)"/> </li> </ul>
data() { return { faceList: faceUtils.alt, faceMap: faceUtils.faces() }; }, methods: { insertFace: function(item) { this.$emit("insertFace", item); } }
C.当接收方收到表情字符串(如face[微笑])时,对应的要进行转译,以字符串标识face[]进行替换为对应的img标签(即表情):
let fa = faceUtils.faces(); content = content .replace(/face\[([^\s\\[\]]+?)]/g, function (face: any) { // 转义表情 let alt = face.replace(/^face/g, ""); return ('<img class="faceImg" width="28" alt="face' + alt + '" src="' + fa[alt] + '">'); })
睿信IM图片及文件是如何实现的呢:
图片及文件发送,通过input标签选择图片或文件
<input type="file" class="fileInput" ref="fileInput" title="发送图片" @change="imageChange" placeholder="上传文件" accept="image/*" /> <input type="file" class="fileUpload" ref="fileUpload" title="发送文件" @change="fileChange" placeholder="上传文件" accept />
接着调用文件发送接口,通过表单的数据格式向后台发送数据,回调函数接收图片或文件路径,
let formData = new FormData(); formData.append("channel_id", this.chatObj.channel_id); formData.append("user_id", Common.getIMUserIDFromCookie()); formData.append("file", this.fileObj); apiIMServices.filePost(formData, (progress) => { this.uploadProgress = progress; }).then((res: any) => { Popup.closeAll(); console.log(res); this.$store.commit('setFilePath',{ id: res.metadata.files[0].id, filePath: this.fileObj.path, exist: true }); this.ifImg = false; }).catch(error => { Popup.closeAll(); console.log(error); Popup.errorMsg(error.errorMsg); });
对方接收到对应的图片或文件,会有如下websocket推送
接收方通过字段image和otherFile判断它是图片还是文件,然后把一整个文件信息数组(上图metadata里的files)传递给文件组件处理:
组件接收到文件files信息,通过id去获取文件链接路径,然后把链接FileLinkUrl传递到img标签,即可完成图片的渲染显示:
private async getFileLink() { this.FileLinkUrl = await apiIMServices.getFileLink(this.file.id); let that: any = this; that.filelinkUrls[this.file.id] = this.FileLinkUrl; this.$store.commit('setFilelinkUrls',that.filelinkUrls); }
<img class="image-item" :src="FileLinkUrl ? FileLinkUrl.link: ''" alt />
同理:把链接FileLinkUrl传递到a标签,即可完成文件的下载:
<a class="file-download" v-if="FileLinkUrl" :href="FileLinkUrl ? FileLinkUrl.link : 'javascript:;'" >下载</a>
总结
总体来说将字符串转换为对应的图片是表情实现的关键,而图片和文件的通讯则依赖于后台接口提供的文件链接,将文件链接嵌入对应的标签从而转变为对应的图片或文件,再通过点击文件的标签链接从而实现文件下载功能。以上是IM表情、图片、文件通讯实现基本思路,希望能给大家带来收获。