|
@@ -0,0 +1,370 @@
|
|
|
+<template>
|
|
|
+ <div class="chat-box-data">
|
|
|
+ <div class="chat-loading" v-show="loading">
|
|
|
+ 会话获取中...
|
|
|
+ </div>
|
|
|
+ <div ref="chatList" class="chat-information">
|
|
|
+ <div v-for="(item,index) in dataList" :key="index">
|
|
|
+ <div class="chat-item" :class="item.from == `workark${$store.getters.user.userId}` ? 'push':'pull' ">
|
|
|
+ <img :src="item.fromUserInfo.avatarUrl" mode="aspectFill" class="avatar"></img>
|
|
|
+ <div class="content-box">
|
|
|
+ <div class="content" v-if="item.type === 'text'">{{item.body.text}}</div>
|
|
|
+ <el-image :src="item.body.thumbnailUrl" :preview-src-list="[item.body.originalUrl]" fit="fill"
|
|
|
+ :class="returnImageClass(item.body)" v-else>
|
|
|
+ </el-image>
|
|
|
+ </div>
|
|
|
+ <span class="date">
|
|
|
+ {{$dayjs(item.time).format('YYYY-MM-DD HH:mm:ss')}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="chat-send">
|
|
|
+ <div class="file-list">
|
|
|
+ <input type="file" ref="fileadd" style="opacity: 0;width: 0;height: 0;" @change="changeImage"
|
|
|
+ accept="image/*" />
|
|
|
+ <i class="el-icon-picture" @click="uploadImage"></i>
|
|
|
+ </div>
|
|
|
+ <el-input type="textarea" :rows="5" resize="none" placeholder="请输入内容" :maxlength="200"
|
|
|
+ v-model="sendMessage">
|
|
|
+ </el-input>
|
|
|
+ <div class="chat-send-btn">
|
|
|
+ <el-button type="primary" size="medium" @click="send" :loading="sendLoading" :disabled="!sendMessage">
|
|
|
+ 发送
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ YeIMUniSDK, // SDK
|
|
|
+ YeIMUniSDKDefines // 预定义常量
|
|
|
+ } from 'yeim-uni-sdk'
|
|
|
+ import {
|
|
|
+ uploadImage
|
|
|
+ } from '@/api/chat.js'
|
|
|
+ import md5 from 'js-md5'
|
|
|
+ import config from "@/config";
|
|
|
+ export default {
|
|
|
+ props: ['body'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ dataList: [],
|
|
|
+ nextMessageId: null,
|
|
|
+ hasTopData: true,
|
|
|
+ loading: false,
|
|
|
+ sendMessage: '',
|
|
|
+ sendLoading: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ YeIMUniSDK.getInstance().removeEventListener(YeIMUniSDKDefines.EVENT.MESSAGE_RECEIVED, this.onMessage);
|
|
|
+ document.removeEventListener('keydown', this.kedown);
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ // 设置onscroll事件处理函数
|
|
|
+ if (!this.$refs.chatList) return;
|
|
|
+ this.$refs.chatList.onscroll = this.chatScroll;
|
|
|
+ this.$chat.clearConversationUnread(this.body.conversationId);
|
|
|
+ document.addEventListener('keydown', this.kedown);
|
|
|
+ this.mescrollUpFunc('init');
|
|
|
+ YeIMUniSDK.getInstance().addEventListener(YeIMUniSDKDefines.EVENT.MESSAGE_RECEIVED, this
|
|
|
+ .onMessage);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ kedown(event) {
|
|
|
+ if (event.keyCode === 13) {
|
|
|
+ // 执行回车键按下后的操作
|
|
|
+ this.send();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ chatScroll() {
|
|
|
+ if (!this.hasTopData) return;
|
|
|
+ if (!this.$refs.chatList) return;
|
|
|
+ let scrollHeight = this.$refs.chatList.scrollTop;
|
|
|
+ if (scrollHeight === 0) this.mescrollUpFunc();
|
|
|
+ },
|
|
|
+ returnImageClass(item) {
|
|
|
+ let w = item.thumbnailWidth,
|
|
|
+ h = item.thumbnailHeight;
|
|
|
+ let str = ''
|
|
|
+ if (w > h) str = 'image-width';
|
|
|
+ if (w == h) str = 'image-width-height';
|
|
|
+ if (w < h) str = 'image-height';
|
|
|
+ return str + ' image-box';
|
|
|
+ },
|
|
|
+ mescrollUpFunc(type) {
|
|
|
+ this.loading = true;
|
|
|
+ this.joinHistoryMsg().then(data => {
|
|
|
+ this.loading = false;
|
|
|
+ if (!this.nextMessageId) this.dataList = [];
|
|
|
+ if (data.length === 0) this.hasTopData = false;
|
|
|
+ this.dataList = data.concat(this.dataList);
|
|
|
+ if (type === 'init') {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.chatList.scrollTo(0, 99999);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ joinHistoryMsg() {
|
|
|
+ return new Promise((done, fail) => {
|
|
|
+ this.$chat.getHistoryMessageList(this.nextMessageId, this.body.conversationId, res => {
|
|
|
+ this.nextMessageId = res.data.nextMessageId || 'null';
|
|
|
+ done(!res.data ? [] : res.data.list);
|
|
|
+ }, () => {
|
|
|
+ done([]);
|
|
|
+ });
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onMessage(e) {
|
|
|
+ let message = e;
|
|
|
+ if (this.body.conversationId != message.conversationId) return;
|
|
|
+ this.dataList.push(message);
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.chatList.scrollTo(0, 99999);
|
|
|
+ })
|
|
|
+ this.$chat.clearConversationUnread(this.body.conversationId);
|
|
|
+ },
|
|
|
+ changeImage(e) {
|
|
|
+ let currentfile = this.$refs.fileadd.files[0];
|
|
|
+ let _self = this;
|
|
|
+ if (currentfile) {
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = function(e) {
|
|
|
+ const img = new Image();
|
|
|
+ img.onload = () => {
|
|
|
+ let filename = currentfile.name;
|
|
|
+ let suffix = filename.substring(filename.lastIndexOf('.'));
|
|
|
+ let name = md5((new Date()).getTime() + '_' + filename) + '_image' + suffix;
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', currentfile);
|
|
|
+ formData.append('key', _self.getUploadFilePath(name, 'image'));
|
|
|
+ _self.$loading();
|
|
|
+ uploadImage(formData).then(res => {
|
|
|
+ if (res.state) {
|
|
|
+ _self.sendImage(res.data, img);
|
|
|
+ } else {
|
|
|
+ _self.$loading.close();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ };
|
|
|
+ img.src = e.target.result; // 设置图片源为读取的结果
|
|
|
+ };
|
|
|
+ reader.readAsDataURL(currentfile); // 读取文件内容为DataURL
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getUploadFilePath(filename, dir = 'files') {
|
|
|
+ let date = new Date();
|
|
|
+ let dateDir = date.getFullYear() + '-' + JSON.stringify(date.getMonth() + 1).padStart(2, 0) + '-' + JSON
|
|
|
+ .stringify(date.getDate()).padStart(2, 0);
|
|
|
+ return dir + '/' + dateDir + '/' + filename;
|
|
|
+ },
|
|
|
+ uploadImage() {
|
|
|
+ this.$refs.fileadd.click();
|
|
|
+ },
|
|
|
+ sendImage(data, img) {
|
|
|
+ //创建图片消息
|
|
|
+ let message = YeIMUniSDK.getInstance().createImageMessageFromUrl({
|
|
|
+ toId: this.body.conversationId, //接收者用户ID字符串
|
|
|
+ conversationType: YeIMUniSDKDefines.CONVERSATION_TYPE.PRIVATE, //会话类型:私聊
|
|
|
+ body: {
|
|
|
+ originalUrl: 'https://www.waywish.com/im' + data.url, //原图网络Url
|
|
|
+ originalWidth: img.width, //原图宽度
|
|
|
+ originalHeight: img.height, //原图高度
|
|
|
+ thumbnailUrl: 'https://www.waywish.com/im' + data.thumbnailUrl, //缩略图网络Url
|
|
|
+ thumbnailWidth: data.thumbnailWidth, //缩略图宽度
|
|
|
+ thumbnailHeight: data.thumbnailHeight, //缩略图高度
|
|
|
+ },
|
|
|
+ extra: ""
|
|
|
+ });
|
|
|
+ YeIMUniSDK.getInstance().sendMessage({
|
|
|
+ message: message,
|
|
|
+ success: this.sendSuccess,
|
|
|
+ fail: (err) => {
|
|
|
+ this.$loading.close();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ // 发送信息
|
|
|
+ send() {
|
|
|
+ if (!this.sendMessage) return this.$message.warning('内容不能为空');
|
|
|
+ this.sendLoading = true;
|
|
|
+ this.$chat.sendText(this.body.conversationId, this.sendMessage, this.sendSuccess, (e) => {
|
|
|
+ this.$message.error('发送失败');
|
|
|
+ this.sendLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ sendSuccess(res) {
|
|
|
+ this.$loading.close();
|
|
|
+ this.dataList.push(res.data);
|
|
|
+ this.sendMessage = '';
|
|
|
+ this.sendLoading = false;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.chatList.scrollTo(0, 99999);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ .chat-box-data {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .file-list {
|
|
|
+ padding: 10px 10px 0 10px;
|
|
|
+
|
|
|
+ .el-icon-picture {
|
|
|
+ font-size: 22px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .chat-item {
|
|
|
+ display: flex;
|
|
|
+ padding: 10px 10px 20px 10px;
|
|
|
+ align-items: flex-start;
|
|
|
+ align-content: flex-start;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .avatar {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: #fff solid 1px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #8e8e8e;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content-box {
|
|
|
+ flex: 1;
|
|
|
+ width: 0;
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-box {
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-width {
|
|
|
+ width: 140px;
|
|
|
+ height: 100px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-height {
|
|
|
+ width: 100px;
|
|
|
+ height: 140px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-width-height {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ padding: 10px 15px;
|
|
|
+ border-radius: 8px;
|
|
|
+ word-break: break-all;
|
|
|
+ line-height: 21px;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 收到的消息 */
|
|
|
+ &.pull {
|
|
|
+ .content-box {
|
|
|
+ margin-right: 50px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-box {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ margin-left: 10px;
|
|
|
+ background-color: $--background-color-base;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ left: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 发出的消息 */
|
|
|
+ &.push {
|
|
|
+ /* 主轴为水平方向,起点在右端。使不修改DOM结构,也能改变元素排列顺序 */
|
|
|
+ flex-direction: row-reverse;
|
|
|
+
|
|
|
+ .content-box {
|
|
|
+ flex-direction: row-reverse;
|
|
|
+ margin-left: 50px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-box {
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ margin-right: 10px;
|
|
|
+ background-color: $--color-primary;
|
|
|
+ color: #fff;
|
|
|
+ box-shadow: 0px 1px 12px rgba(3, 3, 3, 0.08);
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ right: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .chat-information {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ overflow-y: auto;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chat-loading {
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ position: absolute;
|
|
|
+ background: $--color-primary;
|
|
|
+ height: 30px;
|
|
|
+ color: #fff;
|
|
|
+ line-height: 30px;
|
|
|
+ font-size: 12px;
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chat-send {
|
|
|
+ border-top: 1px solid $--border-color-lighter;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .el-textarea__inner {
|
|
|
+ border: none;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .chat-send-btn {
|
|
|
+ padding: 10px;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|