|
|
|
@ -1,18 +1,18 @@
|
|
|
|
|
import { login } from '@/api/chat';
|
|
|
|
|
import config from '@/configs';
|
|
|
|
|
import { ElMessage } from '@/plugins/element-plus';
|
|
|
|
|
import { UUID } from '@/utils/chat';
|
|
|
|
|
/*
|
|
|
|
|
* @Author: ch
|
|
|
|
|
* @Date: 2022-06-07 15:41:05
|
|
|
|
|
* @LastEditors: ch
|
|
|
|
|
* @LastEditTime: 2022-06-13 17:16:27
|
|
|
|
|
* @Description: file content
|
|
|
|
|
*/
|
|
|
|
|
import * as api from '@/api/chat';
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
const state = () => ({
|
|
|
|
|
socket: null,
|
|
|
|
|
heart: null,
|
|
|
|
|
queue: [],
|
|
|
|
|
task: [],
|
|
|
|
|
sessionData: {},
|
|
|
|
|
currentSession: null,
|
|
|
|
|
messageList: [],
|
|
|
|
|
messageType: { 1: 'text', 2: 'audio', 3: 'image', 4: 'video', 5: 'revoke', 6: 'custom', 7: 'notify' },
|
|
|
|
|
const state = {
|
|
|
|
|
curCustomerService: {},
|
|
|
|
|
sessionData: [],
|
|
|
|
|
customerServiceList: [],
|
|
|
|
|
messageType: { 1: 'text', 2: 'audio', 3: 'image', 4: 'video', 5: 'revoke', 6: 'custom', 7: 'notify' },
|
|
|
|
|
|
|
|
|
|
opts: {
|
|
|
|
|
customerServiceType: [
|
|
|
|
|
{
|
|
|
|
@ -29,7 +29,8 @@ const state = () => ({
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getters = {
|
|
|
|
|
parseTime: () => {
|
|
|
|
|
return (timestamp) => {
|
|
|
|
@ -48,7 +49,7 @@ const getters = {
|
|
|
|
|
payload = '[撤回消息]';
|
|
|
|
|
} else if (type === 6 || type === 1) {
|
|
|
|
|
try {
|
|
|
|
|
payload = JSON.parse(payload);
|
|
|
|
|
// payload = JSON.parse(payload.value);
|
|
|
|
|
if ('text' in payload) {
|
|
|
|
|
payload = payload.text;
|
|
|
|
|
} else if ('linkJump' in payload) {
|
|
|
|
@ -64,7 +65,7 @@ const getters = {
|
|
|
|
|
payload = '[解析异常]';
|
|
|
|
|
}
|
|
|
|
|
} else if (type === 7) {
|
|
|
|
|
payload = '[撤回消息]';
|
|
|
|
|
payload = payload.text;
|
|
|
|
|
} else {
|
|
|
|
|
payload = '[未知类型]';
|
|
|
|
|
}
|
|
|
|
@ -74,7 +75,7 @@ const getters = {
|
|
|
|
|
parseImage: () => {
|
|
|
|
|
return (payload) => {
|
|
|
|
|
try {
|
|
|
|
|
payload = JSON.parse(payload);
|
|
|
|
|
// payload = JSON.parse(payload);
|
|
|
|
|
if ('url' in payload) {
|
|
|
|
|
payload = payload.url;
|
|
|
|
|
} else {
|
|
|
|
@ -89,7 +90,7 @@ const getters = {
|
|
|
|
|
parseVideo: () => {
|
|
|
|
|
return (payload) => {
|
|
|
|
|
try {
|
|
|
|
|
payload = JSON.parse(payload);
|
|
|
|
|
// payload = JSON.parse(payload);
|
|
|
|
|
if ('url' in payload) {
|
|
|
|
|
payload = payload.url;
|
|
|
|
|
} else {
|
|
|
|
@ -104,7 +105,7 @@ const getters = {
|
|
|
|
|
parseContent: () => {
|
|
|
|
|
return (payload) => {
|
|
|
|
|
try {
|
|
|
|
|
payload = JSON.parse(payload);
|
|
|
|
|
// payload = JSON.parse(payload);
|
|
|
|
|
if ('linkJump' in payload) {
|
|
|
|
|
payload.type = 'link';
|
|
|
|
|
} else if ('orderNo' in payload) {
|
|
|
|
@ -122,223 +123,45 @@ const getters = {
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
const mutations = {
|
|
|
|
|
setSocket: (state, data) => (state.socket = data),
|
|
|
|
|
setHeart: (state, data) => (state.heart = data),
|
|
|
|
|
setTask: (state, data) => (state.task = data),
|
|
|
|
|
addTask: (state, data) => state.task.push(data),
|
|
|
|
|
delTask: (state, data) => state.task.splice(data, 1),
|
|
|
|
|
setCurrentSession: (state, data) => (state.currentSession = data),
|
|
|
|
|
setSessionData: (state, data) => (state.sessionData = data),
|
|
|
|
|
setMessageList: (state, data) => (state.messageList = data),
|
|
|
|
|
setCustomerServiceList: (state, data) => (state.customerServiceList = data),
|
|
|
|
|
};
|
|
|
|
|
const actions = {
|
|
|
|
|
/**
|
|
|
|
|
* 创建连接
|
|
|
|
|
*/
|
|
|
|
|
connect: async ({ state, commit, dispatch }) => {
|
|
|
|
|
let { ticket } = await login({ storeId: 1 });
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
if (window.WebSocket) {
|
|
|
|
|
const socket = new WebSocket(`${config.socketURL}?client=${ticket}&type=2`);
|
|
|
|
|
socket.onmessage = ({ data }) => {
|
|
|
|
|
dispatch('receive', data);
|
|
|
|
|
};
|
|
|
|
|
socket.onopen = () => {
|
|
|
|
|
commit(
|
|
|
|
|
'setHeart',
|
|
|
|
|
setInterval(() => {
|
|
|
|
|
dispatch('heart');
|
|
|
|
|
}, 3000)
|
|
|
|
|
);
|
|
|
|
|
console.info('[chat] open');
|
|
|
|
|
resolve(socket);
|
|
|
|
|
};
|
|
|
|
|
socket.onclose = () => {
|
|
|
|
|
clearInterval(state.heart);
|
|
|
|
|
console.info('[chat] close');
|
|
|
|
|
};
|
|
|
|
|
socket.onerror = (e) => {
|
|
|
|
|
clearInterval(state.heart);
|
|
|
|
|
console.info('[chat] error', e);
|
|
|
|
|
reject(e);
|
|
|
|
|
};
|
|
|
|
|
commit('setSocket', socket);
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage.error('当前浏览器不支持 WebSocket');
|
|
|
|
|
reject('not support websocket');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 发送心跳,任务监测
|
|
|
|
|
*/
|
|
|
|
|
heart: ({ state, dispatch }) => {
|
|
|
|
|
dispatch('send', {
|
|
|
|
|
traceType: 26,
|
|
|
|
|
content: { storeId: 1 },
|
|
|
|
|
});
|
|
|
|
|
// console.info('[chat] heart');
|
|
|
|
|
state.task.forEach((item) => {
|
|
|
|
|
dispatch('send', item);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 执行任务
|
|
|
|
|
*/
|
|
|
|
|
invoke: ({ commit, dispatch }, data) => {
|
|
|
|
|
data.traceId = UUID();
|
|
|
|
|
commit('addTask', data);
|
|
|
|
|
dispatch('send', data);
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 撤销任务
|
|
|
|
|
*/
|
|
|
|
|
revoke: ({ state, commit }, data) => {
|
|
|
|
|
console.info(state.task.length);
|
|
|
|
|
commit(
|
|
|
|
|
'setTask',
|
|
|
|
|
state.task.filter((item) => item.traceType !== data)
|
|
|
|
|
);
|
|
|
|
|
console.info(state.task.length);
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 发送数据
|
|
|
|
|
*/
|
|
|
|
|
send: ({ state }, data) => {
|
|
|
|
|
if (window.WebSocket) {
|
|
|
|
|
if (state.socket?.readyState === WebSocket.OPEN) {
|
|
|
|
|
data.traceId = data.traceId || UUID();
|
|
|
|
|
state.socket.send(JSON.stringify(data));
|
|
|
|
|
if (data.traceType !== 26) {
|
|
|
|
|
console.info('[chat] send', data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SET_CUR_SERVICE(state, data) {
|
|
|
|
|
state.curCustomerService = data || {};
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 接收数据
|
|
|
|
|
*/
|
|
|
|
|
receive: ({ state, commit, dispatch }, data) => {
|
|
|
|
|
data = JSON.parse(data);
|
|
|
|
|
if (data.traceType !== 0) {
|
|
|
|
|
let index = state.task.findIndex((item) => item.traceId === data.traceId);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
console.info('[chat] data', data);
|
|
|
|
|
commit('delTask', index);
|
|
|
|
|
dispatch('handle', data);
|
|
|
|
|
} else if (data.traceType === 25) {
|
|
|
|
|
console.info('[chat] msg', data);
|
|
|
|
|
dispatch('handle', data);
|
|
|
|
|
} else {
|
|
|
|
|
console.info('[chat] deprecated', data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 处理数据
|
|
|
|
|
*/
|
|
|
|
|
handle: ({ state, commit, dispatch }, { code, traceType, content }) => {
|
|
|
|
|
if (code === 200) {
|
|
|
|
|
switch (traceType) {
|
|
|
|
|
case 25: // 收到消息
|
|
|
|
|
if (content.sessionId === state.currentSession) {
|
|
|
|
|
commit('setMessageList', [...state.messageList, content]);
|
|
|
|
|
dispatch('submitRead');
|
|
|
|
|
} else {
|
|
|
|
|
dispatch('querySession');
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 32: // 发送消息
|
|
|
|
|
commit('setMessageList', [...state.messageList, content]);
|
|
|
|
|
break;
|
|
|
|
|
case 27: // 会话列表
|
|
|
|
|
commit('setSessionData', content);
|
|
|
|
|
break;
|
|
|
|
|
case 28: // 消息列表
|
|
|
|
|
commit('setMessageList', [...content, ...state.messageList]);
|
|
|
|
|
break;
|
|
|
|
|
case 29: // 客服列表
|
|
|
|
|
commit('setCustomerServiceList', content);
|
|
|
|
|
break;
|
|
|
|
|
case 31: // 已读消息
|
|
|
|
|
dispatch('querySession');
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SET_SESSION_DATA(state, data) {
|
|
|
|
|
state.sessionData = data;
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 查询会话列表
|
|
|
|
|
*/
|
|
|
|
|
querySession: ({ dispatch }) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 27,
|
|
|
|
|
content: { storeId: 1 },
|
|
|
|
|
});
|
|
|
|
|
SET_SERVICE_LIST(state, data) {
|
|
|
|
|
state.customerServiceList = data;
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 查询会话消息列表
|
|
|
|
|
*/
|
|
|
|
|
querySessionMessage: ({ state, dispatch }, data) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 28,
|
|
|
|
|
content: { sessionId: state.currentSession, size: 10, topMessageId: null, ...data },
|
|
|
|
|
};
|
|
|
|
|
const actions = {
|
|
|
|
|
queryCurCustomerService: ({ commit }) => {
|
|
|
|
|
api.getCustomerService().then((res) => {
|
|
|
|
|
commit('SET_CUR_SERVICE', res);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询可转移客服列表
|
|
|
|
|
*/
|
|
|
|
|
queryCustomerService: ({ dispatch }) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 29,
|
|
|
|
|
content: { storeId: 1 },
|
|
|
|
|
queryCustomerService: ({ commit }) => {
|
|
|
|
|
api.customerServiceList({
|
|
|
|
|
length: 100,
|
|
|
|
|
pageIndex: 1,
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
commit('SET_SERVICE_LIST', res.records);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 提交转移会话
|
|
|
|
|
*/
|
|
|
|
|
submitTransferSession: ({ dispatch }, data) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 30,
|
|
|
|
|
content: { storeId: 1, ...data },
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 提交已读消息
|
|
|
|
|
*/
|
|
|
|
|
submitRead: ({ state, dispatch }) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 31,
|
|
|
|
|
content: { sessionId: state.currentSession },
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 提交发送消息
|
|
|
|
|
*/
|
|
|
|
|
submitMessage: ({ state, dispatch }, payload) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 32,
|
|
|
|
|
content: { payload, toSessionId: state.currentSession, type: 1 },
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 提交发送图片
|
|
|
|
|
*/
|
|
|
|
|
submitImage: ({ state, dispatch }, payload) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 32,
|
|
|
|
|
content: { payload, toSessionId: state.currentSession, type: 3 },
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 提交发送视频
|
|
|
|
|
*/
|
|
|
|
|
submitVideo: ({ state, dispatch }, payload) => {
|
|
|
|
|
dispatch('invoke', {
|
|
|
|
|
traceType: 32,
|
|
|
|
|
content: { payload, toSessionId: state.currentSession, type: 4 },
|
|
|
|
|
submitTransferSession: ({}, data) => {
|
|
|
|
|
return api
|
|
|
|
|
.transferCustomerService({
|
|
|
|
|
storeId: 1,
|
|
|
|
|
...data,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
console.log(res, 'resresres');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|