This commit is contained in:
wxl 2025-01-10 00:28:12 +08:00
parent 2e07ea8a71
commit f2348ef1f5
9 changed files with 248 additions and 152 deletions

View File

@ -1,8 +1,10 @@
package com.dd.admin.business.chat.controller; package com.dd.admin.business.chat.controller;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.pinyin.PinyinUtil; import cn.hutool.extra.pinyin.PinyinUtil;
import com.dd.admin.business.chat.domain.AuthorChat; import com.dd.admin.business.chat.domain.AuthorChat;
import com.dd.admin.business.chat.domain.MessageBean;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -18,7 +20,7 @@ import com.dd.admin.business.chat.domain.ChatVo;
import com.dd.admin.business.chat.domain.ChatDto; import com.dd.admin.business.chat.domain.ChatDto;
import com.dd.admin.business.chat.service.ChatService; import com.dd.admin.business.chat.service.ChatService;
import java.util.List; import java.util.*;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -37,18 +39,63 @@ public class ChatController {
@Autowired @Autowired
ChatService chatService; ChatService chatService;
/**
* 将给定的Date对象转换为对应东八区Asia/Shanghai的时间戳
*
* @param createTime 要转换的Date对象
* @return 对应东八区的时间戳以毫秒为单位
*/
public static long convertToShanghaiTimeZoneTimestamp(Date createTime) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(createTime);
calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
return calendar.getTimeInMillis();
}
@ApiOperation(value = "作者列表") @ApiOperation(value = "作者列表")
@ApiOperationSupport(order = 2) @ApiOperationSupport(order = 2)
@GetMapping("/admin/chat/authorList") @GetMapping("/admin/chat/authorList")
public ResultBean<List<AuthorChat>> authorList() { public ResultBean<List<AuthorChat>> authorList(String authorId) {
List<AuthorChat> authorChats = chatService.selectAuthorChatList(); List<AuthorChat> authorChats = chatService.selectAuthorChatList(authorId);
authorChats.stream().forEach(authorChat -> { authorChats.stream().forEach(authorChat -> {
authorChat.setIndex(String.valueOf(PinyinUtil.getFirstLetter(authorChat.getIndex().charAt(0)))); authorChat.setIndex(String.valueOf(PinyinUtil.getFirstLetter(authorChat.getIndex().charAt(0))));
if(authorChat.getCreateTime()!=null){
authorChat.setLastSendTime(convertToShanghaiTimeZoneTimestamp( authorChat.getCreateTime()));
}
}); });
return ResultBean.success(authorChats); return ResultBean.success(authorChats);
} }
@ApiOperation(value = "作者相关聊天信息")
@ApiOperationSupport(order = 2)
@GetMapping("/admin/chat/getAuthorChat")
public ResultBean<IPage<MessageBean>> getAuthorChat(String authorId, String fromId) {
ChatDto chatDto = new ChatDto();
chatDto.setFromId(fromId);
chatDto.setToId(authorId);
IPage chatPage = chatService.selectChatPage(chatDto);
List<ChatVo> records = chatPage.getRecords();
List<MessageBean> messageBeanList = new ArrayList<>();
records.stream().forEach(chatVo -> {
MessageBean messageBean = new MessageBean();
messageBean.setId(chatVo.getChatId());
messageBean.setContent(chatVo.getContent());
messageBean.setSendTime(convertToShanghaiTimeZoneTimestamp(chatVo.getCreateTime()));
messageBean.setStatus("succeed");
messageBean.setType("text");
messageBean.setToContactId(chatVo.getToId());
MessageBean.FromUser fromUser = new MessageBean.FromUser();
fromUser.setAvatar(chatVo.getFromAvatar());
fromUser.setDisplayName(chatVo.getFromName());
fromUser.setId(chatVo.getFromId());
messageBean.setFromUser(fromUser);
messageBeanList.add(messageBean);
});
chatPage.setRecords(messageBeanList);
return ResultBean.success(chatPage);
}
@ApiOperation(value = "-分页列表") @ApiOperation(value = "-分页列表")

View File

@ -1,10 +1,13 @@
package com.dd.admin.business.chat.domain; package com.dd.admin.business.chat.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Date;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ -36,4 +39,7 @@ public class AuthorChat {
// 最近一条消息的发送时间通常是时间戳形式单位可能是毫秒 // 最近一条消息的发送时间通常是时间戳形式单位可能是毫秒
@ApiModelProperty(value = "最近一条消息发送时间") @ApiModelProperty(value = "最近一条消息发送时间")
private Long lastSendTime; private Long lastSendTime;
@JsonIgnore
private Date CreateTime;
} }

View File

@ -119,7 +119,8 @@
wa.AVATAR_URL avatar, wa.AVATAR_URL avatar,
wa.AUTHOR_NAME AS 'index', wa.AUTHOR_NAME AS 'index',
wb.unReadCount unRead, wb.unReadCount unRead,
UNIX_TIMESTAMP(CONVERT_TZ(wb.CREATE_TIME, '+08:00', '+00:00')) lastSendTime wb.content lastContent,
wb.create_time
FROM FROM
business_author wa business_author wa
LEFT JOIN ( LEFT JOIN (

View File

@ -1 +1 @@
package com.dd.admin.business.webSocket.handler; import cn.hutool.core.bean.BeanUtil; import com.dd.admin.business.chat.domain.ChatVo; import com.dd.admin.business.chat.entity.Chat; import com.dd.admin.business.chat.service.ChatService; import com.dd.admin.business.webSocket.MsgHandlerInterface; import com.dd.admin.business.webSocket.util.TioUtil; import com.dd.admin.common.utils.AddressUtils; import com.dd.admin.common.utils.HttpContext; import com.dd.admin.common.utils.IPUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.tio.core.ChannelContext; import org.tio.core.Tio; import org.tio.http.common.HttpRequest; import org.tio.utils.lock.SetWithLock; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.Map; import java.util.Set; @Component @Slf4j @Service("5") public class P2PMessageHandler implements MsgHandlerInterface { public static P2PMessageHandler handler; @Autowired ChatService chatService; @Override public Object handler(Map map, ChannelContext context ){ Chat chat = BeanUtil.toBean(map, Chat.class); chat.setIpAddress(context.getClientNode().getIp()); chat.setIpRealAddress(AddressUtils.getRealAddress(chat.getIpAddress())); //ip真实地址 chatService.save(chat); ChatVo chatVo = chatService.selectChat(chat.getChatId()); TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getToId(),"5",chatVo); TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getFromId(),"5",chatVo); return null; }} package com.dd.admin.business.webSocket.handler; import cn.hutool.core.bean.BeanUtil; import com.dd.admin.business.chat.domain.ChatVo; import com.dd.admin.business.chat.domain.MessageBean; import com.dd.admin.business.chat.entity.Chat; import com.dd.admin.business.chat.service.ChatService; import com.dd.admin.business.webSocket.MsgHandlerInterface; import com.dd.admin.business.webSocket.util.TioUtil; import com.dd.admin.common.utils.AddressUtils; import com.dd.admin.common.utils.HttpContext; import com.dd.admin.common.utils.IPUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.tio.core.ChannelContext; import org.tio.core.Tio; import org.tio.http.common.HttpRequest; import org.tio.utils.lock.SetWithLock; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.*; @Component @Slf4j @Service("5") public class P2PMessageHandler implements MsgHandlerInterface { public static P2PMessageHandler handler; @Autowired ChatService chatService; public static long convertToShanghaiTimeZoneTimestamp(Date createTime) { Calendar calendar = Calendar.getInstance(); calendar.setTime(createTime); calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); return calendar.getTimeInMillis(); } @Override public Object handler(Map map, ChannelContext context ){ Chat chat = BeanUtil.toBean(map, Chat.class); chat.setIpAddress(context.getClientNode().getIp()); chat.setIpRealAddress(AddressUtils.getRealAddress(chat.getIpAddress())); //ip真实地址 chatService.save(chat); ChatVo chatVo = chatService.selectChat(chat.getChatId()); if(chat.getToId().equals("8")){ MessageBean messageBean = new MessageBean(); messageBean.setId(chatVo.getChatId()); messageBean.setContent(chatVo.getContent()); messageBean.setSendTime(convertToShanghaiTimeZoneTimestamp(chatVo.getCreateTime())); messageBean.setStatus("succeed"); messageBean.setType("text"); messageBean.setToContactId(chatVo.getToId()); MessageBean.FromUser fromUser = new MessageBean.FromUser(); fromUser.setAvatar(chatVo.getFromAvatar()); fromUser.setDisplayName(chatVo.getFromName()); fromUser.setId(chatVo.getFromId()); messageBean.setFromUser(fromUser); System.out.println(messageBean); TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getToId(),"6",messageBean); }else{ TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getToId(),"5",chatVo); } TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getFromId(),"5",chatVo); return null; }}

View File

@ -1 +1 @@
package com.dd.admin.business.webSocket.handler; import cn.hutool.core.bean.BeanUtil; import com.dd.admin.business.chat.domain.ChatVo; import com.dd.admin.business.chat.domain.MessageBean; import com.dd.admin.business.chat.entity.Chat; import com.dd.admin.business.chat.service.ChatService; import com.dd.admin.business.webSocket.MsgHandlerInterface; import com.dd.admin.business.webSocket.util.TioUtil; import com.dd.admin.common.utils.AddressUtils; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.units.qual.C; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.tio.core.ChannelContext; import java.util.Map; @Component @Slf4j @Service("6") public class ServiceMessageHandler implements MsgHandlerInterface { public static ServiceMessageHandler handler; @Autowired ChatService chatService; @Override public Object handler(Map map, ChannelContext context ){ System.out.println(map); MessageBean messageBean = BeanUtil.toBean(map, MessageBean.class); //xx发送人 MessageBean.FromUser fromUser = messageBean.getFromUser(); Chat chat = new Chat(); chat.setFromId(fromUser.getId()); chat.setFromName(fromUser.getDisplayName()); chat.setToId(messageBean.getToContactId()); chat.setContent(messageBean.getContent()); chat.setIpAddress(context.getClientNode().getIp()); chat.setIpRealAddress(AddressUtils.getRealAddress(chat.getIpAddress())); //ip真实地址 chatService.save(chat); ChatVo chatVo = chatService.selectChat(chat.getChatId()); //如果对方是移动端则按照移动端消息格式推送 TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getToId(),"5",chatVo); //还需要推送给客服自己 TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getFromId(),"5",messageBean); return null; }} package com.dd.admin.business.webSocket.handler; import cn.hutool.core.bean.BeanUtil; import com.dd.admin.business.chat.domain.ChatVo; import com.dd.admin.business.chat.domain.MessageBean; import com.dd.admin.business.chat.entity.Chat; import com.dd.admin.business.chat.service.ChatService; import com.dd.admin.business.webSocket.MsgHandlerInterface; import com.dd.admin.business.webSocket.util.TioUtil; import com.dd.admin.common.utils.AddressUtils; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.units.qual.C; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.tio.core.ChannelContext; import java.util.Map; @Component @Slf4j @Service("6") public class ServiceMessageHandler implements MsgHandlerInterface { public static ServiceMessageHandler handler; @Autowired ChatService chatService; @Override public Object handler(Map map, ChannelContext context ){ System.out.println(map); MessageBean messageBean = BeanUtil.toBean(map, MessageBean.class); //xx发送人 MessageBean.FromUser fromUser = messageBean.getFromUser(); Chat chat = new Chat(); chat.setFromId(fromUser.getId()); chat.setFromName(fromUser.getDisplayName()); chat.setToId(messageBean.getToContactId()); chat.setContent(messageBean.getContent()); chat.setIpAddress(context.getClientNode().getIp()); chat.setIpRealAddress(AddressUtils.getRealAddress(chat.getIpAddress())); //ip真实地址 chatService.save(chat); ChatVo chatVo = chatService.selectChat(chat.getChatId()); //如果对方是移动端则按照移动端消息格式推送 TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getToId(),"5",chatVo); //还需要推送给客服自己 TioUtil.sendChatMessageToUser(context.getGroupContext(),chat.getFromId(),"6",messageBean); return null; }}

View File

@ -55,8 +55,11 @@ public class ApiInterceptor implements HandlerInterceptor {
request.setAttribute("authorId",authorId); request.setAttribute("authorId",authorId);
Author author = authorService.getById(authorId); Author author = authorService.getById(authorId);
if(author==null){
throw new ApiException(700,"token已失效");
}
request.setAttribute("author",author); request.setAttribute("author",author);
if(author.getAuthorStatus().equals(1)){ if(author.getAuthorStatus()!=null&&author.getAuthorStatus().equals(1)){
throw new ApiException(700,"当前用户已冻结~"); throw new ApiException(700,"当前用户已冻结~");
} }
return true; return true;

View File

@ -39,9 +39,18 @@ export function deleteChat(copyId) {
}) })
} }
export function getAuthorChatList() { export function getAuthorChatList(params) {
return request({ return request({
url: '/admin/chat/authorList', url: '/admin/chat/authorList',
method: 'get' method: 'get',
params
})
}
export function getAuthorChat(params) {
return request({
url: '/admin/chat/getAuthorChat',
method: 'get',
params
}) })
} }

View File

@ -1,108 +1,121 @@
import { Message } from 'element-ui' class WebSocketManager {
let socket = null;//实例对象 constructor() {
let socketLeaveFlag = false this.webSocketInstance = null; // WebSocket实例对象使用更清晰的命名
let socketReconnectTimer = null // 计时器对象——重连 this.reconnectTimer = null; // 断线重连后,存储延迟请求的代码,用于延迟重连
let socketReconnectLock = false // WebSocket重连的锁 this.isConnected = false; // 连接标识,使用更符合语义的命名
const heartCheck = { this.onConnectCallback = null; // 连接成功的回调函数
vueThis: this, // vue实例 this.onMessageCallback = null; // 收到消息的回调函数
timeout: 6000, // 超时时间 this.onCloseCallback = null; // 连接关闭的回调函数
timeoutObj: null, // 计时器对象——向后端发送心跳检测 this.heartbeatCheck = {
serverTimeoutObj: null, // 计时器对象——等待后端心跳检测的回复 interval: 5000, // 每段时间发送一次心跳包的时间间隔这里设置为5秒使用更表意明确的变量名
// 心跳检测重置 timer: null, // 延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
reset: function () { start: () => {
clearTimeout(this.timeoutObj); if (this.isConnected) {
clearTimeout(this.serverTimeoutObj); console.log('发送WebSocket心跳');
return this; this.webSocketInstance.send('ping');
}
}, },
// 心跳检测启动 reset: () => {
start: function () { clearTimeout(this.heartbeatCheck.timer);
this.timeoutObj && clearTimeout(this.timeoutObj); this.heartbeatCheck.timer = setTimeout(() => {
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); this.heartbeatCheck.start();
this.timeoutObj = setTimeout(() => { }, this.heartbeatCheck.interval);
// 这里向后端发送一个心跳检测,后端收到后,会返回一个心跳回复 }
socket.send("ping");
console.log("发送心跳检测");
this.serverTimeoutObj = setTimeout(() => {
// 如果超过一定时间还没重置计时器说明websocket与后端断开了
console.log("未收到心跳检测回复");
// 关闭WebSocket
socket.close();
}, this.timeout);
}, this.timeout);
},
}
const initWebSocket = (wsUrl) => {
return new Promise(function (resolve, reject) {
if ("WebSocket" in window) {
socket = new WebSocket(wsUrl);
socket.onerror = webSocketOnError;
socket.onmessage = webSocketOnMessage;
socket.onclose = webSocketOnClose;
socket.onopen = () => {
console.log('连接成功');
heartCheck.reset().start();
resolve(socket)
}; };
} else {
Message({
message: "您的浏览器不支持websocket请更换Chrome或者Firefox",
type: 'error',
})
return reject(new Error('浏览器不支持websocket'));
} }
});
} // 连接WebSocket的方法
const webSocketOnError = (e) => { connect(url) {
console.log("WebSocket:发生错误"); try {
socketReconnect(e.target.url) if (this.isConnected) {
window.dispatchEvent(
new CustomEvent("WSOnError", e)
);
}
//服务器返回的数据
const webSocketOnMessage = (e) => {
if (e.data === 'pong') {
console.log('收到心跳回复');
heartCheck.reset().start();
} else {
console.log('服务器返回的数据')
console.log(e)
}
}
const webSocketOnClose = (e) => {
console.log("WebSocket:已关闭");
// 清除心跳定时器
heartCheck.reset();
if (!socketLeaveFlag) {
// websocket重连
socketReconnect(e.target.url)
}
}
const sendMessage = (data) =>{
if (socket) {
socket.send(data);
console.log('消息已发送:', data);
}
}
const socketReconnect = (url) => {
if (socketReconnectLock) {
return; return;
} }
socketReconnectLock = true; console.log("连接WebSocket");
socketReconnectTimer && clearTimeout(socketReconnectTimer); this.webSocketInstance = new WebSocket(url);
socketReconnectTimer = setTimeout(() => { this.webSocketInstance.onmessage = (event) => {
console.log("WebSocket:重连中..."); const data = event.data;
socketReconnectLock = false; if (data === 'pong') {
// websocket启动 // 重新开启心跳定时
initWebSocket(url); this.heartbeatCheck.reset();
}, 4000); } else {
} // 其他消息转发出去
const closeWebSocket = () => { console.log("收到消息:", data);
socketLeaveFlag = true this.onMessageCallback && this.onMessageCallback(JSON.parse(data));
if (socket) { }
console.log('断开连接'); };
socket.close(); this.webSocketInstance.onclose = (event) => {
console.log('WebSocket连接关闭');
this.isConnected = false;
this.onCloseCallback && this.onCloseCallback(event);
};
this.webSocketInstance.onopen = () => {
console.log("WebSocket连接成功");
this.isConnected = true;
this.heartbeatCheck.start();
};
// 连接发生错误的回调方法
this.webSocketInstance.onerror = () => {
console.log('WebSocket连接发生错误');
this.isConnected = false;
this.reconnect(url);
};
} catch (error) {
console.log("尝试创建连接失败");
this.reconnect(url);
}
}
// 定义重连函数
reconnect(url) {
console.log("尝试重新连接");
if (this.isConnected) {
return;
}
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
}
this.reconnectTimer = setTimeout(() => {
this.connect(url);
}, 15000);
}
// 设置关闭连接的方法
close(code) {
this.webSocketInstance && this.webSocketInstance.close(code);
}
// 发送消息的方法
sendMessage(messageData) {
if (this.webSocketInstance && this.webSocketInstance.readyState === WebSocket.OPEN) {
// 若是ws开启状态
this.webSocketInstance.send(messageData);
} else if (this.webSocketInstance && this.webSocketInstance.readyState === WebSocket.CONNECTING) {
setTimeout(() => {
this.sendMessage(messageData);
}, 1000);
} else {
setTimeout(() => {
this.sendMessage(messageData);
}, 1000);
}
}
// 设置连接成功回调函数的方法
onConnect(callback) {
this.onConnectCallback = callback;
}
// 设置收到消息回调函数的方法
onMessage(callback) {
this.onMessageCallback = callback;
}
// 设置连接关闭回调函数的方法
onClose(callback) {
this.onCloseCallback = callback;
} }
} }
//具体问题具体分析,把需要用到的方法暴露出去
export default { closeWebSocket, socket, initWebSocket,sendMessage }; const webSocketManager = new WebSocketManager();
export default webSocketManager;

View File

@ -24,9 +24,9 @@
</template> </template>
<script> <script>
import {getAuthorChatList} from "@/api/business/chat/chat"; import {getAuthorChatList,getAuthorChat} from "@/api/business/chat/chat";
import {isNotEmpty} from "@/utils"; import {isNotEmpty} from "@/utils";
import Websocket from "@/api/websocket.js"; import webSocketManager from "@/api/websocket.js";
export default { export default {
name: "Im", name: "Im",
@ -37,13 +37,37 @@
return { return {
dialogVisible: false, dialogVisible: false,
temp:{}, temp:{},
page:1,
user:{id:8,displayName:'官方客服-薯队长',avatar:'http://8.146.211.120:8080/upload/avatar/kefu.jpg'}, user:{id:8,displayName:'官方客服-薯队长',avatar:'http://8.146.211.120:8080/upload/avatar/kefu.jpg'},
} }
}, },
mounted(){ mounted(){
Websocket.initWebSocket('ws://192.168.1.136:9326/?authorId=8').then(response=>{ webSocketManager.connect('ws://192.168.10.98:9326/?authorId=8')
console.log(response.onmessage = this.handleMessage)
}) //
webSocketManager.onMessage((data) => {
if(data.handlerType == '6'){
console.log('mounted')
console.log(JSON.stringify(data.body))
const {IMUI} = this.$refs;
IMUI.appendMessage({
"content": "1",
"fromUser": {
"avatar": "http://8.146.211.120:8080/upload/avatar/avatar (3).jpg",
"displayName": "复古喵星人15",
"id": "8"
},
"handlerType": 0,
"id": "c4d344c83fe0e86e23b7508b73e0b5ef",
"sendTime": 1736439914000,
"status": "succeed",
"toContactId": "8",
"type": "text"
});
}
});
}, },
methods: { methods: {
@ -56,7 +80,7 @@
this.getAuthorList() this.getAuthorList()
}, },
getAuthorList(){ getAuthorList(){
getAuthorChatList().then(response=> { getAuthorChatList({authorId:8}).then(response=> {
this.$nextTick(() => { this.$nextTick(() => {
const {IMUI} = this.$refs; const {IMUI} = this.$refs;
const authorList = response.data; const authorList = response.data;
@ -91,26 +115,19 @@
handleSend(message, next, file) { handleSend(message, next, file) {
console.log('发送了信息') console.log('发送了信息')
message.handlerType = '6' message.handlerType = '6'
Websocket.sendMessage(JSON.stringify(message)) webSocketManager.sendMessage(JSON.stringify(message))
//next next({status:'failed'}); //next next({status:'failed'});
next(); next();
}, },
handlePullMessages(contact, next) { handlePullMessages(contact, next) {
console.log('拉取信息') console.log(contact)
// getAuthorChat({authorId:8,fromId:contact.id,limit:6,page:this.page}).then(res=> {
const messages = [{ console.log(res.data.records)
id: '唯一消息ID', next(res.data.records.reverse(),true);
status: 'succeed', })
type: 'text',
sendTime: 1566047865417,
content: '你什么才能对接完?',
toContactId: contact.id,
fromUser:this.user
}]
//true //true
next(messages,true);
}, },
}, },
} }