|
@@ -1,13 +1,10 @@
|
1
|
1
|
<template>
|
2
|
2
|
<div class="contact-box" id="contact-box">
|
3
|
3
|
<div class="contact-box-item msg-box" >
|
4
|
|
- <div class="box-btn " @click="showMsgBox=true">
|
|
4
|
+ <div class="box-btn " @click="toggleMsgBox">
|
5
|
5
|
<i class="el-icon-service"></i>
|
6
|
6
|
<span>在线客服</span>
|
7
|
7
|
</div>
|
8
|
|
- <div class="contact-info-box" v-show="!showMsgBox">
|
9
|
|
- 点击打开在线客服
|
10
|
|
- </div>
|
11
|
8
|
<div class="contact-msg-box" v-show="showMsgBox">
|
12
|
9
|
<div class="msg-box-panel">
|
13
|
10
|
<div class="panel-header">
|
|
@@ -17,57 +14,669 @@
|
17
|
14
|
</div>
|
18
|
15
|
<div class="panel-body">
|
19
|
16
|
<ul class="msg-inner scroll-y">
|
20
|
|
- <li>1</li>
|
21
|
|
- <li>1</li>
|
22
|
|
- <li>1</li>
|
23
|
|
- <li>1</li>
|
24
|
|
- <li>1</li>
|
25
|
|
- <li>1</li>
|
26
|
|
- <li>1</li>
|
27
|
|
- <li>1</li>
|
28
|
|
- <li>1</li>
|
29
|
|
- <li>1</li>
|
30
|
|
- <li>1</li>
|
31
|
|
- <li>1</li>
|
32
|
|
- <li>1</li>
|
33
|
|
- <li>1</li>
|
34
|
|
- <li>1</li>
|
35
|
|
- <li>1</li>
|
36
|
|
- <li>1</li>
|
37
|
|
- <li>1</li>
|
38
|
|
- <li>1</li>
|
39
|
|
- <li>1</li>
|
40
|
|
- <li>1</li>
|
41
|
|
- <li>1</li>
|
42
|
|
- <li>1</li>
|
43
|
|
- <li>1</li>
|
44
|
|
- <li>1</li>
|
45
|
|
- <li>1</li>
|
|
17
|
+ <li v-for="(messageitem, key) in messageBox" :key="key" :id="'id_'+messageitem.id" class="cell clearfix" :class="messageitem.float=='right'?'cell_right':''">
|
|
18
|
+ <template v-if="messageitem.float=='right'">
|
|
19
|
+ <div class="msg_body fl">
|
|
20
|
+ <div class="inner" v-html="messageitem.message"></div>
|
|
21
|
+ </div>
|
|
22
|
+ <div class="cell_pic fl">
|
|
23
|
+ <div class="pic">
|
|
24
|
+ <img :src="messageitem.avatar" alt="">
|
|
25
|
+ </div>
|
|
26
|
+ </div>
|
|
27
|
+ </template>
|
|
28
|
+ <template v-else>
|
|
29
|
+ <div class="cell_pic fl">
|
|
30
|
+ <div class="pic">
|
|
31
|
+ <img :src="messageitem.avatar" alt="">
|
|
32
|
+ </div>
|
|
33
|
+ </div>
|
|
34
|
+ <div class="msg_body fl">
|
|
35
|
+ <div class="inner" v-html="messageitem.message"></div>
|
|
36
|
+ </div>
|
|
37
|
+ </template>
|
|
38
|
+ </li>
|
46
|
39
|
</ul>
|
47
|
40
|
</div>
|
|
41
|
+ <div class="panel-tool">
|
|
42
|
+ <i class="icon-face" title="表情" @click="showEmotion"></i>
|
|
43
|
+ <el-upload
|
|
44
|
+ class="avatar-uploader"
|
|
45
|
+ action="https://jsonplaceholder.typicode.com/posts/"
|
|
46
|
+ :show-file-list="false"
|
|
47
|
+ :http-request='handleIMPicUload'
|
|
48
|
+ :on-success="handleIMPicSuccess"
|
|
49
|
+ :before-upload="beforeIMPicUpload">
|
|
50
|
+ <i class="el-icon-picture" title="图片"></i>
|
|
51
|
+ </el-upload>
|
|
52
|
+ <div class="face-box" v-show="showFace">
|
|
53
|
+ <div class="face-box-title">
|
|
54
|
+ <span>表情</span>
|
|
55
|
+ <i class="el-icon-close " @click="showFace=false" style="float:right" ></i>
|
|
56
|
+ </div>
|
|
57
|
+ <ul class="face-box-list clearfix">
|
|
58
|
+ <li v-for="(faceitem, index) in facelist" :key="index" @click="selectEmotion(faceitem)" >
|
|
59
|
+ <img :src="faceitem[1]" :id="faceitem[0]" alt="">
|
|
60
|
+ </li>
|
|
61
|
+ </ul>
|
|
62
|
+ </div>
|
|
63
|
+
|
|
64
|
+ </div>
|
|
65
|
+ <div class="panel-booter">
|
|
66
|
+ <div class="msg-input-box">
|
|
67
|
+ <textarea class="textarea scroll-y message-textarea" v-model="message" placeholder="请输入"></textarea>
|
|
68
|
+ </div>
|
|
69
|
+ <div class="msg-send-btn-box">
|
|
70
|
+ <span class="time fl">服务时间:工作时间:9:00-22:00 节假日:9:00-18:00</span>
|
|
71
|
+ <el-button type="primary" icon="el-icon-edit" class="fr" size="mini" @click="sendMessage">发送</el-button>
|
|
72
|
+ <!-- <button type="submit" id="sendadminkfmsg" class="send_btn fr">发送</button> -->
|
|
73
|
+ </div>
|
|
74
|
+ </div>
|
48
|
75
|
</div>
|
49
|
76
|
</div>
|
50
|
77
|
</div>
|
51
|
78
|
<div class="contact-box-item phone-box">
|
52
|
|
- <div class="box-btn">
|
|
79
|
+ <div class="box-btn" @click="togglePhoneBox">
|
53
|
80
|
<i class="el-icon-phone-outline"></i>
|
54
|
81
|
<span>客服电话</span>
|
55
|
82
|
</div>
|
56
|
|
- <div class="contact-phone-box">
|
57
|
|
- <i class="el-icon-phone-outline"></i>
|
|
83
|
+ <div class="contact-phone-box" v-show="showPhoneBox">
|
|
84
|
+ <i class="el-icon-phone-outline" ></i>
|
58
|
85
|
<span>0755-86526342</span>
|
59
|
86
|
</div>
|
60
|
87
|
</div>
|
61
|
88
|
</div>
|
62
|
89
|
</template>
|
63
|
90
|
<script>
|
|
91
|
+import {getusersig} from "@/api/kefu/tencentim";
|
|
92
|
+import webim from 'webim-tencent';
|
|
93
|
+let selType = webim.SESSION_TYPE.C2C;
|
|
94
|
+let reqMsgCount = 15; //每次请求的历史消息(c2c获取群)条数
|
|
95
|
+var msgList = [];
|
|
96
|
+var getPrePageC2CHistroyMsgInfoMap = {};
|
64
|
97
|
export default {
|
65
|
98
|
name:'contactBox',
|
66
|
99
|
data(){
|
67
|
100
|
return{
|
68
|
101
|
showMsgBox:false,
|
|
102
|
+ showPhoneBox:false,
|
|
103
|
+ selToID:'',
|
|
104
|
+ loginInfo: {
|
|
105
|
+ sdkAppID: '', //用户所属应用id,必填
|
|
106
|
+ appIDAt3rd: '',
|
|
107
|
+ identifier: '', //当前用户ID,必须是否字符串类型,必填
|
|
108
|
+ accountType: '', //用户所属应用帐号类型,必填
|
|
109
|
+ userSig: '', //当前用户身份凭证,必须是字符串类型,必填
|
|
110
|
+ identifierNick: '', //当前用户昵称,不用填写,登录接口会返回用户的昵称,如果没有设置,则返回用户的id
|
|
111
|
+ headurl: '', //当前用户默认头像,选填,如果设置过头像,则可以通过拉取个人资料接口来得到头像信息
|
|
112
|
+ },
|
|
113
|
+ useradmin:{
|
|
114
|
+ usersig: '',
|
|
115
|
+ Indentifier: '',
|
|
116
|
+ appIDAt3rd:'',
|
|
117
|
+ IdentifierNick:'',
|
|
118
|
+ HeadURL:'',
|
|
119
|
+ },
|
|
120
|
+ kefuUrl:'https://images.shengws.com/ico_gjh.png',
|
|
121
|
+ userSigFlag:false,
|
|
122
|
+ imloginFlag:false,
|
|
123
|
+ message:'',
|
|
124
|
+ messageBox:[],
|
|
125
|
+ facelist:[],
|
|
126
|
+ showFace:false,
|
69
|
127
|
}
|
70
|
|
- }
|
|
128
|
+ },
|
|
129
|
+ created(){
|
|
130
|
+
|
|
131
|
+ this.getusersig();
|
|
132
|
+ },
|
|
133
|
+ methods:{
|
|
134
|
+ getusersig() {
|
|
135
|
+ getusersig().then(response => {
|
|
136
|
+ if (response.data.state == 0) {
|
|
137
|
+ this.$message.error(response.data.msg);
|
|
138
|
+ return false;
|
|
139
|
+ } else {
|
|
140
|
+ this.useradmin = {
|
|
141
|
+ usersig: response.data.data.sig,
|
|
142
|
+ Indentifier: response.data.data.Indentifier,
|
|
143
|
+ appIDAt3rd:response.data.data.appIDAt3rd,
|
|
144
|
+ IdentifierNick:response.data.data.IdentifierNick,
|
|
145
|
+ HeadURL:response.data.data.HeadURL,
|
|
146
|
+ }
|
|
147
|
+
|
|
148
|
+ this.loginInfo.appIDAt3rd = this.useradmin.appIDAt3rd
|
|
149
|
+ this.loginInfo.identifier = this.useradmin.Indentifier
|
|
150
|
+ this.loginInfo.userSig = this.useradmin.usersig
|
|
151
|
+ this.loginInfo.identifierNick = this.useradmin.IdentifierNick
|
|
152
|
+ this.loginInfo.headurl = this.useradmin.HeadURL
|
|
153
|
+ this.loginInfo.sdkAppID = response.data.data.sdkAppID
|
|
154
|
+ this.loginInfo.accountType = response.data.data.accountType
|
|
155
|
+ this.selToID = response.data.data.selToAdmin;
|
|
156
|
+ this.userSigFlag = true;
|
|
157
|
+ }
|
|
158
|
+ });
|
|
159
|
+ },
|
|
160
|
+ showEmotion:function(){
|
|
161
|
+ this.facelist = [];
|
|
162
|
+ for (const index in webim.Emotions) {
|
|
163
|
+ this.facelist.push(webim.Emotions[index]);
|
|
164
|
+ }
|
|
165
|
+ this.showFace = true;
|
|
166
|
+ },
|
|
167
|
+ selectEmotion:function(face){
|
|
168
|
+ this.message += face[0];
|
|
169
|
+ this.showFace = false;
|
|
170
|
+ },
|
|
171
|
+ sendMessage:function(){
|
|
172
|
+ var message = this.message.trim();
|
|
173
|
+ var msgLen = webim.Tool.getStrBytes(message);
|
|
174
|
+ if(message == '') {
|
|
175
|
+ this.$message.error('不能发送空消息');
|
|
176
|
+ return false;
|
|
177
|
+ }
|
|
178
|
+ var maxLen, errInfo;
|
|
179
|
+ if (selType == webim.SESSION_TYPE.C2C) {
|
|
180
|
+ maxLen = webim.MSG_MAX_LENGTH.C2C;
|
|
181
|
+ errInfo = "消息长度超出限制(最多" + Math.round(maxLen / 3) + "汉字)";
|
|
182
|
+ } else {
|
|
183
|
+ maxLen = webim.MSG_MAX_LENGTH.GROUP;
|
|
184
|
+ errInfo = "消息长度超出限制(最多" + Math.round(maxLen / 3) + "汉字)";
|
|
185
|
+ }
|
|
186
|
+ if (msgLen > maxLen) {
|
|
187
|
+ this.$message.error(errInfo);
|
|
188
|
+ return false;
|
|
189
|
+ }
|
|
190
|
+ this.handleMsgSend(message);
|
|
191
|
+ },
|
|
192
|
+ handleMsgSend(msgContent) {
|
|
193
|
+ var selSess = new webim.Session(selType, this.selToID, this.selToID, this.kefuUrl, Math.round(new Date().getTime() / 1000));
|
|
194
|
+ var isSend = true; //是否为自己发送
|
|
195
|
+ var seq = -1; //消息序列,-1表示sdk自动生成,用于去重
|
|
196
|
+ var random = Math.round(Math.random() * 4294967296); //消息随机数,用于去重
|
|
197
|
+ var msgTime = Math.round(new Date().getTime() / 1000); //消息时间戳
|
|
198
|
+ var subType; //消息子类型
|
|
199
|
+ if (selType == webim.SESSION_TYPE.C2C) {
|
|
200
|
+ subType = webim.C2C_MSG_SUB_TYPE.COMMON;
|
|
201
|
+ } else {
|
|
202
|
+ subType = webim.GROUP_MSG_SUB_TYPE.COMMON;
|
|
203
|
+ }
|
|
204
|
+ var msg = new webim.Msg(selSess, isSend, seq, random, msgTime, this.loginInfo.identifier, subType, this.loginInfo.identifierNick);
|
|
205
|
+
|
|
206
|
+ var text_obj, face_obj, tmsg, emotionIndex, emotion, restMsgIndex;
|
|
207
|
+ //解析文本和表情
|
|
208
|
+ var expr = /\[[^[\]]{1,3}\]/mg;
|
|
209
|
+ var emotions = msgContent.match(expr);
|
|
210
|
+ if (!emotions || emotions.length < 1) {
|
|
211
|
+ text_obj = new webim.Msg.Elem.Text(msgContent);
|
|
212
|
+ msg.addText(text_obj);
|
|
213
|
+ } else {
|
|
214
|
+ for (var i = 0; i < emotions.length; i++) {
|
|
215
|
+ tmsg = msgContent.substring(0, msgContent.indexOf(emotions[i]));
|
|
216
|
+ if (tmsg) {
|
|
217
|
+ text_obj = new webim.Msg.Elem.Text(tmsg);
|
|
218
|
+ msg.addText(text_obj);
|
|
219
|
+ }
|
|
220
|
+ emotionIndex = webim.EmotionDataIndexs[emotions[i]];
|
|
221
|
+ emotion = webim.Emotions[emotionIndex];
|
|
222
|
+
|
|
223
|
+ if (emotion) {
|
|
224
|
+ face_obj = new webim.Msg.Elem.Face(emotionIndex, emotions[i]);
|
|
225
|
+ msg.addFace(face_obj);
|
|
226
|
+ } else {
|
|
227
|
+ text_obj = new webim.Msg.Elem.Text(emotions[i]);
|
|
228
|
+ msg.addText(text_obj);
|
|
229
|
+ }
|
|
230
|
+ restMsgIndex = msgContent.indexOf(emotions[i]) + emotions[i].length;
|
|
231
|
+ msgContent = msgContent.substring(restMsgIndex);
|
|
232
|
+ }
|
|
233
|
+ if (msgContent) {
|
|
234
|
+ text_obj = new webim.Msg.Elem.Text(msgContent);
|
|
235
|
+ msg.addText(text_obj);
|
|
236
|
+ }
|
|
237
|
+ }
|
|
238
|
+
|
|
239
|
+ msg.PushInfo = {
|
|
240
|
+ "PushFlag": 0,
|
|
241
|
+ "Desc": '测试离线推送内容', //离线推送内容
|
|
242
|
+ "Ext": '测试离线推送透传内容', //离线推送透传内容
|
|
243
|
+ "AndroidInfo": {
|
|
244
|
+ "Sound": "android.mp3" //离线推送声音文件路径。
|
|
245
|
+ },
|
|
246
|
+ "ApnsInfo": {
|
|
247
|
+ "Sound": "apns.mp3", //离线推送声音文件路径。
|
|
248
|
+ "BadgeMode": 1
|
|
249
|
+ }
|
|
250
|
+ };
|
|
251
|
+
|
|
252
|
+ msg.PushInfoBoolean = true; //是否开启离线推送push同步
|
|
253
|
+ msg.sending = 1;
|
|
254
|
+ msg.originContent = msgContent;
|
|
255
|
+ // turnoffFaces_box();
|
|
256
|
+ var _this = this;
|
|
257
|
+
|
|
258
|
+ webim.sendMsg(msg, function (resp) {
|
|
259
|
+ _this.addMsg(msg);
|
|
260
|
+ _this.message = '';
|
|
261
|
+ }, function (err) {
|
|
262
|
+ console.log(err)
|
|
263
|
+ });
|
|
264
|
+ },
|
|
265
|
+ addMsg(msg, prepage) {
|
|
266
|
+ var messageitem = {
|
|
267
|
+ id:'',
|
|
268
|
+ message:'',
|
|
269
|
+ avatar:'',
|
|
270
|
+ time:'',
|
|
271
|
+ float:''
|
|
272
|
+ };
|
|
273
|
+ var isSelfSend, fromAccount, fromAccountNick, fromAccountImage, sessType, subType;
|
|
274
|
+
|
|
275
|
+ //webim.SESSION_TYPE.GROUP-群聊,
|
|
276
|
+ //webim.SESSION_TYPE.C2C-私聊,
|
|
277
|
+ sessType = msg.getSession().type();
|
|
278
|
+ isSelfSend = msg.getIsSend();//消息是否为自己发的
|
|
279
|
+ fromAccount = msg.getFromAccount();
|
|
280
|
+ if (!fromAccount) {
|
|
281
|
+ return;
|
|
282
|
+ }
|
|
283
|
+ if (isSelfSend) {//如果是自己发的消息
|
|
284
|
+ messageitem.avatar = this.loginInfo.headurl;
|
|
285
|
+ messageitem.float = "right";
|
|
286
|
+ } else {
|
|
287
|
+ messageitem.avatar = this.kefuUrl;
|
|
288
|
+ messageitem.float = "left";
|
|
289
|
+ }
|
|
290
|
+ messageitem.id = msg.random;
|
|
291
|
+ messageitem.time = webim.Tool.formatText2Html(webim.Tool.formatTimeStamp(msg.getTime()));
|
|
292
|
+ messageitem.message = this.convertMsgtoHtml(msg)
|
|
293
|
+ this.messageBox.push(messageitem);
|
|
294
|
+
|
|
295
|
+ var msgflow = document.getElementsByClassName("msg-inner")[0];
|
|
296
|
+ if (prepage) {
|
|
297
|
+ //300ms后,等待图片加载完,滚动条自动滚动到底部
|
|
298
|
+ if (msgflow.scrollTop == 0) {
|
|
299
|
+ setTimeout(function () {
|
|
300
|
+ msgflow.scrollTop = 0;
|
|
301
|
+ }, 300);
|
|
302
|
+ }
|
|
303
|
+ } else {
|
|
304
|
+ //300ms后,等待图片加载完,滚动条自动滚动到底部
|
|
305
|
+ setTimeout(function () {
|
|
306
|
+ msgflow.scrollTop = msgflow.scrollHeight;
|
|
307
|
+ }, 300);
|
|
308
|
+ }
|
|
309
|
+ },
|
|
310
|
+ sendPic(images, imgName) {
|
|
311
|
+ var _this = this;
|
|
312
|
+ if (!this.selToID) {
|
|
313
|
+ alert("请先选择对话用户");
|
|
314
|
+ return;
|
|
315
|
+ }
|
|
316
|
+
|
|
317
|
+ if (!this.selSess) {
|
|
318
|
+ this.selSess = new webim.Session(selType, this.selToID, this.selToID, this.kefuUrl, Math.round(new Date().getTime() / 1000));
|
|
319
|
+ }
|
|
320
|
+ var msg = new webim.Msg(this.selSess, true, -1, -1, -1, this.loginInfo.identifier, 0, this.loginInfo.identifierNick);
|
|
321
|
+ var images_obj = new webim.Msg.Elem.Images(images.File_UUID);
|
|
322
|
+ for (var i in images.URL_INFO) {
|
|
323
|
+ var img = images.URL_INFO[i];
|
|
324
|
+ var newImg;
|
|
325
|
+ var type;
|
|
326
|
+ switch (img.PIC_TYPE) {
|
|
327
|
+ case 1://原图
|
|
328
|
+ type = 1;//原图
|
|
329
|
+ break;
|
|
330
|
+ case 2://小图(缩略图)
|
|
331
|
+ type = 3;//小图
|
|
332
|
+ break;
|
|
333
|
+ case 4://大图
|
|
334
|
+ type = 2;//大图
|
|
335
|
+ break;
|
|
336
|
+ }
|
|
337
|
+ newImg = new webim.Msg.Elem.Images.Image(type, img.PIC_Size, img.PIC_Width, img.PIC_Height, img.DownUrl);
|
|
338
|
+ images_obj.addImage(newImg);
|
|
339
|
+ }
|
|
340
|
+ msg.addImage(images_obj);
|
|
341
|
+ //if(imgName){
|
|
342
|
+ // var data=imgName;//通过自定义消息中的data字段保存图片名称
|
|
343
|
+ // var custom_obj = new webim.Msg.Elem.Custom(data, '', '');
|
|
344
|
+ // msg.addCustom(custom_obj);
|
|
345
|
+ //}
|
|
346
|
+ //调用发送图片消息接口
|
|
347
|
+ webim.sendMsg(msg, function (resp) {
|
|
348
|
+ if (selType == webim.SESSION_TYPE.C2C) {//私聊时,在聊天窗口手动添加一条发的消息,群聊时,长轮询接口会返回自己发的消息
|
|
349
|
+ _this.addMsg(msg);
|
|
350
|
+ }
|
|
351
|
+ }, function (err) {
|
|
352
|
+ alert(err.ErrorInfo);
|
|
353
|
+ });
|
|
354
|
+ },
|
|
355
|
+ bindScrollHistoryEvent(axtion){
|
|
356
|
+ var msgflow = document.getElementsByClassName("msg-inner")[0];
|
|
357
|
+ var _this = this;
|
|
358
|
+ if (axtion=='init') {
|
|
359
|
+ msgflow.onscroll = function () {
|
|
360
|
+ if (msgflow.scrollTop == 0) {
|
|
361
|
+ msgflow.scrollTop = 10;
|
|
362
|
+ if (selType == webim.SESSION_TYPE.C2C) {
|
|
363
|
+ _this.getPrePageC2CHistoryMsgs();
|
|
364
|
+ }
|
|
365
|
+ }
|
|
366
|
+ }
|
|
367
|
+ }else {
|
|
368
|
+ msgflow.onscroll = null;
|
|
369
|
+ }
|
|
370
|
+ },
|
|
371
|
+ getPrePageC2CHistoryMsgs (cbOk, cbError) {
|
|
372
|
+ var _this = this;
|
|
373
|
+ if (selType == webim.SESSION_TYPE.GROUP) {
|
|
374
|
+ _this.$message.error("当前的聊天类型为群聊天,不能进行拉取好友历史消息操作");
|
|
375
|
+ return;
|
|
376
|
+ }
|
|
377
|
+ var tempInfo = getPrePageC2CHistroyMsgInfoMap[_this.selToID];//获取下一次拉取的c2c消息时间和消息Key
|
|
378
|
+ var lastMsgTime;
|
|
379
|
+ var msgKey;
|
|
380
|
+ if (tempInfo) {
|
|
381
|
+ lastMsgTime = tempInfo.LastMsgTime;
|
|
382
|
+ msgKey = tempInfo.MsgKey;
|
|
383
|
+ } else {
|
|
384
|
+ _this.$message.error("获取下一次拉取的c2c消息时间和消息Key为空");
|
|
385
|
+ return;
|
|
386
|
+ }
|
|
387
|
+ var options = {
|
|
388
|
+ 'Peer_Account': _this.selToID, //好友帐号
|
|
389
|
+ 'MaxCnt': reqMsgCount, //拉取消息条数
|
|
390
|
+ 'LastMsgTime': lastMsgTime, //最近的消息时间,即从这个时间点向前拉取历史消息
|
|
391
|
+ 'MsgKey': msgKey
|
|
392
|
+ };
|
|
393
|
+ webim.getC2CHistoryMsgs(
|
|
394
|
+ options,
|
|
395
|
+ function (resp) {
|
|
396
|
+ var complete = resp.Complete;//是否还有历史消息可以拉取,1-表示没有,0-表示有
|
|
397
|
+ if (resp.MsgList.length == 0) {
|
|
398
|
+ webim.Log.warn("没有历史消息了:data=" + JSON.stringify(options));
|
|
399
|
+ return;
|
|
400
|
+ }
|
|
401
|
+ getPrePageC2CHistroyMsgInfoMap[_this.selToID] = {//保留服务器返回的最近消息时间和消息Key,用于下次向前拉取历史消息
|
|
402
|
+ 'LastMsgTime': resp.LastMsgTime,
|
|
403
|
+ 'MsgKey': resp.MsgKey
|
|
404
|
+ };
|
|
405
|
+ if (cbOk) {
|
|
406
|
+ cbOk(resp.MsgList);
|
|
407
|
+ } else {
|
|
408
|
+ _this.getHistoryMsgCallback(resp.MsgList, true);
|
|
409
|
+ }
|
|
410
|
+ },
|
|
411
|
+ cbError
|
|
412
|
+ );
|
|
413
|
+ },
|
|
414
|
+ getLastC2CHistoryMsgs (cbOk, cbError) {
|
|
415
|
+ var _this = this;
|
|
416
|
+ var lastMsgTime = 0;//第一次拉取好友历史消息时,必须传0
|
|
417
|
+ var msgKey = '';
|
|
418
|
+ var options = {
|
|
419
|
+ 'Peer_Account': this.selToID, //好友帐号
|
|
420
|
+ 'MaxCnt': reqMsgCount, //拉取消息条数
|
|
421
|
+ 'LastMsgTime': lastMsgTime, //最近的消息时间,即从这个时间点向前拉取历史消息
|
|
422
|
+ 'MsgKey': msgKey
|
|
423
|
+ };
|
|
424
|
+ this.selSess = null;
|
|
425
|
+ webim.MsgStore.delSessByTypeId(selType, this.selToID);
|
|
426
|
+
|
|
427
|
+ webim.getC2CHistoryMsgs(
|
|
428
|
+ options,
|
|
429
|
+ function (resp) {
|
|
430
|
+ var complete = resp.Complete;//是否还有历史消息可以拉取,1-表示没有,0-表示有
|
|
431
|
+
|
|
432
|
+ if (resp.MsgList.length == 0) {
|
|
433
|
+ webim.Log.warn("没有历史消息了:data=" + JSON.stringify(options));
|
|
434
|
+ return;
|
|
435
|
+ }
|
|
436
|
+ getPrePageC2CHistroyMsgInfoMap[_this.selToID] = {//保留服务器返回的最近消息时间和消息Key,用于下次向前拉取历史消息
|
|
437
|
+ 'LastMsgTime': resp.LastMsgTime,
|
|
438
|
+ 'MsgKey': resp.MsgKey
|
|
439
|
+ };
|
|
440
|
+
|
|
441
|
+ if (cbOk)
|
|
442
|
+ cbOk(resp.MsgList);
|
|
443
|
+ },
|
|
444
|
+ cbError
|
|
445
|
+ );
|
|
446
|
+ },
|
|
447
|
+ getHistoryMsgCallback(msgList, prepage) {
|
|
448
|
+ var msg;
|
|
449
|
+ var prepage = prepage || false;
|
|
450
|
+
|
|
451
|
+ //如果是加载前几页的消息,消息体需要prepend,所以先倒排一下
|
|
452
|
+ if (prepage) {
|
|
453
|
+ msgList.reverse();
|
|
454
|
+ }
|
|
455
|
+
|
|
456
|
+ for (var j in msgList) {//遍历新消息
|
|
457
|
+ msg = msgList[j];
|
|
458
|
+ if (msg.getSession().id() == this.selToID) {//为当前聊天对象的消息
|
|
459
|
+ this.selSess = msg.getSession();
|
|
460
|
+ //在聊天窗体中新增一条消息
|
|
461
|
+ this.addMsg(msg, prepage);
|
|
462
|
+ }
|
|
463
|
+ }
|
|
464
|
+ //消息已读上报,并将当前会话的消息设置成自动已读
|
|
465
|
+ webim.setAutoRead(this.selSess, true, true);
|
|
466
|
+ },
|
|
467
|
+ convertMsgtoHtml(msg) {
|
|
468
|
+ var html = "",
|
|
469
|
+ elems, elem, type, content;
|
|
470
|
+ elems = msg.getElems(); //获取消息包含的元素数组
|
|
471
|
+ var count = elems.length;
|
|
472
|
+ for (var i = 0; i < count; i++) {
|
|
473
|
+ elem = elems[i];
|
|
474
|
+ type = elem.getType();//获取元素类型
|
|
475
|
+ content = elem.getContent();//获取元素对象
|
|
476
|
+ switch (type) {
|
|
477
|
+ case webim.MSG_ELEMENT_TYPE.TEXT:
|
|
478
|
+ var eleHtml = this.convertTextMsgToHtml(content);
|
|
479
|
+ //转义,防XSS
|
|
480
|
+ html += webim.Tool.formatText2Html(eleHtml);
|
|
481
|
+ break;
|
|
482
|
+ case webim.MSG_ELEMENT_TYPE.FACE:
|
|
483
|
+ html += this.convertFaceMsgToHtml(content);
|
|
484
|
+ break;
|
|
485
|
+ case webim.MSG_ELEMENT_TYPE.IMAGE:
|
|
486
|
+ if (i <= count - 2) {
|
|
487
|
+ var customMsgElem = elems[i + 1];//获取保存图片名称的自定义消息elem
|
|
488
|
+ var imgName = customMsgElem.getContent().getData();//业务可以自定义保存字段,demo中采用data字段保存图片文件名
|
|
489
|
+ html += this.convertImageMsgToHtml(content, imgName);
|
|
490
|
+ i++;//下标向后移一位
|
|
491
|
+ } else {
|
|
492
|
+ html += this.convertImageMsgToHtml(content);
|
|
493
|
+ }
|
|
494
|
+ break;
|
|
495
|
+ case webim.MSG_ELEMENT_TYPE.SOUND:
|
|
496
|
+ html += this.convertSoundMsgToHtml(content);
|
|
497
|
+ break;
|
|
498
|
+ case webim.MSG_ELEMENT_TYPE.FILE:
|
|
499
|
+ html += this.convertFileMsgToHtml(content);
|
|
500
|
+ break;
|
|
501
|
+ case webim.MSG_ELEMENT_TYPE.LOCATION:
|
|
502
|
+ html += this.convertLocationMsgToHtml(content);
|
|
503
|
+ break;
|
|
504
|
+ case webim.MSG_ELEMENT_TYPE.CUSTOM:
|
|
505
|
+ var eleHtml = this.convertCustomMsgToHtml(content);
|
|
506
|
+ //转义,防XSS
|
|
507
|
+ html += webim.Tool.formatText2Html(eleHtml);
|
|
508
|
+ break;
|
|
509
|
+ case webim.MSG_ELEMENT_TYPE.GROUP_TIP:
|
|
510
|
+ var eleHtml = this.convertGroupTipMsgToHtml(content);
|
|
511
|
+ //转义,防XSS
|
|
512
|
+ html += webim.Tool.formatText2Html(eleHtml);
|
|
513
|
+ break;
|
|
514
|
+ default:
|
|
515
|
+ webim.Log.error('未知消息元素类型: elemType=' + type);
|
|
516
|
+ break;
|
|
517
|
+ }
|
|
518
|
+ }
|
|
519
|
+ return html;
|
|
520
|
+ },
|
|
521
|
+ convertTextMsgToHtml(content) {
|
|
522
|
+ return content.getText();
|
|
523
|
+ },
|
|
524
|
+ //解析表情消息元素
|
|
525
|
+ convertFaceMsgToHtml(content) {
|
|
526
|
+ var faceUrl = null;
|
|
527
|
+ var data = content.getData();
|
|
528
|
+ var index = webim.EmotionDataIndexs[data];
|
|
529
|
+
|
|
530
|
+ var emotion = webim.Emotions[index];
|
|
531
|
+ if (emotion && emotion[1]) {
|
|
532
|
+ faceUrl = emotion[1];
|
|
533
|
+ }
|
|
534
|
+ if (faceUrl) {
|
|
535
|
+ return "<img src='" + faceUrl + "'/>";
|
|
536
|
+ } else {
|
|
537
|
+ return data;
|
|
538
|
+ }
|
|
539
|
+ },
|
|
540
|
+ //解析图片消息元素
|
|
541
|
+ convertImageMsgToHtml(content, imageName) {
|
|
542
|
+ var smallImage = content.getImage(webim.IMAGE_TYPE.SMALL);//小图
|
|
543
|
+ var bigImage = content.getImage(webim.IMAGE_TYPE.LARGE);//大图
|
|
544
|
+ var oriImage = content.getImage(webim.IMAGE_TYPE.ORIGIN);//原图
|
|
545
|
+ if (!bigImage) {
|
|
546
|
+ bigImage = smallImage;
|
|
547
|
+ }
|
|
548
|
+ if (!oriImage) {
|
|
549
|
+ oriImage = smallImage;
|
|
550
|
+ }
|
|
551
|
+ return "<img name='" + imageName + "' src='" + smallImage.getUrl() + "#" + bigImage.getUrl() + "#" + oriImage.getUrl() + "' style='CURSOR: hand' id='" + content.getImageId() + "' bigImgUrl='" + bigImage.getUrl() + "'/>";
|
|
552
|
+ },
|
|
553
|
+ handleIMPicUload:function(fileobj){
|
|
554
|
+ var file = fileobj.file
|
|
555
|
+ console.log("file", file);
|
|
556
|
+ var _this = this;
|
|
557
|
+ var businessType;//业务类型,1-发群图片,2-向好友发图片
|
|
558
|
+ if (selType != webim.SESSION_TYPE.C2C) {//向好友发图片
|
|
559
|
+ this.$message.error('不支持群聊');
|
|
560
|
+ return;
|
|
561
|
+ }
|
|
562
|
+ businessType = webim.UPLOAD_PIC_BUSSINESS_TYPE.C2C_MSG;
|
|
563
|
+ //封装上传图片请求
|
|
564
|
+ var opt = {
|
|
565
|
+ 'file': file, //图片对象
|
|
566
|
+ 'onProgressCallBack': this.onProgressCallBack, //上传图片进度条回调函数
|
|
567
|
+ //'abortButton': document.getElementById('upd_abort'), //停止上传图片按钮
|
|
568
|
+ 'To_Account': this.selToID, //接收者
|
|
569
|
+ 'businessType': businessType//业务类型
|
|
570
|
+ };
|
|
571
|
+ //上传图片
|
|
572
|
+ webim.uploadPic(opt,
|
|
573
|
+ function (resp) {
|
|
574
|
+ //上传成功发送图片
|
|
575
|
+ _this.sendPic(resp, file.name);
|
|
576
|
+
|
|
577
|
+ },
|
|
578
|
+ function (err) {
|
|
579
|
+ alert(err.ErrorInfo);
|
|
580
|
+ }
|
|
581
|
+ );
|
|
582
|
+ },
|
|
583
|
+ handleIMPicSuccess:function(){},
|
|
584
|
+ beforeIMPicUpload:function(file){
|
|
585
|
+ var fileType = file.type;
|
|
586
|
+ const isJPG = fileType.indexOf("image") > -1;
|
|
587
|
+ if (!isJPG) {
|
|
588
|
+ this.$message.error('只能上传图片');
|
|
589
|
+ }
|
|
590
|
+ return isJPG;
|
|
591
|
+ },
|
|
592
|
+ togglePhoneBox:function(){
|
|
593
|
+ if (this.showPhoneBox) {
|
|
594
|
+ this.showPhoneBox = false;
|
|
595
|
+ }else {
|
|
596
|
+ this.showPhoneBox = true;
|
|
597
|
+ }
|
|
598
|
+ this.showMsgBox = false;
|
|
599
|
+ },
|
|
600
|
+ toggleMsgBox:function(){
|
|
601
|
+ if (this.showMsgBox) {
|
|
602
|
+ this.showMsgBox = false;
|
|
603
|
+ }else {
|
|
604
|
+ this.showMsgBox = true;
|
|
605
|
+ }
|
|
606
|
+ this.showPhoneBox = false;
|
|
607
|
+ },
|
|
608
|
+ webimlogin(){
|
|
609
|
+ let _this = this;
|
|
610
|
+ let listeners = {
|
|
611
|
+ "onConnNotify": this.onConnNotify //监听连接状态回调变化事件,必填
|
|
612
|
+ , "jsonpCallback": this.jsonpCallback //IE9(含)以下浏览器用到的jsonp回调函数,
|
|
613
|
+ , "onMsgNotify": this.onMsgNotify //监听新消息(私聊,普通群(非直播聊天室)消息,全员推送消息)事件,必填
|
|
614
|
+ , "onProfileSystemNotifys": this.onProfileSystemNotifys //监听资料系统(自己或好友)通知事件,选填
|
|
615
|
+ , "onKickedEventCall": this.onKickedEventCall //被其他登录实例踢下线
|
|
616
|
+ , "onC2cEventNotifys": this.onC2cEventNotifys //监听C2C系统消息通道
|
|
617
|
+ };
|
|
618
|
+ webim.login(this.loginInfo, listeners, this.loginOptions,
|
|
619
|
+ function(resp){
|
|
620
|
+ _this.$message.success('webim登录成功');
|
|
621
|
+ _this.imloginFlag = true;
|
|
622
|
+ },
|
|
623
|
+ function(err) {
|
|
624
|
+ _this.$message.error('webim登录错误');
|
|
625
|
+ }
|
|
626
|
+ );
|
|
627
|
+ },
|
|
628
|
+ onConnNotify(){},
|
|
629
|
+ jsonpCallback(){},
|
|
630
|
+ onMsgNotify(newMsgList){
|
|
631
|
+ //监听新消息事件
|
|
632
|
+ var msgList = [];
|
|
633
|
+ var dateStart = null;
|
|
634
|
+ var dateEnd = null;
|
|
635
|
+
|
|
636
|
+ //console.warn(newMsgList);
|
|
637
|
+ var sess, newMsg, formId;
|
|
638
|
+ //获取所有聊天会话
|
|
639
|
+ var sessMap = webim.MsgStore.sessMap();
|
|
640
|
+
|
|
641
|
+ for (var j in newMsgList) {//遍历新消息
|
|
642
|
+
|
|
643
|
+ newMsg = newMsgList[j];
|
|
644
|
+ formId = newMsg.getSession().id();
|
|
645
|
+ if (formId.indexOf("AdminKeFu")<0) {
|
|
646
|
+ continue;
|
|
647
|
+ }else {
|
|
648
|
+ if (newMsg.getSession().id() == this.selToID) {//为当前聊天对象的消息
|
|
649
|
+ this.addMsg(newMsg);
|
|
650
|
+ }
|
|
651
|
+ msgList.push(newMsg.elems[0].content.text);
|
|
652
|
+ }
|
|
653
|
+
|
|
654
|
+ }
|
|
655
|
+ },
|
|
656
|
+ onProfileSystemNotifys(){},
|
|
657
|
+ onKickedEventCall(){},
|
|
658
|
+ onC2cEventNotifys(){},
|
|
659
|
+ },
|
|
660
|
+ watch:{
|
|
661
|
+ 'userSigFlag':function(value){
|
|
662
|
+ if(this.userSigFlag) {
|
|
663
|
+ this.webimlogin();
|
|
664
|
+ }
|
|
665
|
+ },
|
|
666
|
+ 'imloginFlag':function(value) {
|
|
667
|
+ var _this = this;
|
|
668
|
+ if (this.imloginFlag) {
|
|
669
|
+ this.bindScrollHistoryEvent('reset');
|
|
670
|
+ this.getLastC2CHistoryMsgs(function (msgList) {
|
|
671
|
+ _this.getHistoryMsgCallback(msgList);
|
|
672
|
+ _this.bindScrollHistoryEvent('init');
|
|
673
|
+ //绑定滚动操作
|
|
674
|
+ }, function (err) {
|
|
675
|
+ alert(err.ErrorInfo);
|
|
676
|
+ });
|
|
677
|
+ }
|
|
678
|
+ }
|
|
679
|
+ },
|
71
|
680
|
|
72
|
681
|
}
|
73
|
682
|
</script>
|
|
@@ -78,7 +687,7 @@ export default {
|
78
|
687
|
right: 12px;
|
79
|
688
|
bottom: 10%;
|
80
|
689
|
margin-top: -100px;
|
81
|
|
- z-index: 99999;
|
|
690
|
+ z-index: 9999;
|
82
|
691
|
}
|
83
|
692
|
|
84
|
693
|
.contact-box .contact-box-item{
|
|
@@ -102,18 +711,17 @@ export default {
|
102
|
711
|
color: #59a3ec;
|
103
|
712
|
display: inline-block;
|
104
|
713
|
}
|
105
|
|
-.contact-box .contact-box-item .box-btn:hover {
|
106
|
|
- background: #5aa6f1;
|
107
|
|
-}
|
|
714
|
+/* .contact-box .contact-box-item .box-btn:hover {
|
|
715
|
+} */
|
108
|
716
|
.contact-box .box-btn span{
|
109
|
717
|
display: none;
|
110
|
|
-}
|
111
|
|
-
|
112
|
|
-.contact-box .box-btn:hover span{
|
113
|
|
- display: block;
|
114
|
718
|
color:#fff;
|
115
|
719
|
padding: 8px;
|
116
|
720
|
font-size: 14px;
|
|
721
|
+ background: #5aa6f1;
|
|
722
|
+}
|
|
723
|
+.contact-box .box-btn:hover span{
|
|
724
|
+ display: block;
|
117
|
725
|
}
|
118
|
726
|
.contact-box .box-btn:hover i{
|
119
|
727
|
display: none;
|
|
@@ -124,10 +732,9 @@ export default {
|
124
|
732
|
bottom: 0px;
|
125
|
733
|
right: 56px;
|
126
|
734
|
height: 48px;
|
127
|
|
- /* display: block; */
|
|
735
|
+ display:flex;
|
128
|
736
|
background: #fff;
|
129
|
737
|
width: 230px;
|
130
|
|
- display:none;
|
131
|
738
|
align-items: center;
|
132
|
739
|
}
|
133
|
740
|
.contact-box .contact-phone-box i {
|
|
@@ -135,10 +742,6 @@ export default {
|
135
|
742
|
font-size:30px;
|
136
|
743
|
margin: 9px;
|
137
|
744
|
}
|
138
|
|
-.contact-box .phone-box:hover .contact-phone-box{
|
139
|
|
- display:flex;
|
140
|
|
-}
|
141
|
|
-
|
142
|
745
|
.contact-box .contact-phone-box span {
|
143
|
746
|
font-size:20px;
|
144
|
747
|
margin-left: 15px;
|
|
@@ -153,7 +756,7 @@ export default {
|
153
|
756
|
display: none;
|
154
|
757
|
background: #fff;
|
155
|
758
|
width: 175px;
|
156
|
|
- z-index: 1000000;
|
|
759
|
+ z-index: 10000;
|
157
|
760
|
}
|
158
|
761
|
.contact-box .msg-box:hover .contact-info-box{
|
159
|
762
|
display:block;
|
|
@@ -216,4 +819,114 @@ export default {
|
216
|
819
|
.contact-box .scroll-y::-webkit-scrollbar-track {
|
217
|
820
|
border-radius: 2px;
|
218
|
821
|
}
|
|
822
|
+.contact-box .msg-inner .cell {
|
|
823
|
+ margin-bottom: 15px;
|
|
824
|
+}
|
|
825
|
+.contact-box .cell_right {
|
|
826
|
+ float: right;
|
|
827
|
+}
|
|
828
|
+
|
|
829
|
+.contact-box .clearfix {
|
|
830
|
+ clear: both;
|
|
831
|
+}
|
|
832
|
+.contact-box .msg-inner .msg_body {
|
|
833
|
+ border: 1px #e5e5e5 solid;
|
|
834
|
+ line-height: 22px;
|
|
835
|
+ display: inline-block;
|
|
836
|
+ padding: 6px;
|
|
837
|
+ max-width: 292px;
|
|
838
|
+}
|
|
839
|
+.contact-box .fl {
|
|
840
|
+ float: left;
|
|
841
|
+}
|
|
842
|
+.contact-box .msg-inner .msg_body .inner {
|
|
843
|
+ color: #465b6e;
|
|
844
|
+}
|
|
845
|
+.contact-box .msg-inner .cell_pic {
|
|
846
|
+ width: 40px;
|
|
847
|
+ height: 40px;
|
|
848
|
+ display: inline-block;
|
|
849
|
+ margin: 0 20px;
|
|
850
|
+}
|
|
851
|
+.contact-box .msg-inner .cell_pic .pic {
|
|
852
|
+ width: 40px;
|
|
853
|
+ height: 40px;
|
|
854
|
+ display: flex;
|
|
855
|
+}
|
|
856
|
+.contact-box .msg-inner .cell_pic .pic img {
|
|
857
|
+ width: 40px;
|
|
858
|
+ height: 40px;
|
|
859
|
+ border-radius: 50%;
|
|
860
|
+ object-fit: cover;
|
|
861
|
+ object-position: center;
|
|
862
|
+}
|
|
863
|
+
|
|
864
|
+.contact-box .msg-box-panel .panel-booter .textarea {
|
|
865
|
+ border: 1px #fff solid;
|
|
866
|
+ padding: 10px 20px;
|
|
867
|
+ color: #465b6e;
|
|
868
|
+ height: 100px;
|
|
869
|
+ resize: none;
|
|
870
|
+ width: 100%;
|
|
871
|
+}
|
|
872
|
+.contact-box .msg-box-panel .panel-booter .msg-send-btn-box {
|
|
873
|
+ padding: 0 20px 10px 20px;
|
|
874
|
+ float: left;
|
|
875
|
+ background: #fff;
|
|
876
|
+ width: 408px;
|
|
877
|
+}
|
|
878
|
+.contact-box .msg-box-panel .panel-booter .time {
|
|
879
|
+ font-size: 12px;
|
|
880
|
+ color: #bebebe;
|
|
881
|
+ height: 26px;
|
|
882
|
+ line-height: 26px;
|
|
883
|
+}
|
|
884
|
+.contact-box .msg-box-panel .panel-booter .msg-send-btn-box .send_btn {
|
|
885
|
+ color: #fff;
|
|
886
|
+ padding: 6px 20px;
|
|
887
|
+ border-radius: 4px;
|
|
888
|
+ font-size: 12px;
|
|
889
|
+ background: #58a1ed;
|
|
890
|
+ border: none;
|
|
891
|
+}
|
|
892
|
+
|
|
893
|
+.contact-box .panel-tool {
|
|
894
|
+ color: #465b6e;
|
|
895
|
+ height: 30px;
|
|
896
|
+ border-bottom: 1px #e5e5e5 solid;
|
|
897
|
+ display:flex;
|
|
898
|
+ align-items: center;
|
|
899
|
+}
|
|
900
|
+
|
|
901
|
+.contact-box .panel-tool i {
|
|
902
|
+ font-size: 20px;
|
|
903
|
+ padding: 0 5px;
|
|
904
|
+ margin: 0 5px;
|
|
905
|
+ cursor: pointer;
|
|
906
|
+}
|
|
907
|
+
|
|
908
|
+.contact-box .panel-tool .icon-face::before {
|
|
909
|
+ content: '\1F642';
|
|
910
|
+ font-size: 15px;
|
|
911
|
+}
|
|
912
|
+.contact-box .face-box {
|
|
913
|
+ width: 304px;
|
|
914
|
+ z-index: 10001;
|
|
915
|
+ background: #fff;
|
|
916
|
+ position: relative;
|
|
917
|
+ bottom: 70px;
|
|
918
|
+ left: -100px;
|
|
919
|
+ border: 2px #e5e5e5 solid;
|
|
920
|
+}
|
|
921
|
+.contact-box .face-box-list li {
|
|
922
|
+ display: inline-block;
|
|
923
|
+
|
|
924
|
+ border-right: 1px #CCC solid;
|
|
925
|
+ border-bottom: 1px #CCC solid;
|
|
926
|
+ cursor: pointer;
|
|
927
|
+}
|
|
928
|
+.contact-box .face-box-title {
|
|
929
|
+ border-bottom: 1px #e5e5e5 solid;
|
|
930
|
+ margin: 2px 0;
|
|
931
|
+}
|
219
|
932
|
</style>
|