前端代码格式化
This commit is contained in:
@@ -1,92 +1,92 @@
|
||||
import axios from "axios";
|
||||
import config from "@/config";
|
||||
import { useUserStore } from "@/stores/modules/user";
|
||||
import { message } from "ant-design-vue";
|
||||
import router from "@/router";
|
||||
import axios from 'axios'
|
||||
import config from '@/config'
|
||||
import { useUserStore } from '@/stores/modules/user'
|
||||
import { message } from 'ant-design-vue'
|
||||
import router from '@/router'
|
||||
|
||||
const request = axios.create({
|
||||
timeout: 30000,
|
||||
baseURL: config.API_URL,
|
||||
});
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
const userStore = useUserStore();
|
||||
const token = userStore.token;
|
||||
const userStore = useUserStore()
|
||||
const token = userStore.token
|
||||
|
||||
// 如果有 token,添加到请求头
|
||||
if (token) {
|
||||
config.headers["Authorization"] = `Bearer ${token}`;
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
return config;
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
return Promise.reject(error)
|
||||
},
|
||||
);
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
// 根据后端返回的数据结构进行处理
|
||||
// 后端返回格式为 { code, message, data }
|
||||
const { code, data, message: msg } = response.data;
|
||||
const { code, data, message: msg } = response.data
|
||||
|
||||
// 请求成功
|
||||
if (code === 200 || code === 1) {
|
||||
return { code, data, message: msg };
|
||||
return { code, data, message: msg }
|
||||
}
|
||||
|
||||
// 其他错误码处理
|
||||
message.error(msg || "请求失败");
|
||||
return Promise.reject(new Error(msg || "请求失败"));
|
||||
message.error(msg || '请求失败')
|
||||
return Promise.reject(new Error(msg || '请求失败'))
|
||||
},
|
||||
async (error) => {
|
||||
const userStore = useUserStore();
|
||||
const { response } = error;
|
||||
const userStore = useUserStore()
|
||||
const { response } = error
|
||||
|
||||
// 无响应(网络错误、超时等)
|
||||
if (!response) {
|
||||
message.error("网络错误,请检查网络连接");
|
||||
return Promise.reject(error);
|
||||
message.error('网络错误,请检查网络连接')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
const { status, data } = response;
|
||||
const { status, data } = response
|
||||
|
||||
// 401 未授权 - token 过期或无效
|
||||
if (status === 401) {
|
||||
// 直接登出并跳转到登录页
|
||||
userStore.logout();
|
||||
router.push("/login");
|
||||
message.error("登录已过期,请重新登录");
|
||||
return Promise.reject(error);
|
||||
userStore.logout()
|
||||
router.push('/login')
|
||||
message.error('登录已过期,请重新登录')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 403 禁止访问
|
||||
if (status === 403) {
|
||||
message.error("没有权限访问该资源");
|
||||
return Promise.reject(error);
|
||||
message.error('没有权限访问该资源')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 404 资源不存在
|
||||
if (status === 404) {
|
||||
message.error("请求的资源不存在");
|
||||
return Promise.reject(error);
|
||||
message.error('请求的资源不存在')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 500 服务器错误
|
||||
if (status >= 500) {
|
||||
message.error("服务器错误,请稍后重试");
|
||||
return Promise.reject(error);
|
||||
message.error('服务器错误,请稍后重试')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// 其他错误
|
||||
const errorMessage = data?.message || error.message || "请求失败";
|
||||
message.error(errorMessage);
|
||||
return Promise.reject(error);
|
||||
const errorMessage = data?.message || error.message || '请求失败'
|
||||
message.error(errorMessage)
|
||||
return Promise.reject(error)
|
||||
},
|
||||
);
|
||||
)
|
||||
|
||||
export default request;
|
||||
export default request
|
||||
|
||||
+175
-217
@@ -5,10 +5,10 @@
|
||||
* @LastEditTime: 2026年1月15日
|
||||
*/
|
||||
|
||||
import CryptoJS from "crypto-js";
|
||||
import sysConfig from "@/config";
|
||||
import CryptoJS from 'crypto-js'
|
||||
import sysConfig from '@/config'
|
||||
|
||||
const tool = {};
|
||||
const tool = {}
|
||||
|
||||
/**
|
||||
* 检查是否为有效的值(非null、非undefined、非空字符串、非空数组、非空对象)
|
||||
@@ -17,19 +17,19 @@ const tool = {};
|
||||
*/
|
||||
tool.isValid = function (value) {
|
||||
if (value === null || value === undefined) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (typeof value === "string" && value.trim() === "") {
|
||||
return false;
|
||||
if (typeof value === 'string' && value.trim() === '') {
|
||||
return false
|
||||
}
|
||||
if (Array.isArray(value) && value.length === 0) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (typeof value === "object" && Object.keys(value).length === 0) {
|
||||
return false;
|
||||
if (typeof value === 'object' && Object.keys(value).length === 0) {
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
};
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 防抖函数
|
||||
@@ -39,21 +39,21 @@ tool.isValid = function (value) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
tool.debounce = function (func, wait = 300, immediate = false) {
|
||||
let timeout;
|
||||
let timeout
|
||||
return function (...args) {
|
||||
const context = this;
|
||||
clearTimeout(timeout);
|
||||
const context = this
|
||||
clearTimeout(timeout)
|
||||
if (immediate && !timeout) {
|
||||
func.apply(context, args);
|
||||
func.apply(context, args)
|
||||
}
|
||||
timeout = setTimeout(() => {
|
||||
timeout = null;
|
||||
timeout = null
|
||||
if (!immediate) {
|
||||
func.apply(context, args);
|
||||
func.apply(context, args)
|
||||
}
|
||||
}, wait);
|
||||
};
|
||||
};
|
||||
}, wait)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 节流函数
|
||||
@@ -63,36 +63,36 @@ tool.debounce = function (func, wait = 300, immediate = false) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
tool.throttle = function (func, wait = 300, options = {}) {
|
||||
let timeout;
|
||||
let previous = 0;
|
||||
const { leading = true, trailing = true } = options;
|
||||
let timeout
|
||||
let previous = 0
|
||||
const { leading = true, trailing = true } = options
|
||||
|
||||
return function (...args) {
|
||||
const context = this;
|
||||
const now = Date.now();
|
||||
const context = this
|
||||
const now = Date.now()
|
||||
|
||||
if (!previous && !leading) {
|
||||
previous = now;
|
||||
previous = now
|
||||
}
|
||||
|
||||
const remaining = wait - (now - previous);
|
||||
const remaining = wait - (now - previous)
|
||||
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
clearTimeout(timeout)
|
||||
timeout = null
|
||||
}
|
||||
previous = now;
|
||||
func.apply(context, args);
|
||||
previous = now
|
||||
func.apply(context, args)
|
||||
} else if (!timeout && trailing) {
|
||||
timeout = setTimeout(() => {
|
||||
previous = leading ? Date.now() : 0;
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
}, remaining);
|
||||
previous = leading ? Date.now() : 0
|
||||
timeout = null
|
||||
func.apply(context, args)
|
||||
}, remaining)
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 深拷贝对象(支持循环引用)
|
||||
@@ -101,99 +101,88 @@ tool.throttle = function (func, wait = 300, options = {}) {
|
||||
* @returns {*}
|
||||
*/
|
||||
tool.deepClone = function (obj, hash = new WeakMap()) {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return obj;
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
return obj
|
||||
}
|
||||
|
||||
if (hash.has(obj)) {
|
||||
return hash.get(obj);
|
||||
return hash.get(obj)
|
||||
}
|
||||
|
||||
const clone = Array.isArray(obj) ? [] : {};
|
||||
hash.set(obj, clone);
|
||||
const clone = Array.isArray(obj) ? [] : {}
|
||||
hash.set(obj, clone)
|
||||
|
||||
for (const key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
clone[key] = tool.deepClone(obj[key], hash);
|
||||
clone[key] = tool.deepClone(obj[key], hash)
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
};
|
||||
return clone
|
||||
}
|
||||
|
||||
/* localStorage */
|
||||
tool.data = {
|
||||
set(key, data, datetime = 0) {
|
||||
//加密
|
||||
if (sysConfig.LS_ENCRYPTION == "AES") {
|
||||
data = tool.crypto.AES.encrypt(
|
||||
JSON.stringify(data),
|
||||
sysConfig.LS_ENCRYPTION_key,
|
||||
);
|
||||
if (sysConfig.LS_ENCRYPTION == 'AES') {
|
||||
data = tool.crypto.AES.encrypt(JSON.stringify(data), sysConfig.LS_ENCRYPTION_key)
|
||||
}
|
||||
let cacheValue = {
|
||||
content: data,
|
||||
datetime:
|
||||
parseInt(datetime) === 0
|
||||
? 0
|
||||
: new Date().getTime() + parseInt(datetime) * 1000,
|
||||
};
|
||||
return localStorage.setItem(key, JSON.stringify(cacheValue));
|
||||
datetime: parseInt(datetime) === 0 ? 0 : new Date().getTime() + parseInt(datetime) * 1000,
|
||||
}
|
||||
return localStorage.setItem(key, JSON.stringify(cacheValue))
|
||||
},
|
||||
get(key) {
|
||||
try {
|
||||
const value = JSON.parse(localStorage.getItem(key));
|
||||
const value = JSON.parse(localStorage.getItem(key))
|
||||
if (value) {
|
||||
let nowTime = new Date().getTime();
|
||||
let nowTime = new Date().getTime()
|
||||
if (nowTime > value.datetime && value.datetime != 0) {
|
||||
localStorage.removeItem(key);
|
||||
return null;
|
||||
localStorage.removeItem(key)
|
||||
return null
|
||||
}
|
||||
//解密
|
||||
if (sysConfig.LS_ENCRYPTION == "AES") {
|
||||
value.content = JSON.parse(
|
||||
tool.crypto.AES.decrypt(
|
||||
value.content,
|
||||
sysConfig.LS_ENCRYPTION_key,
|
||||
),
|
||||
);
|
||||
if (sysConfig.LS_ENCRYPTION == 'AES') {
|
||||
value.content = JSON.parse(tool.crypto.AES.decrypt(value.content, sysConfig.LS_ENCRYPTION_key))
|
||||
}
|
||||
return value.content;
|
||||
return value.content
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
} catch {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
},
|
||||
remove(key) {
|
||||
return localStorage.removeItem(key);
|
||||
return localStorage.removeItem(key)
|
||||
},
|
||||
clear() {
|
||||
return localStorage.clear();
|
||||
return localStorage.clear()
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/*sessionStorage*/
|
||||
tool.session = {
|
||||
set(table, settings) {
|
||||
const _set = JSON.stringify(settings);
|
||||
return sessionStorage.setItem(table, _set);
|
||||
const _set = JSON.stringify(settings)
|
||||
return sessionStorage.setItem(table, _set)
|
||||
},
|
||||
get(table) {
|
||||
const data = sessionStorage.getItem(table);
|
||||
const data = sessionStorage.getItem(table)
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
return JSON.parse(data)
|
||||
} catch {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
},
|
||||
remove(table) {
|
||||
return sessionStorage.removeItem(table);
|
||||
return sessionStorage.removeItem(table)
|
||||
},
|
||||
clear() {
|
||||
return sessionStorage.clear();
|
||||
return sessionStorage.clear()
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/*cookie*/
|
||||
tool.cookie = {
|
||||
@@ -210,28 +199,28 @@ tool.cookie = {
|
||||
domain: null,
|
||||
secure: false,
|
||||
httpOnly: false,
|
||||
sameSite: "Lax",
|
||||
sameSite: 'Lax',
|
||||
...config,
|
||||
};
|
||||
let cookieStr = `${name}=${encodeURIComponent(value)}`;
|
||||
}
|
||||
let cookieStr = `${name}=${encodeURIComponent(value)}`
|
||||
if (cfg.expires) {
|
||||
const exp = new Date();
|
||||
exp.setTime(exp.getTime() + parseInt(cfg.expires) * 1000);
|
||||
cookieStr += `;expires=${exp.toUTCString()}`;
|
||||
const exp = new Date()
|
||||
exp.setTime(exp.getTime() + parseInt(cfg.expires) * 1000)
|
||||
cookieStr += `;expires=${exp.toUTCString()}`
|
||||
}
|
||||
if (cfg.path) {
|
||||
cookieStr += `;path=${cfg.path}`;
|
||||
cookieStr += `;path=${cfg.path}`
|
||||
}
|
||||
if (cfg.domain) {
|
||||
cookieStr += `;domain=${cfg.domain}`;
|
||||
cookieStr += `;domain=${cfg.domain}`
|
||||
}
|
||||
if (cfg.secure) {
|
||||
cookieStr += `;secure`;
|
||||
cookieStr += `;secure`
|
||||
}
|
||||
if (cfg.sameSite) {
|
||||
cookieStr += `;SameSite=${cfg.sameSite}`;
|
||||
cookieStr += `;SameSite=${cfg.sameSite}`
|
||||
}
|
||||
document.cookie = cookieStr;
|
||||
document.cookie = cookieStr
|
||||
},
|
||||
/**
|
||||
* 获取cookie
|
||||
@@ -239,24 +228,22 @@ tool.cookie = {
|
||||
* @returns {string|null}
|
||||
*/
|
||||
get(name) {
|
||||
const arr = document.cookie.match(
|
||||
new RegExp("(^| )" + name + "=([^;]*)(;|$)"),
|
||||
);
|
||||
const arr = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)(;|$)'))
|
||||
if (arr != null) {
|
||||
return decodeURIComponent(arr[2]);
|
||||
return decodeURIComponent(arr[2])
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
},
|
||||
/**
|
||||
* 删除cookie
|
||||
* @param {string} name - cookie名称
|
||||
*/
|
||||
remove(name) {
|
||||
const exp = new Date();
|
||||
exp.setTime(exp.getTime() - 1);
|
||||
document.cookie = `${name}=;expires=${exp.toUTCString()}`;
|
||||
const exp = new Date()
|
||||
exp.setTime(exp.getTime() - 1)
|
||||
document.cookie = `${name}=;expires=${exp.toUTCString()}`
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/* Fullscreen */
|
||||
/**
|
||||
@@ -264,34 +251,29 @@ tool.cookie = {
|
||||
* @param {HTMLElement} element - 要全屏的元素
|
||||
*/
|
||||
tool.screen = function (element) {
|
||||
const isFull = !!(
|
||||
document.webkitIsFullScreen ||
|
||||
document.mozFullScreen ||
|
||||
document.msFullscreenElement ||
|
||||
document.fullscreenElement
|
||||
);
|
||||
const isFull = !!(document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement)
|
||||
if (isFull) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
document.exitFullscreen()
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
document.msExitFullscreen()
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
document.mozCancelFullScreen()
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
document.webkitExitFullscreen()
|
||||
}
|
||||
} else {
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen();
|
||||
element.requestFullscreen()
|
||||
} else if (element.msRequestFullscreen) {
|
||||
element.msRequestFullscreen();
|
||||
element.msRequestFullscreen()
|
||||
} else if (element.mozRequestFullScreen) {
|
||||
element.mozRequestFullScreen();
|
||||
element.mozRequestFullScreen()
|
||||
} else if (element.webkitRequestFullscreen) {
|
||||
element.webkitRequestFullscreen();
|
||||
element.webkitRequestFullscreen()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* 复制对象(浅拷贝) */
|
||||
/**
|
||||
@@ -300,11 +282,11 @@ tool.screen = function (element) {
|
||||
* @returns {*} - 拷贝后的对象
|
||||
*/
|
||||
tool.objCopy = function (obj) {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return obj;
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
return obj
|
||||
}
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
};
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
/* 日期格式化 */
|
||||
/**
|
||||
@@ -313,38 +295,30 @@ tool.objCopy = function (obj) {
|
||||
* @param {string} fmt - 格式化字符串,默认 "yyyy-MM-dd hh:mm:ss"
|
||||
* @returns {string} - 格式化后的日期字符串
|
||||
*/
|
||||
tool.dateFormat = function (date, fmt = "yyyy-MM-dd hh:mm:ss") {
|
||||
if (!date) return "";
|
||||
const dateObj = new Date(date);
|
||||
if (isNaN(dateObj.getTime())) return "";
|
||||
tool.dateFormat = function (date, fmt = 'yyyy-MM-dd hh:mm:ss') {
|
||||
if (!date) return ''
|
||||
const dateObj = new Date(date)
|
||||
if (isNaN(dateObj.getTime())) return ''
|
||||
|
||||
const o = {
|
||||
"M+": dateObj.getMonth() + 1, // 月份
|
||||
"d+": dateObj.getDate(), // 日
|
||||
"h+": dateObj.getHours(), // 小时
|
||||
"m+": dateObj.getMinutes(), // 分
|
||||
"s+": dateObj.getSeconds(), // 秒
|
||||
"q+": Math.floor((dateObj.getMonth() + 3) / 3), // 季度
|
||||
'M+': dateObj.getMonth() + 1, // 月份
|
||||
'd+': dateObj.getDate(), // 日
|
||||
'h+': dateObj.getHours(), // 小时
|
||||
'm+': dateObj.getMinutes(), // 分
|
||||
's+': dateObj.getSeconds(), // 秒
|
||||
'q+': Math.floor((dateObj.getMonth() + 3) / 3), // 季度
|
||||
S: dateObj.getMilliseconds(), // 毫秒
|
||||
};
|
||||
}
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
(dateObj.getFullYear() + "").substr(4 - RegExp.$1.length),
|
||||
);
|
||||
fmt = fmt.replace(RegExp.$1, (dateObj.getFullYear() + '').substr(4 - RegExp.$1.length))
|
||||
}
|
||||
for (const k in o) {
|
||||
if (new RegExp("(" + k + ")").test(fmt)) {
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length == 1
|
||||
? o[k]
|
||||
: ("00" + o[k]).substr(("" + o[k]).length),
|
||||
);
|
||||
if (new RegExp('(' + k + ')').test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
};
|
||||
return fmt
|
||||
}
|
||||
|
||||
/* 千分符 */
|
||||
/**
|
||||
@@ -354,63 +328,51 @@ tool.dateFormat = function (date, fmt = "yyyy-MM-dd hh:mm:ss") {
|
||||
* @returns {string} - 格式化后的字符串
|
||||
*/
|
||||
tool.groupSeparator = function (num, decimals = 0) {
|
||||
if (num === null || num === undefined || num === "") return "";
|
||||
const numStr = Number(num).toFixed(decimals);
|
||||
const parts = numStr.split(".");
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
return parts.join(".");
|
||||
};
|
||||
if (num === null || num === undefined || num === '') return ''
|
||||
const numStr = Number(num).toFixed(decimals)
|
||||
const parts = numStr.split('.')
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
return parts.join('.')
|
||||
}
|
||||
|
||||
/* 常用加解密 */
|
||||
tool.crypto = {
|
||||
//MD5加密
|
||||
MD5(data) {
|
||||
return CryptoJS.MD5(data).toString();
|
||||
return CryptoJS.MD5(data).toString()
|
||||
},
|
||||
//BASE64加解密
|
||||
BASE64: {
|
||||
encrypt(data) {
|
||||
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data));
|
||||
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
|
||||
},
|
||||
decrypt(cipher) {
|
||||
return CryptoJS.enc.Base64.parse(cipher).toString(
|
||||
CryptoJS.enc.Utf8,
|
||||
);
|
||||
return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8)
|
||||
},
|
||||
},
|
||||
//AES加解密
|
||||
AES: {
|
||||
encrypt(data, secretKey, config = {}) {
|
||||
if (secretKey.length % 8 != 0) {
|
||||
console.warn(
|
||||
"[SCUI error]: 秘钥长度需为8的倍数,否则解密将会失败。",
|
||||
);
|
||||
console.warn('[SCUI error]: 秘钥长度需为8的倍数,否则解密将会失败。')
|
||||
}
|
||||
const result = CryptoJS.AES.encrypt(
|
||||
data,
|
||||
CryptoJS.enc.Utf8.parse(secretKey),
|
||||
{
|
||||
iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
|
||||
mode: CryptoJS.mode[config.mode || "ECB"],
|
||||
padding: CryptoJS.pad[config.padding || "Pkcs7"],
|
||||
},
|
||||
);
|
||||
return result.toString();
|
||||
const result = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(secretKey), {
|
||||
iv: CryptoJS.enc.Utf8.parse(config.iv || ''),
|
||||
mode: CryptoJS.mode[config.mode || 'ECB'],
|
||||
padding: CryptoJS.pad[config.padding || 'Pkcs7'],
|
||||
})
|
||||
return result.toString()
|
||||
},
|
||||
decrypt(cipher, secretKey, config = {}) {
|
||||
const result = CryptoJS.AES.decrypt(
|
||||
cipher,
|
||||
CryptoJS.enc.Utf8.parse(secretKey),
|
||||
{
|
||||
iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
|
||||
mode: CryptoJS.mode[config.mode || "ECB"],
|
||||
padding: CryptoJS.pad[config.padding || "Pkcs7"],
|
||||
},
|
||||
);
|
||||
return CryptoJS.enc.Utf8.stringify(result);
|
||||
const result = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Utf8.parse(secretKey), {
|
||||
iv: CryptoJS.enc.Utf8.parse(config.iv || ''),
|
||||
mode: CryptoJS.mode[config.mode || 'ECB'],
|
||||
padding: CryptoJS.pad[config.padding || 'Pkcs7'],
|
||||
})
|
||||
return CryptoJS.enc.Utf8.stringify(result)
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/* 树形数据转扁平数组 */
|
||||
/**
|
||||
@@ -419,22 +381,22 @@ tool.crypto = {
|
||||
* @param {Object} config - 配置项 { children: "children" }
|
||||
* @returns {Array} - 扁平化后的数组
|
||||
*/
|
||||
tool.treeToList = function (tree, config = { children: "children" }) {
|
||||
const result = [];
|
||||
tool.treeToList = function (tree, config = { children: 'children' }) {
|
||||
const result = []
|
||||
tree.forEach((item) => {
|
||||
const tmp = { ...item };
|
||||
const childrenKey = config.children || "children";
|
||||
const tmp = { ...item }
|
||||
const childrenKey = config.children || 'children'
|
||||
|
||||
if (tmp[childrenKey] && tmp[childrenKey].length > 0) {
|
||||
result.push({ ...item });
|
||||
const childrenRoutes = tool.treeToList(tmp[childrenKey], config);
|
||||
result.push(...childrenRoutes);
|
||||
result.push({ ...item })
|
||||
const childrenRoutes = tool.treeToList(tmp[childrenKey], config)
|
||||
result.push(...childrenRoutes)
|
||||
} else {
|
||||
result.push(tmp);
|
||||
result.push(tmp)
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
/* 获取父节点数据(保留原有函数名) */
|
||||
/**
|
||||
@@ -444,28 +406,24 @@ tool.treeToList = function (tree, config = { children: "children" }) {
|
||||
* @param {Object} config - 配置项 { pid: "parent_id", idField: "id", field: [] }
|
||||
* @returns {*} - 父节点数据或指定字段
|
||||
*/
|
||||
tool.get_parents = function (
|
||||
list,
|
||||
targetId = 0,
|
||||
config = { pid: "parent_id", idField: "id", field: [] },
|
||||
) {
|
||||
let res = null;
|
||||
tool.get_parents = function (list, targetId = 0, config = { pid: 'parent_id', idField: 'id', field: [] }) {
|
||||
let res = null
|
||||
list.forEach((item) => {
|
||||
if (item[config.idField || "id"] === targetId) {
|
||||
if (item[config.idField || 'id'] === targetId) {
|
||||
if (config.field && config.field.length > 1) {
|
||||
res = {};
|
||||
res = {}
|
||||
config.field.forEach((field) => {
|
||||
res[field] = item[field];
|
||||
});
|
||||
res[field] = item[field]
|
||||
})
|
||||
} else if (config.field && config.field.length === 1) {
|
||||
res = item[config.field[0]];
|
||||
res = item[config.field[0]]
|
||||
} else {
|
||||
res = item;
|
||||
res = item
|
||||
}
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
/* 获取数据字段 */
|
||||
/**
|
||||
@@ -475,25 +433,25 @@ tool.get_parents = function (
|
||||
* @returns {*} - 提取的字段数据
|
||||
*/
|
||||
tool.getDataField = function (data, fields = []) {
|
||||
if (!data || typeof data !== "object") {
|
||||
return data;
|
||||
if (!data || typeof data !== 'object') {
|
||||
return data
|
||||
}
|
||||
if (fields.length === 0) {
|
||||
return data;
|
||||
return data
|
||||
}
|
||||
if (fields.length === 1) {
|
||||
return data[fields[0]];
|
||||
return data[fields[0]]
|
||||
} else {
|
||||
const result = {};
|
||||
const result = {}
|
||||
fields.forEach((field) => {
|
||||
result[field] = data[field];
|
||||
});
|
||||
return result;
|
||||
result[field] = data[field]
|
||||
})
|
||||
return result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 兼容旧函数名
|
||||
tool.tree_to_list = tool.treeToList;
|
||||
tool.get_data_field = tool.getDataField;
|
||||
tool.tree_to_list = tool.treeToList
|
||||
tool.get_data_field = tool.getDataField
|
||||
|
||||
export default tool;
|
||||
export default tool
|
||||
|
||||
@@ -6,43 +6,43 @@
|
||||
|
||||
class WebSocketClient {
|
||||
constructor(url, options = {}) {
|
||||
this.url = url;
|
||||
this.ws = null;
|
||||
this.reconnectAttempts = 0;
|
||||
this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
|
||||
this.reconnectInterval = options.reconnectInterval || 3000;
|
||||
this.reconnectDelay = options.reconnectDelay || 1000;
|
||||
this.heartbeatInterval = options.heartbeatInterval || 30000;
|
||||
this.heartbeatTimer = null;
|
||||
this.isManualClose = false;
|
||||
this.isConnecting = false;
|
||||
this.url = url
|
||||
this.ws = null
|
||||
this.reconnectAttempts = 0
|
||||
this.maxReconnectAttempts = options.maxReconnectAttempts || 5
|
||||
this.reconnectInterval = options.reconnectInterval || 3000
|
||||
this.reconnectDelay = options.reconnectDelay || 1000
|
||||
this.heartbeatInterval = options.heartbeatInterval || 30000
|
||||
this.heartbeatTimer = null
|
||||
this.isManualClose = false
|
||||
this.isConnecting = false
|
||||
|
||||
// Event handlers
|
||||
this.onOpen = options.onOpen || null;
|
||||
this.onMessage = options.onMessage || null;
|
||||
this.onError = options.onError || null;
|
||||
this.onClose = options.onClose || null;
|
||||
this.onOpen = options.onOpen || null
|
||||
this.onMessage = options.onMessage || null
|
||||
this.onError = options.onError || null
|
||||
this.onClose = options.onClose || null
|
||||
|
||||
// Message handlers
|
||||
this.messageHandlers = new Map();
|
||||
this.messageHandlers = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection state description
|
||||
*/
|
||||
getConnectionState() {
|
||||
if (!this.ws) return "CLOSED";
|
||||
if (!this.ws) return 'CLOSED'
|
||||
switch (this.ws.readyState) {
|
||||
case WebSocket.CONNECTING:
|
||||
return "CONNECTING";
|
||||
return 'CONNECTING'
|
||||
case WebSocket.OPEN:
|
||||
return "OPEN";
|
||||
return 'OPEN'
|
||||
case WebSocket.CLOSING:
|
||||
return "CLOSING";
|
||||
return 'CLOSING'
|
||||
case WebSocket.CLOSED:
|
||||
return "CLOSED";
|
||||
return 'CLOSED'
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
return 'UNKNOWN'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,90 +50,84 @@ class WebSocketClient {
|
||||
* Connect to WebSocket server
|
||||
*/
|
||||
connect() {
|
||||
if (
|
||||
this.isConnecting ||
|
||||
(this.ws && this.ws.readyState === WebSocket.OPEN)
|
||||
) {
|
||||
return;
|
||||
if (this.isConnecting || (this.ws && this.ws.readyState === WebSocket.OPEN)) {
|
||||
return
|
||||
}
|
||||
|
||||
this.isConnecting = true;
|
||||
this.isManualClose = false;
|
||||
this.isConnecting = true
|
||||
this.isManualClose = false
|
||||
|
||||
try {
|
||||
this.ws = new WebSocket(this.url);
|
||||
this.ws = new WebSocket(this.url)
|
||||
|
||||
this.ws.onopen = (event) => {
|
||||
console.log("WebSocket connected", event);
|
||||
this.isConnecting = false;
|
||||
this.reconnectAttempts = 0;
|
||||
console.log('WebSocket connected', event)
|
||||
this.isConnecting = false
|
||||
this.reconnectAttempts = 0
|
||||
|
||||
// Start heartbeat
|
||||
this.startHeartbeat();
|
||||
this.startHeartbeat()
|
||||
|
||||
// Call onOpen handler
|
||||
if (this.onOpen) {
|
||||
this.onOpen(event);
|
||||
this.onOpen(event)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.ws.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
console.log("WebSocket message received", message);
|
||||
const message = JSON.parse(event.data)
|
||||
console.log('WebSocket message received', message)
|
||||
|
||||
// Handle different message types
|
||||
this.handleMessage(message);
|
||||
this.handleMessage(message)
|
||||
|
||||
// Call onMessage handler
|
||||
if (this.onMessage) {
|
||||
this.onMessage(message, event);
|
||||
this.onMessage(message, event)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to parse WebSocket message", error);
|
||||
console.error('Failed to parse WebSocket message', error)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.ws.onerror = (error) => {
|
||||
console.error("WebSocket error", error);
|
||||
this.isConnecting = false;
|
||||
console.error('WebSocket error', error)
|
||||
this.isConnecting = false
|
||||
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat();
|
||||
this.stopHeartbeat()
|
||||
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error);
|
||||
this.onError(error)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.ws.onclose = (event) => {
|
||||
console.log("WebSocket closed", event);
|
||||
this.isConnecting = false;
|
||||
console.log('WebSocket closed', event)
|
||||
this.isConnecting = false
|
||||
|
||||
// Stop heartbeat
|
||||
this.stopHeartbeat();
|
||||
this.stopHeartbeat()
|
||||
|
||||
// Call onClose handler
|
||||
if (this.onClose) {
|
||||
this.onClose(event);
|
||||
this.onClose(event)
|
||||
}
|
||||
|
||||
// Attempt to reconnect if not manually closed
|
||||
if (
|
||||
!this.isManualClose &&
|
||||
this.reconnectAttempts < this.maxReconnectAttempts
|
||||
) {
|
||||
this.reconnect();
|
||||
if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnect()
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to create WebSocket connection", error);
|
||||
this.isConnecting = false;
|
||||
console.error('Failed to create WebSocket connection', error)
|
||||
this.isConnecting = false
|
||||
|
||||
// Call onError handler
|
||||
if (this.onError) {
|
||||
this.onError(error);
|
||||
this.onError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,37 +136,31 @@ class WebSocketClient {
|
||||
* Reconnect to WebSocket server
|
||||
*/
|
||||
reconnect() {
|
||||
if (
|
||||
this.isConnecting ||
|
||||
this.reconnectAttempts >= this.maxReconnectAttempts
|
||||
) {
|
||||
console.log("Max reconnection attempts reached");
|
||||
return;
|
||||
if (this.isConnecting || this.reconnectAttempts >= this.maxReconnectAttempts) {
|
||||
console.log('Max reconnection attempts reached')
|
||||
return
|
||||
}
|
||||
|
||||
this.reconnectAttempts++;
|
||||
const delay =
|
||||
this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
||||
this.reconnectAttempts++
|
||||
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1)
|
||||
|
||||
console.log(
|
||||
`Reconnecting attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`,
|
||||
);
|
||||
console.log(`Reconnecting attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`)
|
||||
|
||||
setTimeout(() => {
|
||||
this.connect();
|
||||
}, delay);
|
||||
this.connect()
|
||||
}, delay)
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from WebSocket server
|
||||
*/
|
||||
disconnect() {
|
||||
this.isManualClose = true;
|
||||
this.stopHeartbeat();
|
||||
this.isManualClose = true
|
||||
this.stopHeartbeat()
|
||||
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
this.ws.close()
|
||||
this.ws = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,11 +172,11 @@ class WebSocketClient {
|
||||
const message = JSON.stringify({
|
||||
type,
|
||||
data,
|
||||
});
|
||||
this.ws.send(message);
|
||||
console.log("WebSocket message sent", { type, data });
|
||||
})
|
||||
this.ws.send(message)
|
||||
console.log('WebSocket message sent', { type, data })
|
||||
} else {
|
||||
console.warn("WebSocket is not connected");
|
||||
console.warn('WebSocket is not connected')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,12 +184,12 @@ class WebSocketClient {
|
||||
* Handle incoming messages
|
||||
*/
|
||||
handleMessage(message) {
|
||||
const { type, data } = message;
|
||||
const { type, data } = message
|
||||
|
||||
// Get handler for this message type
|
||||
const handler = this.messageHandlers.get(type);
|
||||
const handler = this.messageHandlers.get(type)
|
||||
if (handler) {
|
||||
handler(data);
|
||||
handler(data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,24 +197,24 @@ class WebSocketClient {
|
||||
* Register message handler
|
||||
*/
|
||||
on(messageType, handler) {
|
||||
this.messageHandlers.set(messageType, handler);
|
||||
this.messageHandlers.set(messageType, handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister message handler
|
||||
*/
|
||||
off(messageType) {
|
||||
this.messageHandlers.delete(messageType);
|
||||
this.messageHandlers.delete(messageType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Start heartbeat
|
||||
*/
|
||||
startHeartbeat() {
|
||||
this.stopHeartbeat();
|
||||
this.stopHeartbeat()
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
this.send("heartbeat", { timestamp: Date.now() });
|
||||
}, this.heartbeatInterval);
|
||||
this.send('heartbeat', { timestamp: Date.now() })
|
||||
}, this.heartbeatInterval)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,8 +222,8 @@ class WebSocketClient {
|
||||
*/
|
||||
stopHeartbeat() {
|
||||
if (this.heartbeatTimer) {
|
||||
clearInterval(this.heartbeatTimer);
|
||||
this.heartbeatTimer = null;
|
||||
clearInterval(this.heartbeatTimer)
|
||||
this.heartbeatTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,15 +231,15 @@ class WebSocketClient {
|
||||
* Get connection state
|
||||
*/
|
||||
get readyState() {
|
||||
if (!this.ws) return WebSocket.CLOSED;
|
||||
return this.ws.readyState;
|
||||
if (!this.ws) return WebSocket.CLOSED
|
||||
return this.ws.readyState
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if connected
|
||||
*/
|
||||
get isConnected() {
|
||||
return this.ws && this.ws.readyState === WebSocket.OPEN;
|
||||
return this.ws && this.ws.readyState === WebSocket.OPEN
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,61 +247,59 @@ class WebSocketClient {
|
||||
* Create WebSocket connection
|
||||
*/
|
||||
export function createWebSocket(userId, token, options = {}) {
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
|
||||
// 优先使用配置的 WS_URL,否则使用当前域名
|
||||
const host = options.wsUrl || window.location.host;
|
||||
const url = `${protocol}//${host}/ws?user_id=${userId}&token=${token}`;
|
||||
const host = options.wsUrl || window.location.host
|
||||
const url = `${protocol}//${host}/ws?user_id=${userId}&token=${token}`
|
||||
|
||||
return new WebSocketClient(url, options);
|
||||
return new WebSocketClient(url, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket singleton instance with connection management
|
||||
*/
|
||||
let wsClient = null;
|
||||
let currentUserId = null;
|
||||
let currentToken = null;
|
||||
let pendingConnection = null;
|
||||
let wsClient = null
|
||||
let currentUserId = null
|
||||
let currentToken = null
|
||||
let pendingConnection = null
|
||||
|
||||
export function getWebSocket(userId, token, options = {}) {
|
||||
// Check if we have a connection for the same user
|
||||
if (wsClient) {
|
||||
// If connection exists and user/token matches
|
||||
if (currentUserId === userId && currentToken === token) {
|
||||
const state = wsClient.getConnectionState();
|
||||
const state = wsClient.getConnectionState()
|
||||
|
||||
// If already connected or connecting, return existing instance
|
||||
if (state === "OPEN" || state === "CONNECTING") {
|
||||
console.log("WebSocket: Reusing existing connection", {
|
||||
if (state === 'OPEN' || state === 'CONNECTING') {
|
||||
console.log('WebSocket: Reusing existing connection', {
|
||||
state,
|
||||
userId: currentUserId,
|
||||
});
|
||||
return wsClient;
|
||||
})
|
||||
return wsClient
|
||||
}
|
||||
|
||||
// If connection is closed or closing, clean up
|
||||
if (state === "CLOSED" || state === "CLOSING") {
|
||||
console.log("WebSocket: Cleaning up closed connection");
|
||||
if (state === 'CLOSED' || state === 'CLOSING') {
|
||||
console.log('WebSocket: Cleaning up closed connection')
|
||||
if (wsClient.ws) {
|
||||
wsClient.ws.onopen = null;
|
||||
wsClient.ws.onmessage = null;
|
||||
wsClient.ws.onerror = null;
|
||||
wsClient.ws.onclose = null;
|
||||
wsClient.ws = null;
|
||||
wsClient.ws.onopen = null
|
||||
wsClient.ws.onmessage = null
|
||||
wsClient.ws.onerror = null
|
||||
wsClient.ws.onclose = null
|
||||
wsClient.ws = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Different user/token, disconnect old connection
|
||||
if (currentUserId !== userId || currentToken !== token) {
|
||||
console.log(
|
||||
"WebSocket: User changed, disconnecting old connection",
|
||||
);
|
||||
console.log('WebSocket: User changed, disconnecting old connection')
|
||||
if (wsClient) {
|
||||
wsClient.disconnect();
|
||||
wsClient.disconnect()
|
||||
}
|
||||
wsClient = null;
|
||||
wsClient = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,74 +308,74 @@ export function getWebSocket(userId, token, options = {}) {
|
||||
return new Promise((resolve) => {
|
||||
const checkPending = setInterval(() => {
|
||||
if (!pendingConnection) {
|
||||
clearInterval(checkPending);
|
||||
console.log("WebSocket: Pending connection completed");
|
||||
resolve(getWebSocket(userId, token, options));
|
||||
clearInterval(checkPending)
|
||||
console.log('WebSocket: Pending connection completed')
|
||||
resolve(getWebSocket(userId, token, options))
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
|
||||
// Create new connection
|
||||
console.log("WebSocket: Creating new connection", {
|
||||
console.log('WebSocket: Creating new connection', {
|
||||
userId,
|
||||
token: token ? "***" : null,
|
||||
});
|
||||
currentUserId = userId;
|
||||
currentToken = token;
|
||||
token: token ? '***' : null,
|
||||
})
|
||||
currentUserId = userId
|
||||
currentToken = token
|
||||
|
||||
pendingConnection = true;
|
||||
wsClient = createWebSocket(userId, token, options);
|
||||
pendingConnection = true
|
||||
wsClient = createWebSocket(userId, token, options)
|
||||
|
||||
// Mark connection as no longer pending when connected or failed
|
||||
const originalOnOpen = wsClient.onOpen;
|
||||
const originalOnError = wsClient.onError;
|
||||
const originalOnClose = wsClient.onClose;
|
||||
const originalOnOpen = wsClient.onOpen
|
||||
const originalOnError = wsClient.onError
|
||||
const originalOnClose = wsClient.onClose
|
||||
|
||||
wsClient.onOpen = (event) => {
|
||||
pendingConnection = null;
|
||||
console.log("WebSocket: Connection established", { userId });
|
||||
if (originalOnOpen) originalOnOpen(event);
|
||||
};
|
||||
pendingConnection = null
|
||||
console.log('WebSocket: Connection established', { userId })
|
||||
if (originalOnOpen) originalOnOpen(event)
|
||||
}
|
||||
|
||||
wsClient.onError = (error) => {
|
||||
pendingConnection = null;
|
||||
console.error("WebSocket: Connection error", { userId, error });
|
||||
if (originalOnError) originalOnError(error);
|
||||
};
|
||||
pendingConnection = null
|
||||
console.error('WebSocket: Connection error', { userId, error })
|
||||
if (originalOnError) originalOnError(error)
|
||||
}
|
||||
|
||||
wsClient.onClose = (event) => {
|
||||
pendingConnection = null;
|
||||
console.log("WebSocket: Connection closed", {
|
||||
pendingConnection = null
|
||||
console.log('WebSocket: Connection closed', {
|
||||
userId,
|
||||
code: event.code,
|
||||
reason: event.reason,
|
||||
});
|
||||
if (originalOnClose) originalOnClose(event);
|
||||
};
|
||||
})
|
||||
if (originalOnClose) originalOnClose(event)
|
||||
}
|
||||
|
||||
return wsClient;
|
||||
return wsClient
|
||||
}
|
||||
|
||||
export function closeWebSocket() {
|
||||
if (wsClient) {
|
||||
console.log("WebSocket: Closing connection manually");
|
||||
wsClient.disconnect();
|
||||
console.log('WebSocket: Closing connection manually')
|
||||
wsClient.disconnect()
|
||||
|
||||
// Clean up event handlers
|
||||
if (wsClient.ws) {
|
||||
wsClient.ws.onopen = null;
|
||||
wsClient.ws.onmessage = null;
|
||||
wsClient.ws.onerror = null;
|
||||
wsClient.ws.onclose = null;
|
||||
wsClient.ws = null;
|
||||
wsClient.ws.onopen = null
|
||||
wsClient.ws.onmessage = null
|
||||
wsClient.ws.onerror = null
|
||||
wsClient.ws.onclose = null
|
||||
wsClient.ws = null
|
||||
}
|
||||
|
||||
wsClient = null;
|
||||
currentUserId = null;
|
||||
currentToken = null;
|
||||
pendingConnection = null;
|
||||
wsClient = null
|
||||
currentUserId = null
|
||||
currentToken = null
|
||||
pendingConnection = null
|
||||
}
|
||||
}
|
||||
|
||||
export default WebSocketClient;
|
||||
export default WebSocketClient
|
||||
|
||||
Reference in New Issue
Block a user