17 changed files with 365 additions and 287 deletions
@ -0,0 +1,21 @@ |
|||||
|
var config = { |
||||
|
baseUrl: 'https://test.tall.wiki', |
||||
|
apiUrl: 'https://test.tall.wiki/gateway', |
||||
|
msgUrl: 'wss://test.tall.wiki/websocket/message/v4.0/ws'; |
||||
|
projectPath: 'https://test.tall.wiki/tall-project', |
||||
|
|
||||
|
// baseUrl: 'https://www.tall.wiki',
|
||||
|
// apiUrl: 'https://www.tall.wiki/gateway',
|
||||
|
// msgUrl: 'wss://www.tall.wiki/websocket/message/v4.0/ws';
|
||||
|
// projectPath: 'https://www.tall.wiki/tall-project',
|
||||
|
|
||||
|
version: 'v4.0.0' |
||||
|
|
||||
|
VUE_APP_BASE_URL= |
||||
|
VUE_APP_API_URL= |
||||
|
VUE_APP_MSG_URL= |
||||
|
VUE_APP_PROJECT_PATH= |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
export default config; |
@ -1,60 +0,0 @@ |
|||||
const install = (Vue, vm) => { |
|
||||
Vue.prototype.$u.http.setConfig({ |
|
||||
baseUrl: '', |
|
||||
showLoading: true, // 是否显示请求中的loading
|
|
||||
loadingText: '玩命加载中...', |
|
||||
loadingTime: 800, |
|
||||
loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
|
||||
// 配置请求头信息
|
|
||||
header: { |
|
||||
'content-type': 'application/json;charset=UTF-8' |
|
||||
}, |
|
||||
}); |
|
||||
|
|
||||
// 请求拦截部分,如配置,每次请求前都会执行
|
|
||||
Vue.prototype.$u.http.interceptor.request = config => { |
|
||||
const token = vm.$store.state.user.token || uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); |
|
||||
if (token) { |
|
||||
config.header.Authorization = `Bearer ${token}`; |
|
||||
} |
|
||||
|
|
||||
return config; |
|
||||
}; |
|
||||
|
|
||||
// 响应拦截,如配置,每次请求结束都会执行本方法
|
|
||||
Vue.prototype.$u.http.interceptor.response = res => { |
|
||||
if (res.code === 200) { |
|
||||
// res为服务端返回值,可能有code,result等字段
|
|
||||
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
|
|
||||
// 如果配置了originalData为true,请留意这里的返回值
|
|
||||
return res.data; |
|
||||
} else if (res.code === 401) { |
|
||||
// 假设201为token失效,这里跳转登录
|
|
||||
vm.$u.toast('验证失败,请重新登录'); |
|
||||
setTimeout(() => { |
|
||||
// 此为uView的方法,详见路由相关文档
|
|
||||
vm.$u.route('/pages/user/login'); |
|
||||
}, 1500); |
|
||||
return false; |
|
||||
} else { |
|
||||
// 如果返回false,则会调用Promise的reject回调,
|
|
||||
// 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值
|
|
||||
return false; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
Vue.prototype.$u.post = (url, param = {}, header = {}) => { |
|
||||
return Vue.prototype.$u.http.request({ |
|
||||
url, |
|
||||
method: 'POST', |
|
||||
header, |
|
||||
data: { |
|
||||
param |
|
||||
}, |
|
||||
}); |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
export default { |
|
||||
install |
|
||||
}; |
|
@ -1,59 +0,0 @@ |
|||||
export default { |
|
||||
/** |
|
||||
* 显示toast |
|
||||
* @param {string} title 提示内容 |
|
||||
* @param {number} duration 显示时间 默认2000 |
|
||||
*/ |
|
||||
showToast(title, duration = 2000) { |
|
||||
return uni.showToast({ |
|
||||
title, |
|
||||
icon: 'none', |
|
||||
duration, |
|
||||
mask: true, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 隐藏toast
|
|
||||
hideToast() { |
|
||||
return uni.hideToast(); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 显示加载雪花 |
|
||||
* @param {string} title |
|
||||
*/ |
|
||||
showLoading(title = '玩命加载中...') { |
|
||||
return uni.showLoading({ |
|
||||
title, |
|
||||
mask: true, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 隐藏loading
|
|
||||
hideLoading() { |
|
||||
return uni.hideLoading(); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 显示modal弹出框 |
|
||||
* @param {string} title 标题 |
|
||||
* @param {string} content 内容 |
|
||||
* @param {boolean} showCancel 是否显示取消按钮 默认true |
|
||||
*/ |
|
||||
showModal(title, content, showCancel = true) { |
|
||||
return new Promise(function(resolve, reject) { |
|
||||
uni.showModal({ |
|
||||
title, |
|
||||
content, |
|
||||
showCancel, |
|
||||
success: ({ |
|
||||
confirm, |
|
||||
cancel |
|
||||
}) => { |
|
||||
confirm && resolve(); |
|
||||
cancel && reject(); |
|
||||
}, |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}; |
|
@ -0,0 +1,211 @@ |
|||||
|
const WS_BASE_URL = 'wss://test.tall.wiki/websocket/message/v4.0/ws'; // 测试
|
||||
|
// const WS_BASE_URL = 'wss://www.tall.wiki/websocket/message/v4.0/ws'; // 生产
|
||||
|
|
||||
|
let prevTime = 0; |
||||
|
let socketMsgQueue = []; // socket消息队列
|
||||
|
let sendHeartTimer = null; |
||||
|
|
||||
|
const actions = { |
||||
|
// 初始化socket
|
||||
|
initSocket({ commit, dispatch, state, rootState }) { |
||||
|
if (state.lockSocket) return; |
||||
|
const { |
||||
|
token |
||||
|
} = rootState.user; |
||||
|
if (!token) return; |
||||
|
commit('setLockSocket', true); |
||||
|
commit('setSocket', uni.connectSocket({ |
||||
|
url: WS_BASE_URL, |
||||
|
complete: () => {} |
||||
|
})); |
||||
|
dispatch('onSocketOpen'); |
||||
|
dispatch('onSocketMessage'); |
||||
|
dispatch('onSocketClose'); |
||||
|
state.socket.onError(errMsg => console.error(errMsg)); |
||||
|
commit('setLockSocket', false); |
||||
|
}, |
||||
|
|
||||
|
// 监听ws打开
|
||||
|
onSocketOpen({ |
||||
|
dispatch, |
||||
|
commit, |
||||
|
state |
||||
|
}) { |
||||
|
// eslint-disable-next-line no-unused-vars
|
||||
|
state.socket.onOpen(res => { |
||||
|
// console.log('ws open: ', res);
|
||||
|
commit('setConnected', true); |
||||
|
prevTime = Date.now(); |
||||
|
// this.auth();
|
||||
|
dispatch('auth'); |
||||
|
for (let i = 0; i < socketMsgQueue.length; i++) { |
||||
|
dispatch('sendSocketMessage', socketMsgQueue[i]); |
||||
|
} |
||||
|
socketMsgQueue = []; |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 监听收到的ws消息
|
||||
|
onSocketMessage({ |
||||
|
dispatch, |
||||
|
state |
||||
|
}) { |
||||
|
state.socket.onMessage(res => { |
||||
|
// console.log('收到消息:', res);
|
||||
|
prevTime = Date.now(); |
||||
|
if (!res || !res.data || !JSON.parse(res.data)) return; |
||||
|
const resData = JSON.parse(res.data); |
||||
|
const { |
||||
|
messageSet, |
||||
|
ackId |
||||
|
} = resData; |
||||
|
// 处理消息体对象
|
||||
|
messageSet.forEach(item => dispatch('handleMessagesData', item)); |
||||
|
ackId && dispatch('sendSocketMessage', { |
||||
|
type: 'Ack', |
||||
|
data: { |
||||
|
ackId |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 处理收到的消息内容 |
||||
|
* @param {object} item 单个消息体对象 |
||||
|
*/ |
||||
|
handleMessagesData({ |
||||
|
dispatch, |
||||
|
commit |
||||
|
}, item) { |
||||
|
const data = JSON.parse(item.data); |
||||
|
switch (data.type) { |
||||
|
case 'Sync': // 开始某个节点
|
||||
|
commit('messages/messagesAdd', { |
||||
|
message: data, |
||||
|
type: 'syncMessages' |
||||
|
}, { |
||||
|
root: true |
||||
|
}); |
||||
|
break; |
||||
|
case 'taskStatus': // 任务状态修改相关消息
|
||||
|
commit('task/setTaskStatus', data.data, { |
||||
|
root: true |
||||
|
}); |
||||
|
break; |
||||
|
// case 'Chrome': // !收到开始游戏的消息
|
||||
|
// console.log('handleMessagesData', data);
|
||||
|
// // @ts-ignore
|
||||
|
// util.openGameApp({
|
||||
|
// type: data.data.type,
|
||||
|
// projectId: data.data.projectId,
|
||||
|
// id: data.data.recordId,
|
||||
|
// token: rootState.user.token,
|
||||
|
// });
|
||||
|
// break;
|
||||
|
// case 'Deliver': // 交付物相关消息
|
||||
|
// commit('messages/messagesAdd', { type: 'checkMessages', message: data }, { root: true });
|
||||
|
// break;
|
||||
|
case 'ChannelStatus': |
||||
|
dispatch('handleAuthMessage', data); |
||||
|
break; |
||||
|
// case 'switchoverProject': // 康复相关消息
|
||||
|
// dispatch('home/getProjectById', data.data.projectId, { root: true });
|
||||
|
// break;
|
||||
|
// case 'startDrill': // 康复开始训练相关消息
|
||||
|
// console.log('setStartDrillInfo', data.data);
|
||||
|
// commit('home/setStartDrillMessages', data.data, { root: true });
|
||||
|
// break;
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 发送消息
|
||||
|
sendSocketMessage({ |
||||
|
state |
||||
|
}, data) { |
||||
|
if (state.connected) { |
||||
|
const msg = JSON.stringify({ |
||||
|
toDomain: 'Server', |
||||
|
data: JSON.stringify(data) |
||||
|
}); |
||||
|
state.socket.send({ |
||||
|
data: msg |
||||
|
}); |
||||
|
} else { |
||||
|
socketMsgQueue.push(data); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 监听关闭事件
|
||||
|
onSocketClose({ |
||||
|
dispatch, |
||||
|
commit, |
||||
|
state |
||||
|
}) { |
||||
|
// console.log('onSocketClose');
|
||||
|
state.socket.onClose(() => { |
||||
|
commit('setConnected', false); |
||||
|
if (sendHeartTimer) clearInterval(sendHeartTimer); |
||||
|
setTimeout(() => { |
||||
|
dispatch('initSocket'); |
||||
|
}, 300); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// websocket发送channelId进行认证
|
||||
|
auth({ |
||||
|
dispatch, |
||||
|
rootState |
||||
|
}) { |
||||
|
const { |
||||
|
token |
||||
|
} = rootState.user; |
||||
|
if (!token) return; |
||||
|
const data = { |
||||
|
type: 'Auth', |
||||
|
data: { |
||||
|
token |
||||
|
} |
||||
|
}; |
||||
|
dispatch('sendSocketMessage', data); |
||||
|
}, |
||||
|
|
||||
|
// 心跳检测
|
||||
|
sendHeart({ |
||||
|
dispatch, |
||||
|
state |
||||
|
}) { |
||||
|
if (sendHeartTimer) clearInterval(sendHeartTimer); |
||||
|
sendHeartTimer = setInterval(() => { |
||||
|
if (Date.now() - prevTime >= 15000) { |
||||
|
dispatch('sendSocketMessage', { |
||||
|
type: 'Ping' |
||||
|
}); |
||||
|
if (Date.now() - prevTime >= 20000) { |
||||
|
state.socket.close(); |
||||
|
} |
||||
|
} |
||||
|
}, 5000); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 处理auth认证返回的ChannelStatus消息 |
||||
|
* @param {object} data 消息内容对象 |
||||
|
*/ |
||||
|
handleAuthMessage({ |
||||
|
commit, |
||||
|
dispatch |
||||
|
}, data) { |
||||
|
if (data.data.authed) { |
||||
|
dispatch('sendHeart'); |
||||
|
} else { |
||||
|
uni.$u.toast('消息系统认证失败, 请退出重新登录'); |
||||
|
uni.$t.removeStorageSync('anyringToken'); |
||||
|
commit('setSocket', null); |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default actions; |
@ -0,0 +1,10 @@ |
|||||
|
import state from './state'; |
||||
|
import mutations from './mutations'; |
||||
|
import actions from './actions'; |
||||
|
|
||||
|
export default { |
||||
|
namespaced: true, |
||||
|
state, |
||||
|
mutations, |
||||
|
actions |
||||
|
}; |
@ -0,0 +1,26 @@ |
|||||
|
const mutations = { |
||||
|
// 设置socket实例
|
||||
|
setSocket(state, socket) { |
||||
|
state.socket = socket; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 设置socket连接状态 |
||||
|
* @param {Object} state |
||||
|
* @param {boolean} connected 是否连接 true -> 连接 |
||||
|
*/ |
||||
|
setConnected(state, connected) { |
||||
|
state.connected = connected; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 设置连接锁 正在连接中 锁上 避免多个连接同时发出 |
||||
|
* @param {Object} state |
||||
|
* @param {boolean} lockSocket 是否正在连接的过程中 |
||||
|
*/ |
||||
|
setLockSocket(state, lockSocket) { |
||||
|
state.lockSocket = lockSocket; |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default mutations; |
@ -0,0 +1,7 @@ |
|||||
|
const state = { |
||||
|
socket: null, // websocket实例
|
||||
|
connected: false, // 是否处于连接状态
|
||||
|
lockSocket: false, // 是否正在连接状态
|
||||
|
}; |
||||
|
|
||||
|
export default state; |
Loading…
Reference in new issue