You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
shop-app/common/plugins/msbIm.js

238 lines
6.4 KiB

/*
* @Author: ch
* @Date: 2022-05-18 14:54:47
* @LastEditors: ch
* @LastEditTime: 2022-05-20 11:25:57
* @Description: file content
*/
const connect = Symbol('connect'),
send = Symbol('send');
export default class MsbIm {
option = {
ioKey : 'traceId',
reconnect: true,
}
socket = null;
queue = {};
interceptors = {
dataChangeBefore: null,
dataChangeAfter: null,
onMessage: null,
onResponse: null
};
sessionData = [];
curSession = {};
constructor(option) {
this.option = {
...this.option,
...option
}
}
/**
* 创建连接返回一个Promise 创建成功并成功打开连接算连接成功
* @param {*} option
*/
[connect](option) {
return new Promise((resolve, reject) => {
this.socket = uni.connectSocket({
...option,
fail(e){
reject(e);
}
});
this.socket.onOpen(() => {
this.socket.onMessage((res) => {
const result = JSON.parse(res.data);
// 每次消息推送都会推送至onMessage Hook中
this.interceptors.onMessage && this.interceptors.onMessage(result);
// 查看是否有返回信息处理Hook有的话优先取处理后的结果返回
const responseData = this.interceptors.onResponse ? this.interceptors.onResponse(result) : result;
const isError = responseData.constructor === Promise;
// 如果再消息堆里有此消息回调,则执行回调,并删除
const cbk = this.queue[result[this.option.ioKey]];
if (cbk) {
cbk(isError ? {error:responseData} : {result:responseData});
delete this.queue[result[this.option.ioKey]];
}
})
resolve(this.socket);
});
this.socket.onClose(() => {
if (this.option.reconnect) {
this.connect();
}
});
});
}
/**
* 向服务端发送消息||请求返回一个Promise对象收到ioKey对应的消息会算一个同步完成
* @param {*} data
*/
[send](data) {
return new Promise((resolve, reject) => {
this.queue[data[this.option.ioKey]] = ({ result, error }) => {
if (result) {
resolve(result);
} else {
reject(error);
}
};
this.socket.send({
data : JSON.stringify(data),
fail(e) {
if (this.interceptors.onResponse) {
reject(this.interceptors.onResponse(e))
}
reject(e);
}
});
})
}
/**
* 扩展钩子
* @param {*} hookName
* @param {*} cb
*/
use(hookName, cb){
this.hook[hookName] = cb;
}
init (config) {
return new Promise((resolve, reject) => {
const heart = () => {
setTimeout(async () => {
await this[send]({
traceId: CreateUUID(),
traceType: '0',
content: { text: "ping" }
});
heart();
},5000)
}
this[connect]({
...config,
// url : `wss://you-gateway.mashibing.com/ws?client=${store.state.token}&type=1`
// url : `wss://k8s-horse-gateway.mashibing.cn/ws?client=${store.state.token}&type=1`, // url是websocket连接ip
}).then(() => {
heart();
resolve(this);
});
})
}
/**
* 设置
*/
setSessionData(data) {
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(data, this.sessionData);
this.sessionData = data;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
},
/**
* 设置当前聊天窗口
* Data为Session数据
* @param {*} data
*/
setCurSession(data) {
this.curSession = data;
}
async getSessionList (params) {
let {content} = await this[send]({
traceId: CreateUUID(),
...params
});
content.sessionVOS.forEach(item => {
if (item.lastMessage) {
item.lastMessage.createTimeStamp = FormatDate(item.lastMessage.createTimeStamp, 'mm-dd hh:ii')
item.lastMessage.payload = JSON.parse(item.lastMessage.payload || {});
}
let historyData = this.sessionData;
let hisIndex = historyData.findIndex(i => i.id === item.id);
if(hisIndex >= 0){
historyData[hisIndex].lastMessage = item.lastMessage;
historyData[hisIndex].unreadCount++;
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(historyData, this.sessionData);
this.sessionData = historyData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}else{
item.messageList = [];
const newData = [...historyData, item]
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
this.sessionData = newData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}
});
}
async getHistoryMsg (params){
let { content } = await this[send]({
traceId: CreateUUID(),
traceType : 23,
...params
})
if(!content.length){
return false;
}
// ctx.reverse();
let newData = this.sessionData;
const hisIdx = newData.findIndex(i => i.id === content[0].sessionId);
content.forEach(item => {
item.createTimeStamp = FormatDate(item.createTimeStamp, 'mm-dd hh:ii');
item.payload = JSON.parse(item.payload)
})
newData[hisIdx].messageList = newData[hisIdx].messageList.concat(content);
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
this.sessionData = newData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
return Promise.resolve(content);
}
async setRead (params){
await this[send]({
traceId : CreateUUID(),
traceType : "6",
...params
});
// 计算页头消息数
this.curSession.unreadCount = 0;
}
async sendMsg (params){
const { content } = await this[send]({
traceId: CreateUUID(),
traceType: 20,
...params
});
return Promise.resolve(content)
}
async createSession (params){
const { content } = await this[send]({
traceId : CreateUUID(),
traceType : 21,
...params
});
let historyData = this.sessionData;
let curSession = historyData.find(i => i.id === content.id);
if (!curSession) {
curSession = {
...content,
unreadCount: 0,
messageList : []
}
const newData = [...historyData, curSession];
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
this.sessionData = newData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}
this.curSession = curSession;
// store.commit('SET_SESSION_DATA',this.sessionData);
// store.commit('SET_SESSION_MSG_ID',curSession.id);
return Promise.resolve(content);
}
}