+
diff --git a/src/config/api-user.js b/src/config/api-user.js
index 5c5f290..3056438 100644
--- a/src/config/api-user.js
+++ b/src/config/api-user.js
@@ -7,20 +7,7 @@ import axios from 'axios';
let { proxyUrl, msgUrl } = require('@/config/setting');
const tall = `${proxyUrl}/tall/v1.0`;
-// console.log('tall: ', tall);
const users = `${tall}/users`;
-// 用户登录
-export const signIn = params => axios.post(`${users}/signin`, params);
-
-// 注册
-export const signUp = params => axios.post(`${users}/signup`, params);
-
-// 图片验证码
-export const getPicCode = () => axios.get(`${users}/code`);
-
-// 发送验证码
-export const getSmscode = params => axios.get(`${users}/smscode`, params);
-
-// 通过手机号修改密码
-export const changePassword = params => axios.post(`${users}/password`, params);
+// 查找用户详细信息
+export const getUserId = params => axios.get(`${users}/userId`, params);
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
new file mode 100644
index 0000000..033a4d0
--- /dev/null
+++ b/src/mixins/socket.js
@@ -0,0 +1,213 @@
+import { WS_BASE_URL } from 'config/api';
+import { mapGetters, mapMutations } from 'vuex';
+
+let connected = false; // socket 是否连接
+let socket = null; // websocket 实例
+let lockSocket = false;
+let socketMsgQueue = []; // socket消息队列
+let prevTimestamp = 0; // 上次收到消息的时间戳
+let sendHeartTimer = null; // 💓的timer计时器
+
+const mixin = {
+ // computed: mapGetters('home', ['projectId']),
+
+ mounted() {
+ socket ? socket.close() : this.initSocket();
+ },
+
+ methods: {
+ ...mapMutations('messages', [
+ 'messagesAdd',
+ 'messagesAddWeight',
+ 'messagesAddRfid',
+ 'messagesAddWeighSensor1',
+ 'messagesAddWeighSensor2',
+ 'messagesAddWeighSensor3',
+ 'messagesAddWeighSensor4',
+ 'messagesAddVibrationSensor',
+ 'messagesAddThrombolyticDose',
+ 'messagesAddBolusDose',
+ 'messagesAddMaintenanceDose',
+ ]),
+ // ...mapMutations('home', ['increaseProjectsRingNum']),
+
+ // 初始化websocket
+ initSocket() {
+ if (lockSocket) return;
+ lockSocket = true;
+ // const token = sessionStorage.getItem('anyringToken');
+ // if (!token) return;
+ if ('WebSocket' in window) {
+ socket = new WebSocket(WS_BASE_URL);
+ socket.onopen = this.websocketOpen;
+ socket.onmessage = this.websocketOnMessage;
+ socket.onclose = this.websocketClose;
+ socket.onerror = this.websocketError;
+ } else {
+ this.$message.error('当前浏览器不支持 websocket');
+ }
+ lockSocket = false;
+ },
+
+ /**
+ * 处理收到的消息内容
+ * @param {object} item 单个消息体对象
+ */
+ handleMessagesData(item) {
+ const data = JSON.parse(item.data);
+ console.log('data: ', data);
+ switch (data.type) {
+ case 'ChannelStatus': // 认证消息
+ this.handleAuthMessage(data);
+ break;
+ case 1: // 体重
+ // 收到同步消息
+ // 把消息添加到store 的消息栈中
+ this.messagesAddWeight(data);
+ break;
+ case 2: // RFID
+ this.messagesAddRfid(data);
+ break;
+ case 3: // 称重传感器一
+ this.messagesAddWeighSensor1(data);
+ break;
+ case 4: // 称重传感器二
+ this.messagesAddWeighSensor2(data);
+ break;
+ case 5: // 称重传感器三
+ this.messagesAddWeighSensor3(data);
+ break;
+ case 6: // 称重传感器四
+ this.messagesAddWeighSensor4(data);
+ break;
+ case 7: // 震动传感器
+ this.messagesAddVibrationSensor(data);
+ break;
+ case 8: // 溶栓剂量(总量)
+ this.messagesAddThrombolyticDose(data);
+ break;
+ case 9: // 团注剂量
+ this.messagesAddBolusDose(data);
+ break;
+ case 10: // 维持剂量
+ this.messagesAddMaintenanceDose(data);
+ break;
+ default:
+ break;
+ }
+ },
+
+ /**
+ * 收到ws 消息
+ * @param {object} res 收到的消息数据
+ */
+ async websocketOnMessage(res) {
+ try {
+ prevTimestamp = Date.now();
+ // console.warn('message: ', res, new Date().toLocaleString());
+ if (res && res.data && JSON.parse(res.data)) {
+ const resData = JSON.parse(res.data);
+ const { messageSet, ackId } = resData;
+ // 处理消息体对象
+ messageSet.forEach(item => this.handleMessagesData(item));
+ // console.log('ackId', ackId);
+ // 有ackId 发送ack
+ ackId && this.sendSocketMessage({ type: 'Ack', data: { ackId } });
+ }
+ } catch (error) {
+ console.error('error: ', error);
+ }
+ },
+
+ // 打开socket
+ websocketOpen() {
+ // console.warn('socket 打开成功', new Date().toLocaleString());
+ connected = true;
+ prevTimestamp = Date.now();
+ this.auth();
+ for (let i = 0; i < socketMsgQueue.length; i += 1) {
+ this.sendSocketMessage(socketMsgQueue[i]);
+ }
+ socketMsgQueue = [];
+ },
+
+ // 发送消息
+ sendSocketMessage(data) {
+ // console.warn('send:', data, new Date().toLocaleString());
+ if (connected) {
+ if (socket.readyState === 1) {
+ socket.send(JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }));
+ }
+ } else {
+ socketMsgQueue.push(data);
+ }
+ },
+
+ // 关闭socket
+ websocketClose(e) {
+ // console.warn(e);
+ connected = false;
+ if (sendHeartTimer) clearInterval(sendHeartTimer);
+ // console.warn('close:', connected, new Date().toLocaleString());
+ if (!e || e.code !== 1005) {
+ socket.close();
+ }
+
+ setTimeout(() => {
+ // connected 在这里的作用是:
+ // 在发生重连 但是还没连上之前 不要再次重连
+ this.initSocket();
+ }, 300);
+ },
+
+ // 连接失败
+ websocketError() {
+ console.warn('error = ', connected);
+ },
+
+ // websocket发送token进行认证
+ auth() {
+ // const token = sessionStorage.getItem('anyringToken');
+ // if (!token) return;
+ const userId = '1338747522436435968';
+ const data = { type: 'Auth', data: { userId }, major: 1, minor: 1 };
+ this.sendSocketMessage(data);
+ },
+
+ // 心跳检测
+ sendHeart() {
+ if (sendHeartTimer) clearInterval(sendHeartTimer);
+ sendHeartTimer = setInterval(() => {
+ if (Date.now() - prevTimestamp >= 15000) {
+ this.sendSocketMessage({ type: 'Ping' });
+
+ if (Date.now() - prevTimestamp > 20000) {
+ // console.warn('手动断开');
+ socket.close();
+ }
+ }
+ }, 5000);
+ },
+
+ /**
+ * 处理auth认证返回的ChannelStatus消息
+ * @param {object} data 消息内容对象
+ */
+ handleAuthMessage(data) {
+ if (data.data.authed) {
+ // 认证成功
+ this.sendHeart();
+ } else {
+ this.$message.error('消息系统认证失败, 请重新登录');
+ // 清除掉本地无用的token
+ sessionStorage.removeItem('anyringToken');
+ socket = null;
+ setTimeout(() => {
+ this.$router.push('/user/login');
+ }, 1000);
+ }
+ },
+ },
+};
+
+export default mixin;
diff --git a/src/store/actions.js b/src/store/actions.js
deleted file mode 100644
index 7ecf322..0000000
--- a/src/store/actions.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import axios from 'axios';
-import { message } from 'ant-design-vue';
-import { getSmscode, getPicCode, signIn, changePassword, signUp, getUserId } from 'config/api-user';
-
-const actions = {
- /**
- * sendCode 发送验证码
- * @param {any} commit
- * @param {object} params 提交的数据
- * @param {string} params.phone 手机号
- */
- async sendCode({ commit }, params) {
- try {
- const res = await getSmscode({ params });
- const { code, msg, data } = res.data;
- if (code === 200) {
- return data;
- } else {
- message.error(msg || '发送失败');
- throw msg;
- }
- } catch (error) {
- throw error || '发送失败';
- }
- },
-
- /**
- * sendPicCode 获取图片验证码
- * @param {any} commit
- * @param {object} params 提交的数据
- */
- async sendPicCode({ commit }) {
- try {
- const res = await getPicCode();
- const { code, msg, data } = res.data;
- if (code === 200) {
- commit('setPicCode', data);
- return data;
- } else {
- throw msg;
- }
- } catch (error) {
- throw error || '获取失败';
- }
- },
-
- /**
- * signIn 登录
- * @param {any} commit
- * @param {string} identifier 身份标识 手机号 用户名
- * @param {string} credential 身份凭证 验证码 密码
- * @return {Promise} result 服务器返回信息
- */
- async signIn({ commit }, params) {
- const hideLoading = message.loading('登录中', 0);
- try {
- const res = await signIn(params);
- const { code, msg, data } = res.data;
- if (code === 200) {
- commit('sign', data.token);
- commit('setUser', data);
- hideLoading();
- message.success('登录成功');
- return data;
- } else {
- hideLoading();
- throw msg || '登录失败';
- }
- } catch (error) {
- hideLoading();
- throw error || '登录失败';
- }
- },
-
- /**
- * 修改密码 忘记密码
- * @param {any} commit
- * @param {object} params 要提交的参数
- */
- async changePassword({ commit }, params) {
- try {
- const res = await changePassword(params);
- const { code, msg, data } = res.data;
- if (code === 200) {
- message.success('修改密码成功');
- return data;
- } else {
- throw msg || '修改密码失败';
- }
- } catch (error) {
- throw error || '修改密码失败';
- }
- },
-
- /**
- * singUp 注册新用户
- * @param {any} commit
- * @param {object} params 提交的数据
- * @param {string} params.account 用户名
- * @param {string} params.password 密码
- * @param {string} params.phone 手机号
- * @param {string} params.smsCode 验证码
- */
- async signUp({ commit }, params) {
- try {
- const res = await signUp(params);
- const { code, msg, data } = res.data;
- if (code === 200) {
- commit('sign', data.token);
- commit('setUser', data);
- message.success('注册成功');
- return data;
- } else {
- throw msg || '注册失败';
- }
- } catch (error) {
- throw error || '注册失败';
- }
- },
-
- /**
- * 通过userId获取token
- * @param {any} commit
- * @param {object} params 提交的参数
- */
- // async getUserId({ commit }, params) {
- // try {
- // const res = await getUserId({ params });
- // const { code, msg, data } = res.data;
- // if (code === 200) {
- // commit('sign', data.token);
- // commit('setUser', data);
- // return data;
- // } else {
- // throw msg;
- // }
- // } catch (error) {
- // throw error || '获取个人信息失败';
- // }
- // },
-};
-
-export default actions;
diff --git a/src/store/index.js b/src/store/index.js
index b97fc4b..7dd359a 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,16 +1,13 @@
-import Vue from "vue";
-import Vuex from "vuex";
-import mutations from './mutations';
-import actions from './actions';
-import state from './state';
-import getters from './getters';
+/*
+ * Copyright (c) 2019.
+ * author: wally
+ * email: 18603454788@163.com
+ */
-Vue.use(Vuex);
-
-const store = new Vuex.Store({
- state,
- mutations,
- actions,
-});
+import Vue from 'vue';
+import Vuex from 'vuex';
+import home from './modules/home/index';
+import messages from './modules/messages/index';
-export default store;
+Vue.use(Vuex);
+export default new Vuex.Store({ modules: { home, messages } });
diff --git a/src/store/modules/home/actions.js b/src/store/modules/home/actions.js
new file mode 100644
index 0000000..1b9113f
--- /dev/null
+++ b/src/store/modules/home/actions.js
@@ -0,0 +1,28 @@
+import axios from 'axios';
+import { message } from 'ant-design-vue';
+import { getUserId } from 'config/api-user';
+
+const actions = {
+ /**
+ * 通过userId获取token
+ * @param {any} commit
+ * @param {object} params 提交的参数
+ */
+ async getUserId({ commit }, params) {
+ try {
+ const res = await getUserId({ params });
+ const { code, msg, data } = res.data;
+ if (code === 200) {
+ commit('sign', data.token);
+ commit('setUser', data);
+ return data;
+ } else {
+ throw msg;
+ }
+ } catch (error) {
+ throw error || '获取个人信息失败';
+ }
+ },
+};
+
+export default actions;
diff --git a/src/store/getters.js b/src/store/modules/home/getters.js
similarity index 100%
rename from src/store/getters.js
rename to src/store/modules/home/getters.js
diff --git a/src/store/modules/home/index.js b/src/store/modules/home/index.js
new file mode 100644
index 0000000..149de4f
--- /dev/null
+++ b/src/store/modules/home/index.js
@@ -0,0 +1,6 @@
+import mutations from './mutations';
+import actions from './actions';
+import getters from './getters';
+import state from './state';
+
+export default { namespaced: true, state, getters, mutations, actions };
diff --git a/src/store/mutations.js b/src/store/modules/home/mutations.js
similarity index 100%
rename from src/store/mutations.js
rename to src/store/modules/home/mutations.js
diff --git a/src/store/state.js b/src/store/modules/home/state.js
similarity index 100%
rename from src/store/state.js
rename to src/store/modules/home/state.js
diff --git a/src/store/modules/messages/actions.js b/src/store/modules/messages/actions.js
new file mode 100644
index 0000000..61da9cc
--- /dev/null
+++ b/src/store/modules/messages/actions.js
@@ -0,0 +1,7 @@
+import http from 'axios';
+import { message } from 'ant-design-vue';
+import {} from 'config/api';
+
+const actions = {};
+
+export default actions;
diff --git a/src/store/modules/messages/getters.js b/src/store/modules/messages/getters.js
new file mode 100644
index 0000000..56c8c75
--- /dev/null
+++ b/src/store/modules/messages/getters.js
@@ -0,0 +1,3 @@
+const getters = {};
+
+export default getters;
diff --git a/src/store/modules/messages/index.js b/src/store/modules/messages/index.js
new file mode 100644
index 0000000..91969b1
--- /dev/null
+++ b/src/store/modules/messages/index.js
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2019.
+ * author: wally
+ * email: 18603454788@163.com
+ */
+import mutations from './mutations';
+import actions from './actions';
+import getters from './getters';
+import state from './state';
+
+export default { namespaced: true, state, getters, mutations, actions };
diff --git a/src/store/modules/messages/mutations.js b/src/store/modules/messages/mutations.js
new file mode 100644
index 0000000..2ba1ebe
--- /dev/null
+++ b/src/store/modules/messages/mutations.js
@@ -0,0 +1,173 @@
+const mutations = {
+ /**
+ * 初始化消息栈
+ * @param {object} state
+ * @param {string} type
+ * type:
+ * syncMessages 同步消息栈
+ * checkMessages 交付物消息栈
+ * faultMessages 故障消息 未处理消息栈
+ * faults 所有的故障消息栈
+ */
+ messagesInit(state, type) {
+ const messages = localStorage.getItem(type) ? JSON.parse(localStorage.getItem(type)) : [];
+ state[type] = messages;
+ },
+
+ /**
+ * 将新 消息添加到 消息栈 最前边
+ * @param { object } state
+ * @param { object } data
+ * data: message, type
+ * message 消息对象
+ * type:
+ * syncMessages 同步消息栈
+ * checkMessages 交付物消息栈
+ * faultMessages 故障消息 未处理消息栈
+ * faults 所有的故障消息栈
+ *
+ * cache: boolean true 本地存储 false 不存储
+ */
+ messagesAdd(state, data) {
+ const messages = state[data.type];
+ if (messages.length > 0) {
+ const result = messages.find(msg => msg.id === data.message.id);
+ if (result) return;
+ }
+ messages.unshift(data.message);
+ // eslint-disable-next-line no-param-reassign
+ state[data.type] = messages;
+ if (data.cache) {
+ localStorage.setItem(data.type, JSON.stringify(messages));
+ }
+ },
+
+ /**
+ * 通过消息id移除指定 同步 消息
+ * @param { object } state
+ * @param { object } data
+ * data: messageId, type
+ * messageId: 要移除的消息的messageId
+ * type:
+ * syncMessages 同步消息栈
+ * checkMessages 交付物消息栈
+ * faultMessages 故障消息 未处理消息栈
+ * faults 所有的故障消息栈
+ * cache: boolean true 本地存储 false 不存储
+ */
+ messagesRemoveById(state, data) {
+ const messages = state[data.type];
+ const index = messages.findIndex(msg => msg.id === data.messageId);
+ if (index < 0) return;
+ messages.splice(index, 1);
+ // eslint-disable-next-line no-param-reassign
+ state[data.type] = messages;
+ if (data.cache) {
+ localStorage.setItem(data.type, JSON.stringify(messages));
+ }
+ },
+
+ /**
+ * 清除指定type的消息
+ * @param {any} state
+ * @param {object} data
+ * data: type, cache
+ */
+ messagesClear(state, data) {
+ state[data.type] = [];
+ if (data.cache) {
+ localStorage.removeItem(data.type);
+ }
+ },
+
+ /**
+ * 添加体重消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddWeight(state, data) {
+ state.weightMessage = data;
+ },
+
+ /**
+ * 添加RFID消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddRfid(state, data) {
+ state.rfidMessage = data;
+ },
+
+ /**
+ * 添加称重传感器一消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddWeighSensor1(state, data) {
+ state.weighSensor1 = data;
+ },
+
+ /**
+ * 添加称重传感器二消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddWeighSensor2(state, data) {
+ state.weighSensor2 = data;
+ },
+
+ /**
+ * 添加称重传感器三消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddWeighSensor3(state, data) {
+ state.weighSensor3 = data;
+ },
+
+ /**
+ * 添加称重传感器四消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddWeighSensor4(state, data) {
+ state.weighSensor4 = data;
+ },
+
+ /**
+ * 添加震动传感器消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddVibrationSensor(state, data) {
+ state.vibrationSensor = data;
+ },
+
+ /**
+ * 添加溶栓剂量(总量)消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddThrombolyticDose(state, data) {
+ state.thrombolyticDose = data;
+ },
+
+ /**
+ * 添加团注剂量消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddBolusDose(state, data) {
+ state.bolusDose = data;
+ },
+
+ /**
+ * 添加维持剂量消息
+ * @param {*} state
+ * @param {*} data
+ */
+ messagesAddMaintenanceDose(state, data) {
+ state.maintenanceDose = data;
+ },
+};
+export default mutations;
diff --git a/src/store/modules/messages/state.js b/src/store/modules/messages/state.js
new file mode 100644
index 0000000..3a86c92
--- /dev/null
+++ b/src/store/modules/messages/state.js
@@ -0,0 +1,15 @@
+const state = {
+ syncMessages: [], // 同步消息
+ weightMessage: null, // 体重
+ rfidMessage: null, // RFID
+ weighSensor1: null, // 称重传感器一
+ weighSensor2: null, // 称重传感器二
+ weighSensor3: null, // 称重传感器三
+ weighSensor4: null, // 称重传感器四
+ vibrationSensor: null, // 震动传感器
+ thrombolyticDose: null, // 溶栓剂量(总量)
+ bolusDose: null, // 团注剂量
+ maintenanceDose: null, // 维持剂量
+};
+
+export default state;
diff --git a/src/views/Index/Index.vue b/src/views/Index/Index.vue
index 79575af..33c2628 100644
--- a/src/views/Index/Index.vue
+++ b/src/views/Index/Index.vue
@@ -125,9 +125,12 @@ import LoadCells from 'components/LoadCells/LoadCells.vue';
import RFID from 'components/RFID/RFID.vue';
import FastEd from 'components/FastEd/FastEd.vue';
import Panel from 'components/Panel/Panel.vue';
+import socketMixin from '@/mixins/socket';
+
export default {
name: 'Index',
components: { Statistics, Duration, Sensor, LoadCells, RFID, FastEd, Panel },
+ mixins: [socketMixin],
data() {
return {
nowTime: new Date(),