diff --git a/common/api/im.js b/common/api/im.js new file mode 100644 index 0000000..1d31ccb --- /dev/null +++ b/common/api/im.js @@ -0,0 +1,48 @@ +// /* +// * @Author: ch +// * @Date: 2022-05-18 15:21:10 +// * @LastEditors: ch +// * @LastEditTime: 2022-05-18 17:24:37 +// * @Description: file content +// */ +// import { MsbSkt } from "../utils/webSkt"; +// import { createUUID } from '@/common/utils'; + +// /** +// * 系统消息心跳 +// */ +// export const ApiSktSysHeart = () => MsbSkt.send({ +// traceId: createUUID(), +// traceType: '0', +// content: { text: "ping" } +// }); + +// /** +// * 获取系统通知会话 +// * @param {*} content +// */ +// export const ApiSktSysGetSession = (content) => MsbSkt.send({ +// traceId: createUUID(), +// traceType: '1', +// content +// }); + +// /** +// * 获取系统消息历史消息 +// * @param {*} content +// */ +// export const ApiSktSysGetHistory = (content) => MsbSkt.send({ +// traceId: createUUID(), +// traceType: '2', +// content +// }); + +// /** +// * 系统消息已读 +// * @param {*} content +// */ +// export const ApiSktSysGetHistory = (content) => MsbSkt.send({ +// traceId: createUUID(), +// traceType: '6', +// content +// }); \ No newline at end of file diff --git a/common/dicts/im.js b/common/dicts/im.js index 23505d3..c7fdf3a 100644 --- a/common/dicts/im.js +++ b/common/dicts/im.js @@ -2,7 +2,7 @@ * @Author: ch * @Date: 2022-05-10 20:50:54 * @LastEditors: ch - * @LastEditTime: 2022-05-13 14:28:29 + * @LastEditTime: 2022-05-18 14:45:49 * @Description: file content */ @@ -20,16 +20,36 @@ const MSG_TYPE = { // 提示消息 TIP : 7 } -const TYPE = { +// 系统会话类型 +const SYS_IO = { + // 连接心跳 + HEART: 0, + // 获取会话列表 + GET_SESSION_LIST: 1, + // 查询会话消息 + GET_SESSION_MSG: 2, + // 发送消息 + SEND_MSG: 3, + // 根据消息ID查询消息 + GET_ID_MSG: 4, + + + + + + +} +const KF_IO = { + // 会话心跳 + HEART: 22, // 给某个会话发送消息 SEND_MSG: 20, // 创建会话 CRETAE_SEEION: 21, - // 会话心跳 - SESSION_HEART : 22 - } export { // 消息类型 - MSG_TYPE + MSG_TYPE, + SYS_IO, + KF_IO } \ No newline at end of file diff --git a/common/plugins/webSkt.js b/common/plugins/webSkt.js new file mode 100644 index 0000000..bcd0d6d --- /dev/null +++ b/common/plugins/webSkt.js @@ -0,0 +1,95 @@ +/* + * @Author: ch + * @Date: 2022-05-18 14:54:47 + * @LastEditors: ch + * @LastEditTime: 2022-05-19 15:42:19 + * @Description: file content + */ + +export class MsbWebSktNew{ + constructor(option) { + this.option = { + ioKey : 'traceId', + reconnect: true, + ...option + } + this.socket = null; + this.queue = {}; + this.hook = {}; + + this.data = []; + this.count = 0; + this.curSession = {}; + } + /** + * 创建连接返回一个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.hook.onMessage && this.hook.onMessage(result); + + // 查看是否有返回信息处理Hook,有的话优先取处理后的结果返回 + const responseData = this.hook.onResponse ? this.hook.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.hook.onResponse) { + reject(this.hook.onResponse(e)) + } + reject(e); + } + }); + }) + } + /** + * 扩展钩子 + * @param {*} hookName + * @param {*} cb + */ + use(hookName, cb){ + this.hook[hookName] = cb; + } + + +} \ No newline at end of file diff --git a/common/utils/requset.js b/common/utils/requset.js index 6e73d71..ddc24b1 100644 --- a/common/utils/requset.js +++ b/common/utils/requset.js @@ -2,14 +2,14 @@ * @Author: ch * @Date: 2022-03-17 17:42:32 * @LastEditors: ch - * @LastEditTime: 2022-05-17 18:15:04 + * @LastEditTime: 2022-05-18 16:41:46 * @Description: 项目接口请求统一处理器,返回一个需要token和不需要token的请求封装方法 */ import MsbUniRequest from '@/common/plugins/msbUniRequest'; import $store from '@/common/store'; -const ENV = 'prod'; +const ENV = 'test'; const BASE_URL = { 'test' : 'https://k8s-horse-gateway.mashibing.cn', 'dev' : '', diff --git a/common/utils/webSkt.js b/common/utils/webSkt.js new file mode 100644 index 0000000..f0f43d9 --- /dev/null +++ b/common/utils/webSkt.js @@ -0,0 +1,184 @@ +/* + * @Author: ch + * @Date: 2022-05-18 15:27:02 + * @LastEditors: ch + * @LastEditTime: 2022-05-19 15:50:12 + * @Description: file content + */ + +import { MsbWebSktNew } from "../plugins/webSkt"; +import { createUUID, formatDate } from '@/common/utils'; +import store from "../store"; + +const MsbSkt = new MsbWebSktNew(); +MsbSkt.use('onResponse', (data) => { + if (data.code !== 500) { + return data; + } + return Promise.reject(data); + +}) +MsbSkt.use('onMessage', (data) => { + // 判断非服务端主动推送消息不做处理 + if (data[MsbSkt.option.ioKey]) { + return false; + } + ctx = data.content; + ctx.payload = JSON.parse(ctx.payload || {}); + ctx.createTimeStamp = formatDate(ctx.createTimeStamp || new Date(), 'mm-dd hh:ii') + let historyData = MsbSkt.data; + const hisIndex = historyData.findIndex(i => i.id === ctx.sessionId); + // 不在当前会话框则全局消息加1 + // if(ctx.sessionId !== store.state.sessionMsgId){ + // store.commit('SET_SESSION_MSG_COUNT', store.state.sessionMsgCount + 1); + // } + if(hisIndex >= 0){ + // 存在会话往现有会话增加一条消息 + const curHisData = historyData[hisIndex]; + curHisData.messageList.push(ctx); //= [ ctx, ...(curHisData.messageList || [])] + // 不在当前会话框则会话框消息加1 + // if(ctx.sessionId !== store.state.sessionMsgId){ + // curHisData.unreadCount++; + // } + MsbSkt.data = historyData; + }else{ + // 会话列表不存在,则创建一个会话 + MsbSkt.data = [...historyData, { + fromAvatar : ctx.fromAvatar, + fromId : ctx.fromId, + fromNickname : ctx.fromNickname, + id : ctx.id, + lastMessage : ctx, + messageList : [ctx], + unreadCount : 1 + }] + } + store.commit('SET_SESSION_DATA',MsbSkt.data); + +}); +/** + * 初始化IM + */ +export const MsbSktInit = () => { + return new Promise((resolve, reject) => { + const heart = () => { + setTimeout(async () => { + await MsbSkt.send({ + traceId: createUUID(), + traceType: '0', + content: { text: "ping" } + }); + heart(); + },5000) + } + MsbSkt.connect({ + // 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(MsbSkt); + }); + }) + +} +/** + * 获取会话列表 + * @param {*} params + */ +export const MsbSktGetSessionList = async (params) => { + let {content} = await MsbSkt.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 = MsbSkt.data; + let hisIndex = historyData.findIndex(i => i.id === item.id); + if(hisIndex >= 0){ + historyData[hisIndex].lastMessage = item.lastMessage; + historyData[hisIndex].unreadCount++; + MsbSkt.data = historyData + }else{ + item.messageList = []; + MsbSkt.data = [...historyData, item]; + } + }); +} +/** + * 获取历史消息 + */ +export const MsbSktGetHistoryMsg = async (params) => { + let { content } = await MsbSkt.send({ + traceId: createUUID(), + traceType : 23, + ...params + }) + if(!content.length){ + return false; + } + // ctx.reverse(); + let newData = MsbSkt.data; + 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); + MsbSkt.data = newData; + store.commit('SET_SESSION_DATA', newData); + return Promise.resolve(content); + +} +/** + * 设置为已读 + */ +export const MsbSktSetRead = async (params) => { + await MsbSkt.send({ + traceId : createUUID(), + traceType : "6", + ...params + }); + // 计算页头消息数 + MsbSkt.curSession.unreadCount = 0; + +} +/** + * 发送消息 + */ +export const MsbSktSendMsg = async (params) => { + const { content } = await MsbSkt.send({ + traceId: createUUID(), + traceType: 20, + ...params + }); + return Promise.resolve(content) +} +/** + * 主动创建会话 + */ +export const MsbSktCreateSession = async (params) => { + const { content } = await MsbSkt.send({ + traceId : createUUID(), + traceType : 21, + ...params + }); + let historyData = MsbSkt.data; + let curSession = historyData.find(i => i.id === content.id); + if (!curSession) { + curSession = { + ...content, + unreadCount: 0, + messageList : [] + } + MsbSkt.data = [...historyData, curSession]; + } + MsbSkt.curSession = curSession; + store.commit('SET_SESSION_DATA',MsbSkt.data); + store.commit('SET_SESSION_MSG_ID',curSession.id); + return Promise.resolve(content); +} + diff --git a/common/utils/websocket.js b/common/utils/websocket.js index bf7e847..a1024b9 100644 --- a/common/utils/websocket.js +++ b/common/utils/websocket.js @@ -2,7 +2,7 @@ * @Author: ch * @Date: 2022-04-25 14:39:19 * @LastEditors: ch - * @LastEditTime: 2022-05-17 18:14:57 + * @LastEditTime: 2022-05-18 16:29:56 * @Description: file content */ import store from "../store"; @@ -104,6 +104,7 @@ const createSessionMain = (ctx) => { } export let MsbWebSkt = null; const token = 'eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjQwNzA4ODAwMDAsImlkIjo5LCJ0aW1lIjoxNjUyNTAwMDUyNTgwfQ.VAMmJTU1FAcw-vD39E_7EHoDaEdKD3A53L-kdcF6Hj_ygs1urs7xfTNsE2Z_Tb5wXRkS_j-qm0pGnRgfD2EQebc8Pcd28-Rp2W8o-CmCw2_uZUZbfUGeFRZ_ihsFCCpsepU7uEkA9L--cI_u3jw9xdNqzkiXYAVeAXsJ2j570bk' + export const MsbWebSktInit = () => { return new Promise((resolve, reject) => { MsbWebSkt = uni.connectSocket({ diff --git a/main.js b/main.js index b5b4c00..b4fb30e 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ * @Author: ch * @Date: 2021-07-26 23:22:16 * @LastEditors: ch - * @LastEditTime: 2022-05-16 09:46:02 + * @LastEditTime: 2022-05-19 10:45:53 * @Description: file content */ import Vue from 'vue'; @@ -16,29 +16,16 @@ import route from 'uview-ui/libs/util/route'; import {toSearchJson} from '@/common/utils'; import {ApiGetOpenId, ApiGetAuthUrl} from '@/common/api/wx'; import {MsbWebSkt, MsbWebSktInit, createUUID} from '@/common/utils'; +import { MsbSktInit, MsbSktGetSessionList} from './common/utils/webSkt'; +import { ApiSktSysGetSession, ApiSktSysHeart } from './common/api/im'; -if(store.state.token){ -// 进入应用则向IM发起心跳包 以及获取IM会话数据 - MsbWebSktInit().then(()=>{ - MsbWebSkt.send({ - data : JSON.stringify({ - traceId : createUUID(), - traceType : "1", - content: { sysId : "1"} - }) +if (store.state.token) { + MsbSktInit().then(() => { + MsbSktGetSessionList({ + traceType : 1, + content: { sysId : 1} }); - - setInterval(()=>{ - MsbWebSkt.send({ - data : JSON.stringify({ - traceId : createUUID(), - traceType : "0", - content: { text : "ping"} - }) - }) - - }, 5000); - }) + }); }