初始化
This commit is contained in:
261
saiadmin-vue/src/utils/common.js
Normal file
261
saiadmin-vue/src/utils/common.js
Normal file
@@ -0,0 +1,261 @@
|
||||
import checkAuth from '@/directives/auth/auth'
|
||||
import checkRole from '@/directives/role/role'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
import { Notification, Message } from '@arco-design/web-vue'
|
||||
import { nextTick } from 'vue'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import router from '@/router'
|
||||
import { useTagStore, useKeepAliveStore } from '@/store'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export const refreshTag = () => {
|
||||
const route = router.currentRoute.value
|
||||
const keepStore = useKeepAliveStore()
|
||||
NProgress.start()
|
||||
keepStore.removeKeepAlive(route)
|
||||
keepStore.hidden()
|
||||
nextTick(() => {
|
||||
keepStore.addKeepAlive(route)
|
||||
keepStore.display()
|
||||
NProgress.done()
|
||||
})
|
||||
}
|
||||
|
||||
export const addTag = (tag) => {
|
||||
const tagStore = useTagStore()
|
||||
const keepStore = useKeepAliveStore()
|
||||
tagStore.addTag(tag)
|
||||
keepStore.addKeepAlive(tag)
|
||||
}
|
||||
|
||||
export const closeTag = (tag) => {
|
||||
const tagStore = useTagStore()
|
||||
const keepStore = useKeepAliveStore()
|
||||
const t = tagStore.removeTag(tag)
|
||||
keepStore.removeKeepAlive(tag)
|
||||
router.push({ path: t.path, query: tool.getRequestParams(t.path) })
|
||||
}
|
||||
|
||||
export const success = (title, content) => {
|
||||
Notification.success({ title, content, closable: true })
|
||||
}
|
||||
|
||||
export const info = (title, content) => {
|
||||
Notification.info({ title, content, closable: true })
|
||||
}
|
||||
|
||||
export const error = (title, content) => {
|
||||
Notification.error({ title, content, closable: true })
|
||||
}
|
||||
|
||||
// 检查权限函数
|
||||
export const auth = (name) => checkAuth(name)
|
||||
|
||||
// 检查角色函数
|
||||
export const role = (name) => checkRole(name)
|
||||
|
||||
// 复制
|
||||
export const copy = (text) => {
|
||||
try {
|
||||
useClipboard().toClipboard(text)
|
||||
Message.success('已成功复制到剪切板')
|
||||
} catch (e) {
|
||||
Message.error('复制失败')
|
||||
}
|
||||
}
|
||||
|
||||
function transitionJsonToString(jsonObj, callback) {
|
||||
// 转换后的jsonObj受体对象
|
||||
var _jsonObj = null
|
||||
// 判断传入的jsonObj对象是不是字符串,如果是字符串需要先转换为对象,再转换为字符串,这样做是为了保证转换后的字符串为双引号
|
||||
if (Object.prototype.toString.call(jsonObj) !== '[object String]') {
|
||||
try {
|
||||
_jsonObj = JSON.stringify(jsonObj)
|
||||
} catch (error) {
|
||||
// 转换失败错误信息
|
||||
console.error('您传递的json数据格式有误,请核对...')
|
||||
console.error(error)
|
||||
callback(error)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
jsonObj = jsonObj.replace(/(\')/g, '"')
|
||||
_jsonObj = JSON.stringify(JSON.parse(jsonObj))
|
||||
} catch (error) {
|
||||
// 转换失败错误信息
|
||||
console.error('您传递的json数据格式有误,请核对....')
|
||||
console.error(error)
|
||||
// callback(error);
|
||||
}
|
||||
}
|
||||
return _jsonObj
|
||||
}
|
||||
|
||||
export const formatJson = (jsonObj, callback) => {
|
||||
// 正则表达式匹配规则变量
|
||||
var reg = null
|
||||
// 转换后的字符串变量
|
||||
var formatted = ''
|
||||
// 换行缩进位数
|
||||
var pad = 0
|
||||
// 一个tab对应空格位数
|
||||
var PADDING = ' '
|
||||
// json对象转换为字符串变量
|
||||
var jsonString = transitionJsonToString(jsonObj, callback)
|
||||
if (!jsonString) {
|
||||
return jsonString
|
||||
}
|
||||
// 存储需要特殊处理的字符串段
|
||||
var _index = []
|
||||
// 存储需要特殊处理的“再数组中的开始位置变量索引
|
||||
var _indexStart = null
|
||||
// 存储需要特殊处理的“再数组中的结束位置变量索引
|
||||
var _indexEnd = null
|
||||
// 将jsonString字符串内容通过\r\n符分割成数组
|
||||
var jsonArray = []
|
||||
// 正则匹配到{,}符号则在两边添加回车换行
|
||||
jsonString = jsonString.replace(/([\{\}])/g, '\r\n$1\r\n')
|
||||
// 正则匹配到[,]符号则在两边添加回车换行
|
||||
jsonString = jsonString.replace(/([\[\]])/g, '\r\n$1\r\n')
|
||||
// 正则匹配到,符号则在两边添加回车换行
|
||||
jsonString = jsonString.replace(/(\,)/g, '$1\r\n')
|
||||
// 正则匹配到要超过一行的换行需要改为一行
|
||||
jsonString = jsonString.replace(/(\r\n\r\n)/g, '\r\n')
|
||||
// 正则匹配到单独处于一行的,符号时需要去掉换行,将,置于同行
|
||||
jsonString = jsonString.replace(/\r\n\,/g, ',')
|
||||
// 特殊处理双引号中的内容
|
||||
jsonArray = jsonString.split('\r\n')
|
||||
jsonArray.forEach(function (node, index) {
|
||||
// 获取当前字符串段中"的数量
|
||||
var num = node.match(/\"/g) ? node.match(/\"/g).length : 0
|
||||
// 判断num是否为奇数来确定是否需要特殊处理
|
||||
if (num % 2 && !_indexStart) {
|
||||
_indexStart = index
|
||||
}
|
||||
if (num % 2 && _indexStart && _indexStart != index) {
|
||||
_indexEnd = index
|
||||
}
|
||||
// 将需要特殊处理的字符串段的其实位置和结束位置信息存入,并对应重置开始时和结束变量
|
||||
if (_indexStart && _indexEnd) {
|
||||
_index.push({
|
||||
start: _indexStart,
|
||||
end: _indexEnd
|
||||
})
|
||||
_indexStart = null
|
||||
_indexEnd = null
|
||||
}
|
||||
})
|
||||
// 开始处理双引号中的内容,将多余的"去除
|
||||
_index.reverse().forEach(function (item, index) {
|
||||
var newArray = jsonArray.slice(item.start, item.end + 1)
|
||||
jsonArray.splice(item.start, item.end + 1 - item.start, newArray.join(''))
|
||||
})
|
||||
// 奖处理后的数组通过\r\n连接符重组为字符串
|
||||
jsonString = jsonArray.join('\r\n')
|
||||
// 将匹配到:后为回车换行加大括号替换为冒号加大括号
|
||||
jsonString = jsonString.replace(/\:\r\n\{/g, ':{')
|
||||
// 将匹配到:后为回车换行加中括号替换为冒号加中括号
|
||||
jsonString = jsonString.replace(/\:\r\n\[/g, ':[')
|
||||
// 将上述转换后的字符串再次以\r\n分割成数组
|
||||
jsonArray = jsonString.split('\r\n')
|
||||
// 将转换完成的字符串根据PADDING值来组合成最终的形态
|
||||
jsonArray.forEach(function (item, index) {
|
||||
// console.log(item);
|
||||
var i = 0
|
||||
// 表示缩进的位数,以tab作为计数单位
|
||||
var indent = 0
|
||||
// 表示缩进的位数,以空格作为计数单位
|
||||
var padding = ''
|
||||
if (item.match(/\{$/) || item.match(/\[$/)) {
|
||||
// 匹配到以{和[结尾的时候indent加1
|
||||
indent += 1
|
||||
} else if (
|
||||
item.match(/\}$/) ||
|
||||
item.match(/\]$/) ||
|
||||
item.match(/\},$/) ||
|
||||
item.match(/\],$/)
|
||||
) {
|
||||
// 匹配到以}和]结尾的时候indent减1
|
||||
if (pad !== 0) {
|
||||
pad -= 1
|
||||
}
|
||||
} else {
|
||||
indent = 0
|
||||
}
|
||||
for (i = 0; i < pad; i++) {
|
||||
padding += PADDING
|
||||
}
|
||||
formatted += padding + item + '\n'
|
||||
pad += indent
|
||||
})
|
||||
// 返回的数据需要去除两边的空格
|
||||
return formatted.trim()
|
||||
}
|
||||
|
||||
// 判断是否弹出层全屏
|
||||
export const setModalSizeEvent = (callback) => {
|
||||
callback({ isFull: window.screen.width < 768, width: window.screen.width })
|
||||
}
|
||||
// 加载远程js
|
||||
export const loadScript = (src, callback) => {
|
||||
const s = document.createElement('script')
|
||||
s.type = 'text/javascript'
|
||||
s.src = src
|
||||
s.onload = s.onreadystatechange = function () {
|
||||
if (
|
||||
!this.readyState ||
|
||||
this.readyState === 'loaded' ||
|
||||
this.readyState === 'complete'
|
||||
) {
|
||||
callback && callback()
|
||||
s.onload = s.onreadystatechange = null
|
||||
}
|
||||
}
|
||||
document.body.appendChild(s)
|
||||
}
|
||||
|
||||
// 加载远程css
|
||||
export const loadCss = (href, callback) => {
|
||||
const s = document.createElement('link')
|
||||
s.type = 'text/css'
|
||||
s.rel = 'stylesheet'
|
||||
s.media = 'all'
|
||||
s.href = href
|
||||
s.onload = s.onreadystatechange = function () {
|
||||
if (
|
||||
!this.readyState ||
|
||||
this.readyState === 'loaded' ||
|
||||
this.readyState === 'complete'
|
||||
) {
|
||||
callback && callback()
|
||||
s.onload = s.onreadystatechange = null
|
||||
}
|
||||
}
|
||||
document.body.appendChild(s)
|
||||
}
|
||||
|
||||
export const discount = (discount, price) => {
|
||||
return (
|
||||
(price * (discount === '0.00' || discount === 0 ? 10 : discount)) /
|
||||
10
|
||||
).toFixed(2)
|
||||
}
|
||||
|
||||
export const versionCompare = (v1, v2) => {
|
||||
// 将版本号转换成数字数组
|
||||
v1 = v1.split('.')
|
||||
v2 = v2.split('.')
|
||||
// 对齐版本号的长度
|
||||
while (v1.length < v2.length) v1.push('0')
|
||||
while (v2.length < v1.length) v2.push('0')
|
||||
// 转换成数字数组
|
||||
v1 = v1.map(Number)
|
||||
v2 = v2.map(Number)
|
||||
|
||||
for (let i = 0; i < v1.length; i++) {
|
||||
if (v1[i] < v2[i]) return -1 // v1 < v2
|
||||
if (v1[i] > v2[i]) return 1 // v1 > v2
|
||||
}
|
||||
return 0 // v1 == v2
|
||||
}
|
||||
135
saiadmin-vue/src/utils/print.js
Normal file
135
saiadmin-vue/src/utils/print.js
Normal file
@@ -0,0 +1,135 @@
|
||||
// 打印类属性、方法定义
|
||||
/* eslint-disable */
|
||||
|
||||
class Print
|
||||
{
|
||||
dom = null
|
||||
|
||||
options = {}
|
||||
|
||||
constructor (dom, options = {}) {
|
||||
// if (!(this instanceof Print)) return new Print(dom, options)
|
||||
|
||||
this.options = this.extend({ 'noPrint': '.no-print' }, options)
|
||||
|
||||
if ( typeof dom === 'string' ) {
|
||||
try {
|
||||
this.dom = document.querySelector(dom)
|
||||
} catch {
|
||||
this.dom = document.createElement('div')
|
||||
this.dom.innerHTML = dom
|
||||
}
|
||||
} else {
|
||||
this.isDOM(dom)
|
||||
this.dom = this.isDOM(dom) ? dom : dom.$el
|
||||
}
|
||||
|
||||
this.init()
|
||||
}
|
||||
|
||||
init () {
|
||||
this.writeIframe(this.getStyle() + this.getHtml())
|
||||
}
|
||||
|
||||
extend (obj, obj2) {
|
||||
for (let key in obj2) {
|
||||
obj[key] = obj2[key]
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
getStyle () {
|
||||
let str = '', styles = document.querySelectorAll('style,link')
|
||||
for (let i = 0; i < styles.length; i++) {
|
||||
str += styles[i].outerHTML
|
||||
}
|
||||
str += '<style>' + (this.options.noPrint ? this.options.noPrint : '.no-print') + '{ display: none; }</style>'
|
||||
str += '<style>html, body{ background-color: #fff; }</style>'
|
||||
return str
|
||||
}
|
||||
|
||||
getHtml () {
|
||||
const inputs = document.querySelectorAll('input');
|
||||
const textAreas = document.querySelectorAll('textarea');
|
||||
const selects = document.querySelectorAll('select');
|
||||
|
||||
for (let k = 0; k < inputs.length; k++) {
|
||||
if (inputs[k].type === 'checkbox' || inputs[k].type === 'radio') {
|
||||
if (inputs[k].checked === true) {
|
||||
inputs[k].setAttribute('checked', "checked")
|
||||
} else {
|
||||
inputs[k].removeAttribute('checked')
|
||||
}
|
||||
} else if (inputs[k].type === 'text') {
|
||||
inputs[k].setAttribute('value', inputs[k].value)
|
||||
} else {
|
||||
inputs[k].setAttribute('value', inputs[k].value)
|
||||
}
|
||||
}
|
||||
|
||||
for (let k = 0; k < textAreas.length; k++) {
|
||||
if (textAreas[k].type === 'textarea') {
|
||||
textAreas[k].innerHTML = textAreas[k].value
|
||||
}
|
||||
}
|
||||
|
||||
for (let k = 0; k < selects.length; k++) {
|
||||
if (selects[k].type === 'select-one') {
|
||||
let child = selects[k].children;
|
||||
for (let i in child) {
|
||||
if (child[i].tagName === 'OPTION') {
|
||||
if (child[i].selected === true) {
|
||||
child[i].setAttribute('selected', "selected")
|
||||
} else {
|
||||
child[i].removeAttribute('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.dom.outerHTML
|
||||
}
|
||||
|
||||
writeIframe (content) {
|
||||
let w, doc, iframe = document.createElement('iframe'), f = document.body.appendChild(iframe)
|
||||
iframe.id = 'myIframe'
|
||||
iframe.setAttribute('style', 'position:absolute; width:0; height:0; top:-10px; left:-10px;')
|
||||
w = f.contentWindow ?? f.contentDocument
|
||||
doc = f.contentDocument ?? f.contentWindow.document
|
||||
doc.open()
|
||||
doc.write(content)
|
||||
doc.close()
|
||||
const _this = this
|
||||
iframe.onload = () => {
|
||||
_this.toPrint(w)
|
||||
setTimeout(() => { document.body.removeChild(iframe) }, 100)
|
||||
}
|
||||
}
|
||||
|
||||
toPrint (frameWindow) {
|
||||
try {
|
||||
setTimeout(() => {
|
||||
frameWindow.focus()
|
||||
try {
|
||||
if (! frameWindow.document.execCommand('print', false, null)) {
|
||||
frameWindow.print()
|
||||
}
|
||||
} catch (e) {
|
||||
frameWindow.print()
|
||||
}
|
||||
frameWindow.close()
|
||||
}, 10)
|
||||
} catch (err) {
|
||||
console.log('err', err)
|
||||
}
|
||||
}
|
||||
|
||||
isDOM (obj) {
|
||||
return (typeof HTMLElement === 'object')
|
||||
? obj instanceof HTMLElement
|
||||
: obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string'
|
||||
}
|
||||
}
|
||||
|
||||
export default Print
|
||||
732
saiadmin-vue/src/utils/push-vue.js
Normal file
732
saiadmin-vue/src/utils/push-vue.js
Normal file
@@ -0,0 +1,732 @@
|
||||
|
||||
export const Push = function (options) {
|
||||
this.doNotConnect = 0;
|
||||
options = options || {};
|
||||
options.heartbeat = options.heartbeat || 25000;
|
||||
options.pingTimeout = options.pingTimeout || 10000;
|
||||
this.config = options;
|
||||
this.uid = 0;
|
||||
this.channels = {};
|
||||
this.connection = null;
|
||||
this.pingTimeoutTimer = 0;
|
||||
Push.instances.push(this);
|
||||
this.createConnection();
|
||||
}
|
||||
|
||||
Push.prototype.checkoutPing = function () {
|
||||
var _this = this;
|
||||
setTimeout(function () {
|
||||
if (_this.connection.state === 'connected') {
|
||||
_this.connection.send('{"event":"pusher:ping","data":{}}');
|
||||
if (_this.pingTimeoutTimer) {
|
||||
clearTimeout(_this.pingTimeoutTimer);
|
||||
_this.pingTimeoutTimer = 0;
|
||||
}
|
||||
_this.pingTimeoutTimer = setTimeout(function () {
|
||||
_this.connection.closeAndClean();
|
||||
if (!_this.connection.doNotConnect) {
|
||||
_this.connection.waitReconnect();
|
||||
}
|
||||
}, _this.config.pingTimeout);
|
||||
}
|
||||
}, this.config.heartbeat);
|
||||
};
|
||||
|
||||
Push.prototype.channel = function (name) {
|
||||
return this.channels.find(name);
|
||||
};
|
||||
|
||||
Push.prototype.allChannels = function () {
|
||||
return this.channels.all();
|
||||
};
|
||||
|
||||
Push.prototype.createConnection = function () {
|
||||
if (this.connection) {
|
||||
throw Error('Connection already exist');
|
||||
}
|
||||
var _this = this;
|
||||
var url = this.config.url;
|
||||
function updateSubscribed() {
|
||||
for (var i in _this.channels) {
|
||||
_this.channels[i].subscribed = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.connection = new Connection({
|
||||
url: url,
|
||||
app_key: this.config.app_key,
|
||||
onOpen: function () {
|
||||
_this.connection.state = 'connecting';
|
||||
_this.checkoutPing();
|
||||
},
|
||||
onMessage: function (params) {
|
||||
if (_this.pingTimeoutTimer) {
|
||||
clearTimeout(_this.pingTimeoutTimer);
|
||||
_this.pingTimeoutTimer = 0;
|
||||
}
|
||||
|
||||
params = JSON.parse(params.data);
|
||||
var event = params.event;
|
||||
var channel_name = params.channel;
|
||||
|
||||
if (event === 'pusher:pong') {
|
||||
_this.checkoutPing();
|
||||
return;
|
||||
}
|
||||
if (event === 'pusher:error') {
|
||||
throw Error(params.data.message);
|
||||
}
|
||||
var data = JSON.parse(params.data), channel;
|
||||
if (event === 'pusher_internal:subscription_succeeded') {
|
||||
channel = _this.channels[channel_name];
|
||||
channel.subscribed = true;
|
||||
channel.processQueue();
|
||||
channel.emit('pusher:subscription_succeeded');
|
||||
return;
|
||||
}
|
||||
if (event === 'pusher:connection_established') {
|
||||
_this.connection.socket_id = data.socket_id;
|
||||
_this.connection.state = 'connected';
|
||||
_this.subscribeAll();
|
||||
}
|
||||
if (event.indexOf('pusher_internal') !== -1) {
|
||||
console.log("Event '" + event + "' not implement");
|
||||
return;
|
||||
}
|
||||
channel = _this.channels[channel_name];
|
||||
if (channel) {
|
||||
channel.emit(event, data);
|
||||
}
|
||||
},
|
||||
onClose: function () {
|
||||
updateSubscribed();
|
||||
},
|
||||
onError: function () {
|
||||
updateSubscribed();
|
||||
}
|
||||
});
|
||||
};
|
||||
Push.prototype.disconnect = function () {
|
||||
this.connection.doNotConnect = 1;
|
||||
this.connection.close();
|
||||
};
|
||||
|
||||
Push.prototype.subscribeAll = function () {
|
||||
if (this.connection.state !== 'connected') {
|
||||
return;
|
||||
}
|
||||
for (var channel_name in this.channels) {
|
||||
//this.connection.send(JSON.stringify({event:"pusher:subscribe", data:{channel:channel_name}}));
|
||||
this.channels[channel_name].processSubscribe();
|
||||
}
|
||||
};
|
||||
|
||||
Push.prototype.unsubscribe = function (channel_name) {
|
||||
if (this.channels[channel_name]) {
|
||||
delete this.channels[channel_name];
|
||||
if (this.connection.state === 'connected') {
|
||||
this.connection.send(JSON.stringify({ event: "pusher:unsubscribe", data: { channel: channel_name } }));
|
||||
}
|
||||
}
|
||||
};
|
||||
Push.prototype.unsubscribeAll = function () {
|
||||
var channels = Object.keys(this.channels);
|
||||
if (channels.length) {
|
||||
if (this.connection.state === 'connected') {
|
||||
for (var channel_name in this.channels) {
|
||||
this.unsubscribe(channel_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.channels = {};
|
||||
};
|
||||
Push.prototype.subscribe = function (channel_name) {
|
||||
if (this.channels[channel_name]) {
|
||||
return this.channels[channel_name];
|
||||
}
|
||||
if (channel_name.indexOf('private-') === 0) {
|
||||
return createPrivateChannel(channel_name, this);
|
||||
}
|
||||
if (channel_name.indexOf('presence-') === 0) {
|
||||
return createPresenceChannel(channel_name, this);
|
||||
}
|
||||
return createChannel(channel_name, this);
|
||||
};
|
||||
Push.instances = [];
|
||||
|
||||
function createChannel(channel_name, push) {
|
||||
var channel = new Channel(push.connection, channel_name);
|
||||
push.channels[channel_name] = channel;
|
||||
channel.subscribeCb = function () {
|
||||
push.connection.send(JSON.stringify({ event: "pusher:subscribe", data: { channel: channel_name } }));
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
function createPrivateChannel(channel_name, push) {
|
||||
var channel = new Channel(push.connection, channel_name);
|
||||
push.channels[channel_name] = channel;
|
||||
channel.subscribeCb = function () {
|
||||
__ajax({
|
||||
url: push.config.auth,
|
||||
type: 'POST',
|
||||
data: { channel_name: channel_name, socket_id: push.connection.socket_id },
|
||||
success: function (data) {
|
||||
data = JSON.parse(data);
|
||||
data.channel = channel_name;
|
||||
push.connection.send(JSON.stringify({ event: "pusher:subscribe", data: data }));
|
||||
},
|
||||
error: function (e) {
|
||||
throw Error(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
channel.processSubscribe();
|
||||
return channel;
|
||||
}
|
||||
|
||||
function createPresenceChannel(channel_name, push) {
|
||||
return createPrivateChannel(channel_name, push);
|
||||
}
|
||||
|
||||
function Connection(options) {
|
||||
this.dispatcher = new Dispatcher();
|
||||
__extends(this, this.dispatcher);
|
||||
var properies = ['on', 'off', 'emit'];
|
||||
for (var i in properies) {
|
||||
this[properies[i]] = this.dispatcher[properies[i]];
|
||||
}
|
||||
this.options = options;
|
||||
this.state = 'initialized'; //initialized connecting connected disconnected
|
||||
this.doNotConnect = 0;
|
||||
this.reconnectInterval = 1;
|
||||
this.connection = null;
|
||||
this.reconnectTimer = 0;
|
||||
this.connect();
|
||||
}
|
||||
|
||||
Connection.prototype.updateNetworkState = function (state) {
|
||||
var old_state = this.state;
|
||||
this.state = state;
|
||||
if (old_state !== state) {
|
||||
this.emit('state_change', { previous: old_state, current: state });
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.connect = function () {
|
||||
this.doNotConnect = 0;
|
||||
if (this.state === 'connected') {
|
||||
console.log('networkState is "' + this.state + '" and do not need connect');
|
||||
return;
|
||||
}
|
||||
if (this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer);
|
||||
this.reconnectTimer = 0;
|
||||
}
|
||||
|
||||
this.closeAndClean();
|
||||
|
||||
var options = this.options;
|
||||
var websocket = new WebSocket(options.url + '/app/' + options.app_key);
|
||||
|
||||
this.updateNetworkState('connecting');
|
||||
|
||||
var _this = this;
|
||||
websocket.onopen = function (res) {
|
||||
_this.reconnectInterval = 1;
|
||||
if (_this.doNotConnect) {
|
||||
_this.updateNetworkState('disconnected');
|
||||
websocket.close();
|
||||
return;
|
||||
}
|
||||
if (options.onOpen) {
|
||||
options.onOpen(res);
|
||||
}
|
||||
};
|
||||
|
||||
if (options.onMessage) {
|
||||
websocket.onmessage = options.onMessage;
|
||||
}
|
||||
|
||||
websocket.onclose = function (res) {
|
||||
websocket.onmessage = websocket.onopen = websocket.onclose = websocket.onerror = null;
|
||||
_this.updateNetworkState('disconnected');
|
||||
if (!_this.doNotConnect) {
|
||||
_this.waitReconnect();
|
||||
}
|
||||
if (options.onClose) {
|
||||
options.onClose(res);
|
||||
}
|
||||
};
|
||||
|
||||
websocket.onerror = function (res) {
|
||||
_this.close();
|
||||
if (!_this.doNotConnect) {
|
||||
_this.waitReconnect();
|
||||
}
|
||||
if (options.onError) {
|
||||
options.onError(res);
|
||||
}
|
||||
};
|
||||
this.connection = websocket;
|
||||
}
|
||||
|
||||
Connection.prototype.closeAndClean = function () {
|
||||
if (this.connection) {
|
||||
var websocket = this.connection;
|
||||
websocket.onmessage = websocket.onopen = websocket.onclose = websocket.onerror = null;
|
||||
try {
|
||||
websocket.close();
|
||||
} catch (e) { }
|
||||
this.updateNetworkState('disconnected');
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.waitReconnect = function () {
|
||||
if (this.state === 'connected' || this.state === 'connecting') {
|
||||
return;
|
||||
}
|
||||
if (!this.doNotConnect) {
|
||||
this.updateNetworkState('connecting');
|
||||
var _this = this;
|
||||
if (this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer);
|
||||
}
|
||||
this.reconnectTimer = setTimeout(function () {
|
||||
_this.connect();
|
||||
}, this.reconnectInterval);
|
||||
if (this.reconnectInterval < 1000) {
|
||||
this.reconnectInterval = 1000;
|
||||
} else {
|
||||
// 每次重连间隔增大一倍
|
||||
this.reconnectInterval = this.reconnectInterval * 2;
|
||||
}
|
||||
// 有网络的状态下,重连间隔最大2秒
|
||||
if (this.reconnectInterval > 2000 && navigator.onLine) {
|
||||
_this.reconnectInterval = 2000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connection.prototype.send = function (data) {
|
||||
if (this.state !== 'connected') {
|
||||
console.trace('networkState is "' + this.state + '", can not send ' + data);
|
||||
return;
|
||||
}
|
||||
this.connection.send(data);
|
||||
}
|
||||
|
||||
Connection.prototype.close = function () {
|
||||
this.updateNetworkState('disconnected');
|
||||
this.connection.close();
|
||||
}
|
||||
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) { d[p] = b[p]; }
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
|
||||
function Channel(connection, channel_name) {
|
||||
this.subscribed = false;
|
||||
this.dispatcher = new Dispatcher();
|
||||
this.connection = connection;
|
||||
this.channelName = channel_name;
|
||||
this.subscribeCb = null;
|
||||
this.queue = [];
|
||||
__extends(this, this.dispatcher);
|
||||
var properies = ['on', 'off', 'emit'];
|
||||
for (var i in properies) {
|
||||
this[properies[i]] = this.dispatcher[properies[i]];
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.processSubscribe = function () {
|
||||
if (this.connection.state !== 'connected') {
|
||||
return;
|
||||
}
|
||||
this.subscribeCb();
|
||||
};
|
||||
|
||||
Channel.prototype.processQueue = function () {
|
||||
if (this.connection.state !== 'connected' || !this.subscribed) {
|
||||
return;
|
||||
}
|
||||
for (var i in this.queue) {
|
||||
this.queue[i]();
|
||||
}
|
||||
this.queue = [];
|
||||
};
|
||||
|
||||
Channel.prototype.trigger = function (event, data) {
|
||||
if (event.indexOf('client-') !== 0) {
|
||||
throw new Error("Event '" + event + "' should start with 'client-'");
|
||||
}
|
||||
var _this = this;
|
||||
this.queue.push(function () {
|
||||
_this.connection.send(JSON.stringify({ event: event, data: data, channel: _this.channelName }));
|
||||
});
|
||||
this.processQueue();
|
||||
};
|
||||
|
||||
////////////////
|
||||
var Collections = (function () {
|
||||
var exports = {};
|
||||
function extend(target) {
|
||||
var sources = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
sources[_i - 1] = arguments[_i];
|
||||
}
|
||||
for (var i = 0; i < sources.length; i++) {
|
||||
var extensions = sources[i];
|
||||
for (var property in extensions) {
|
||||
if (extensions[property] && extensions[property].constructor &&
|
||||
extensions[property].constructor === Object) {
|
||||
target[property] = extend(target[property] || {}, extensions[property]);
|
||||
}
|
||||
else {
|
||||
target[property] = extensions[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
exports.extend = extend;
|
||||
function stringify() {
|
||||
var m = ["Push"];
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (typeof arguments[i] === "string") {
|
||||
m.push(arguments[i]);
|
||||
}
|
||||
else {
|
||||
m.push(safeJSONStringify(arguments[i]));
|
||||
}
|
||||
}
|
||||
return m.join(" : ");
|
||||
}
|
||||
|
||||
exports.stringify = stringify;
|
||||
function arrayIndexOf(array, item) {
|
||||
var nativeIndexOf = Array.prototype.indexOf;
|
||||
if (array === null) {
|
||||
return -1;
|
||||
}
|
||||
if (nativeIndexOf && array.indexOf === nativeIndexOf) {
|
||||
return array.indexOf(item);
|
||||
}
|
||||
for (var i = 0, l = array.length; i < l; i++) {
|
||||
if (array[i] === item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
exports.arrayIndexOf = arrayIndexOf;
|
||||
function objectApply(object, f) {
|
||||
for (var key in object) {
|
||||
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
||||
f(object[key], key, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.objectApply = objectApply;
|
||||
function keys(object) {
|
||||
var keys = [];
|
||||
objectApply(object, function (_, key) {
|
||||
keys.push(key);
|
||||
});
|
||||
return keys;
|
||||
}
|
||||
|
||||
exports.keys = keys;
|
||||
function values(object) {
|
||||
var values = [];
|
||||
objectApply(object, function (value) {
|
||||
values.push(value);
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
exports.values = values;
|
||||
function apply(array, f, context) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
f.call(context || (window), array[i], i, array);
|
||||
}
|
||||
}
|
||||
|
||||
exports.apply = apply;
|
||||
function map(array, f) {
|
||||
var result = [];
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
result.push(f(array[i], i, array, result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.map = map;
|
||||
function mapObject(object, f) {
|
||||
var result = {};
|
||||
objectApply(object, function (value, key) {
|
||||
result[key] = f(value);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.mapObject = mapObject;
|
||||
function filter(array, test) {
|
||||
test = test || function (value) {
|
||||
return !!value;
|
||||
};
|
||||
var result = [];
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (test(array[i], i, array, result)) {
|
||||
result.push(array[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.filter = filter;
|
||||
function filterObject(object, test) {
|
||||
var result = {};
|
||||
objectApply(object, function (value, key) {
|
||||
if ((test && test(value, key, object, result)) || Boolean(value)) {
|
||||
result[key] = value;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.filterObject = filterObject;
|
||||
function flatten(object) {
|
||||
var result = [];
|
||||
objectApply(object, function (value, key) {
|
||||
result.push([key, value]);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.flatten = flatten;
|
||||
function any(array, test) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (test(array[i], i, array)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
exports.any = any;
|
||||
function all(array, test) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (!test(array[i], i, array)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
exports.all = all;
|
||||
function encodeParamsObject(data) {
|
||||
return mapObject(data, function (value) {
|
||||
if (typeof value === "object") {
|
||||
value = safeJSONStringify(value);
|
||||
}
|
||||
return encodeURIComponent(base64_1["default"](value.toString()));
|
||||
});
|
||||
}
|
||||
|
||||
exports.encodeParamsObject = encodeParamsObject;
|
||||
function buildQueryString(data) {
|
||||
var params = filterObject(data, function (value) {
|
||||
return value !== undefined;
|
||||
});
|
||||
return map(flatten(encodeParamsObject(params)), util_1["default"].method("join", "=")).join("&");
|
||||
}
|
||||
|
||||
exports.buildQueryString = buildQueryString;
|
||||
function decycleObject(object) {
|
||||
var objects = [], paths = [];
|
||||
return (function derez(value, path) {
|
||||
var i, name, nu;
|
||||
switch (typeof value) {
|
||||
case 'object':
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
for (i = 0; i < objects.length; i += 1) {
|
||||
if (objects[i] === value) {
|
||||
return { $ref: paths[i] };
|
||||
}
|
||||
}
|
||||
objects.push(value);
|
||||
paths.push(path);
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
nu = [];
|
||||
for (i = 0; i < value.length; i += 1) {
|
||||
nu[i] = derez(value[i], path + '[' + i + ']');
|
||||
}
|
||||
}
|
||||
else {
|
||||
nu = {};
|
||||
for (name in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, name)) {
|
||||
nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']');
|
||||
}
|
||||
}
|
||||
}
|
||||
return nu;
|
||||
case 'number':
|
||||
case 'string':
|
||||
case 'boolean':
|
||||
return value;
|
||||
}
|
||||
}(object, '$'));
|
||||
}
|
||||
|
||||
exports.decycleObject = decycleObject;
|
||||
function safeJSONStringify(source) {
|
||||
try {
|
||||
return JSON.stringify(source);
|
||||
}
|
||||
catch (e) {
|
||||
return JSON.stringify(decycleObject(source));
|
||||
}
|
||||
}
|
||||
|
||||
exports.safeJSONStringify = safeJSONStringify;
|
||||
return exports;
|
||||
})();
|
||||
|
||||
var Dispatcher = (function () {
|
||||
function Dispatcher(failThrough) {
|
||||
this.callbacks = new CallbackRegistry();
|
||||
this.global_callbacks = [];
|
||||
this.failThrough = failThrough;
|
||||
}
|
||||
Dispatcher.prototype.on = function (eventName, callback, context) {
|
||||
this.callbacks.add(eventName, callback, context);
|
||||
return this;
|
||||
};
|
||||
Dispatcher.prototype.on_global = function (callback) {
|
||||
this.global_callbacks.push(callback);
|
||||
return this;
|
||||
};
|
||||
Dispatcher.prototype.off = function (eventName, callback, context) {
|
||||
this.callbacks.remove(eventName, callback, context);
|
||||
return this;
|
||||
};
|
||||
Dispatcher.prototype.emit = function (eventName, data) {
|
||||
var i;
|
||||
for (i = 0; i < this.global_callbacks.length; i++) {
|
||||
this.global_callbacks[i](eventName, data);
|
||||
}
|
||||
var callbacks = this.callbacks.get(eventName);
|
||||
if (callbacks && callbacks.length > 0) {
|
||||
for (i = 0; i < callbacks.length; i++) {
|
||||
callbacks[i].fn.call(callbacks[i].context || (window), data);
|
||||
}
|
||||
}
|
||||
else if (this.failThrough) {
|
||||
this.failThrough(eventName, data);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
return Dispatcher;
|
||||
}());
|
||||
|
||||
var CallbackRegistry = (function () {
|
||||
function CallbackRegistry() {
|
||||
this._callbacks = {};
|
||||
}
|
||||
CallbackRegistry.prototype.get = function (name) {
|
||||
return this._callbacks[prefix(name)];
|
||||
};
|
||||
CallbackRegistry.prototype.add = function (name, callback, context) {
|
||||
var prefixedEventName = prefix(name);
|
||||
this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
|
||||
this._callbacks[prefixedEventName].push({
|
||||
fn: callback,
|
||||
context: context
|
||||
});
|
||||
};
|
||||
CallbackRegistry.prototype.remove = function (name, callback, context) {
|
||||
if (!name && !callback && !context) {
|
||||
this._callbacks = {};
|
||||
return;
|
||||
}
|
||||
var names = name ? [prefix(name)] : Collections.keys(this._callbacks);
|
||||
if (callback || context) {
|
||||
this.removeCallback(names, callback, context);
|
||||
}
|
||||
else {
|
||||
this.removeAllCallbacks(names);
|
||||
}
|
||||
};
|
||||
CallbackRegistry.prototype.removeCallback = function (names, callback, context) {
|
||||
Collections.apply(names, function (name) {
|
||||
this._callbacks[name] = Collections.filter(this._callbacks[name] || [], function (oning) {
|
||||
return (callback && callback !== oning.fn) ||
|
||||
(context && context !== oning.context);
|
||||
});
|
||||
if (this._callbacks[name].length === 0) {
|
||||
delete this._callbacks[name];
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
CallbackRegistry.prototype.removeAllCallbacks = function (names) {
|
||||
Collections.apply(names, function (name) {
|
||||
delete this._callbacks[name];
|
||||
}, this);
|
||||
};
|
||||
return CallbackRegistry;
|
||||
}());
|
||||
|
||||
function prefix(name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
function __ajax(options) {
|
||||
options = options || {};
|
||||
options.type = (options.type || 'GET').toUpperCase();
|
||||
options.dataType = options.dataType || 'json';
|
||||
var params = formatParams(options.data);
|
||||
|
||||
var xhr;
|
||||
if (window.XMLHttpRequest) {
|
||||
xhr = new XMLHttpRequest();
|
||||
} else {
|
||||
xhr = ActiveXObject('Microsoft.XMLHTTP');
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
var status = xhr.status;
|
||||
if (status >= 200 && status < 300) {
|
||||
options.success && options.success(xhr.responseText, xhr.responseXML);
|
||||
} else {
|
||||
options.error && options.error(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.type === 'GET') {
|
||||
xhr.open('GET', options.url + '?' + params, true);
|
||||
xhr.send(null);
|
||||
} else if (options.type === 'POST') {
|
||||
xhr.open('POST', options.url, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.send(params);
|
||||
}
|
||||
}
|
||||
|
||||
function formatParams(data) {
|
||||
var arr = [];
|
||||
for (var name in data) {
|
||||
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
|
||||
}
|
||||
return arr.join('&');
|
||||
}
|
||||
192
saiadmin-vue/src/utils/request.js
Normal file
192
saiadmin-vue/src/utils/request.js
Normal file
@@ -0,0 +1,192 @@
|
||||
import axios from 'axios'
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import tool from '@/utils/tool'
|
||||
import { get, isEmpty } from 'lodash'
|
||||
import qs from 'qs'
|
||||
import { h } from 'vue'
|
||||
import { IconFaceFrownFill } from '@arco-design/web-vue/dist/arco-vue-icon'
|
||||
import router from '@/router'
|
||||
|
||||
function createExternalService() {
|
||||
// 创建一个外部网络 axios 实例
|
||||
const service = axios.create()
|
||||
|
||||
// HTTP request 拦截器
|
||||
service.interceptors.request.use(
|
||||
(config) => config,
|
||||
(error) => Promise.reject(error)
|
||||
)
|
||||
|
||||
// HTTP response 拦截器
|
||||
service.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
Promise.reject(error.response ?? null)
|
||||
}
|
||||
)
|
||||
return service
|
||||
}
|
||||
|
||||
function createService() {
|
||||
// 创建一个 axios 实例
|
||||
const service = axios.create()
|
||||
|
||||
// HTTP request 拦截器
|
||||
service.interceptors.request.use(
|
||||
(config) => config,
|
||||
(error) => {
|
||||
console.log(error)
|
||||
// 失败
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// HTTP response 拦截器
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
if (
|
||||
(response.headers['content-disposition'] ||
|
||||
!/^application\/json/.test(response.headers['content-type'])) &&
|
||||
response.status === 200
|
||||
) {
|
||||
return response
|
||||
} else if (response.data.size) {
|
||||
response.data.code = 500
|
||||
response.data.message = '服务器内部错误'
|
||||
response.data.success = false
|
||||
} else if (response.data.code && response.data.code !== 200) {
|
||||
if (response.data.code === 401) {
|
||||
throttle(() => {
|
||||
Message.error({
|
||||
content: response.data.message || response.data.msg,
|
||||
icon: () => h(IconFaceFrownFill)
|
||||
})
|
||||
tool.local.clear()
|
||||
router.push({ name: 'login' })
|
||||
})()
|
||||
} else {
|
||||
Message.error({
|
||||
content: response.data.message || response.data.msg,
|
||||
icon: () => h(IconFaceFrownFill)
|
||||
})
|
||||
}
|
||||
}
|
||||
return response.data
|
||||
},
|
||||
(error) => {
|
||||
const err = (text) => {
|
||||
Message.error({
|
||||
content:
|
||||
error.response && error.response.data && error.response.data.message
|
||||
? error.response.data.message
|
||||
: text,
|
||||
icon: () => h(IconFaceFrownFill)
|
||||
})
|
||||
}
|
||||
if (error.response && error.response.data) {
|
||||
switch (error.response.status) {
|
||||
case 404:
|
||||
err('服务器资源不存在')
|
||||
break
|
||||
case 500:
|
||||
err('服务器内部错误')
|
||||
break
|
||||
case 401:
|
||||
throttle(() => {
|
||||
err('登录状态已过期,需要重新登录')
|
||||
tool.local.clear()
|
||||
router.push({ name: 'login' })
|
||||
})()
|
||||
break
|
||||
case 403:
|
||||
err('没有权限访问该资源')
|
||||
break
|
||||
default:
|
||||
err('未知错误!')
|
||||
}
|
||||
} else {
|
||||
err('请求超时,服务器无响应!')
|
||||
}
|
||||
return Promise.resolve({
|
||||
code: error.response.status || 500,
|
||||
message: error.response.statusText || '未知错误'
|
||||
})
|
||||
}
|
||||
)
|
||||
return service
|
||||
}
|
||||
|
||||
//节流
|
||||
function throttle(fn, wait = 1500) {
|
||||
return function () {
|
||||
let context = this
|
||||
if (!throttle.timer) {
|
||||
fn.apply(context, arguments)
|
||||
throttle.timer = setTimeout(function () {
|
||||
throttle.timer = null
|
||||
}, wait)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stringify(data) {
|
||||
return qs.stringify(data, { allowDots: true, encode: false })
|
||||
}
|
||||
|
||||
function formatToken(token) {
|
||||
return token ? `Bearer ${token}` : null
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建请求方法
|
||||
* @param service
|
||||
* @param externalService
|
||||
*/
|
||||
function createRequest(service, externalService) {
|
||||
return function (config) {
|
||||
const env = import.meta.env
|
||||
const token = tool.local.get(env.VITE_APP_TOKEN_PREFIX)
|
||||
const setting = tool.local.get('setting')
|
||||
const configDefault = {
|
||||
headers: Object.assign(
|
||||
{
|
||||
Authorization: formatToken(token),
|
||||
'Accept-Language': setting?.language || 'zh_CN',
|
||||
'Content-Type': get(
|
||||
config,
|
||||
'headers.Content-Type',
|
||||
'application/json;charset=UTF-8'
|
||||
)
|
||||
},
|
||||
config.headers
|
||||
),
|
||||
|
||||
timeout: 10000,
|
||||
data: {}
|
||||
}
|
||||
|
||||
delete config.headers
|
||||
// return
|
||||
const option = Object.assign(configDefault, config)
|
||||
|
||||
// json
|
||||
if (!isEmpty(option.params)) {
|
||||
option.url = option.url + '?' + stringify(option.params)
|
||||
option.params = {}
|
||||
}
|
||||
|
||||
if (!/^(http|https)/g.test(option.url)) {
|
||||
option.baseURL =
|
||||
env.VITE_APP_OPEN_PROXY === 'true'
|
||||
? env.VITE_APP_PROXY_PREFIX
|
||||
: env.VITE_APP_BASE_URL
|
||||
return service(option)
|
||||
} else {
|
||||
return externalService(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const service = createService()
|
||||
export const externalService = createExternalService()
|
||||
export const request = createRequest(service, externalService)
|
||||
525
saiadmin-vue/src/utils/tool.js
Normal file
525
saiadmin-vue/src/utils/tool.js
Normal file
@@ -0,0 +1,525 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
import CityLinkageJson from '@/components/ma-cityLinkage/lib/city.json'
|
||||
|
||||
/**
|
||||
* 根据类型获取颜色
|
||||
*/
|
||||
const typeColor = (type = 'default') => {
|
||||
let color = ''
|
||||
switch (type) {
|
||||
case 'default':
|
||||
color = '#35495E'
|
||||
break
|
||||
case 'primary':
|
||||
color = '#3488ff'
|
||||
break
|
||||
case 'success':
|
||||
color = '#43B883'
|
||||
break
|
||||
case 'warning':
|
||||
color = '#e6a23c'
|
||||
break
|
||||
case 'danger':
|
||||
color = '#f56c6c'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
const tool = {}
|
||||
|
||||
/**
|
||||
* LocalStorage
|
||||
*/
|
||||
tool.local = {
|
||||
set(table, settings) {
|
||||
let _set = JSON.stringify(settings)
|
||||
return localStorage.setItem(table, _set)
|
||||
},
|
||||
get(table) {
|
||||
let data = localStorage.getItem(table)
|
||||
try {
|
||||
data = JSON.parse(data)
|
||||
} catch (err) {
|
||||
return null
|
||||
}
|
||||
return data
|
||||
},
|
||||
remove(table) {
|
||||
return localStorage.removeItem(table)
|
||||
},
|
||||
clear() {
|
||||
return localStorage.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SessionStorage
|
||||
*/
|
||||
tool.session = {
|
||||
set(table, settings) {
|
||||
let _set = JSON.stringify(settings)
|
||||
return sessionStorage.setItem(table, _set)
|
||||
},
|
||||
get(table) {
|
||||
let data = sessionStorage.getItem(table)
|
||||
try {
|
||||
data = JSON.parse(data)
|
||||
} catch (err) {
|
||||
return null
|
||||
}
|
||||
return data
|
||||
},
|
||||
remove(table) {
|
||||
return sessionStorage.removeItem(table)
|
||||
},
|
||||
clear() {
|
||||
return sessionStorage.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieStorage
|
||||
*/
|
||||
tool.cookie = {
|
||||
set(name, value, config = {}) {
|
||||
var cfg = {
|
||||
expires: null,
|
||||
path: null,
|
||||
domain: null,
|
||||
secure: false,
|
||||
httpOnly: false,
|
||||
...config
|
||||
}
|
||||
var cookieStr = `${name}=${escape(value)}`
|
||||
if (cfg.expires) {
|
||||
var exp = new Date()
|
||||
exp.setTime(exp.getTime() + parseInt(cfg.expires) * 1000)
|
||||
cookieStr += `;expires=${exp.toGMTString()}`
|
||||
}
|
||||
if (cfg.path) {
|
||||
cookieStr += `;path=${cfg.path}`
|
||||
}
|
||||
if (cfg.domain) {
|
||||
cookieStr += `;domain=${cfg.domain}`
|
||||
}
|
||||
document.cookie = cookieStr
|
||||
},
|
||||
get(name) {
|
||||
var arr = document.cookie.match(
|
||||
new RegExp('(^| )' + name + '=([^;]*)(;|$)')
|
||||
)
|
||||
if (arr != null) {
|
||||
return unescape(arr[2])
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
},
|
||||
remove(name) {
|
||||
var exp = new Date()
|
||||
exp.setTime(exp.getTime() - 1)
|
||||
document.cookie = `${name}=;expires=${exp.toGMTString()}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全屏操作
|
||||
*/
|
||||
tool.screen = (element) => {
|
||||
let isFull = !!(
|
||||
document.webkitIsFullScreen ||
|
||||
document.mozFullScreen ||
|
||||
document.msFullscreenElement ||
|
||||
document.fullscreenElement
|
||||
)
|
||||
if (isFull) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen()
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen()
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen()
|
||||
}
|
||||
} else {
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen()
|
||||
} else if (element.msRequestFullscreen) {
|
||||
element.msRequestFullscreen()
|
||||
} else if (element.mozRequestFullScreen) {
|
||||
element.mozRequestFullScreen()
|
||||
} else if (element.webkitRequestFullscreen) {
|
||||
element.webkitRequestFullscreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备信息
|
||||
*/
|
||||
tool.getDevice = function () {
|
||||
const hasTouchScreen =
|
||||
'ontouchstart' in window || navigator.maxTouchPoints > 0
|
||||
const isSmallScreen = window.innerWidth < 768
|
||||
|
||||
if (hasTouchScreen && isSmallScreen) {
|
||||
return 'mobile'
|
||||
} else {
|
||||
return 'desktop'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图片
|
||||
*/
|
||||
tool.parseImage = (url) => {
|
||||
if (url === undefined) {
|
||||
return import.meta.env.VITE_APP_BASE + 'not-image.png'
|
||||
}
|
||||
if (typeof url === 'string' && url !== null) {
|
||||
return url
|
||||
} else {
|
||||
if (url !== null) {
|
||||
return url[0]
|
||||
} else {
|
||||
return import.meta.env.VITE_APP_BASE + 'not-image.png'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 城市代码翻译成名称
|
||||
*/
|
||||
tool.cityToCode = function (
|
||||
province,
|
||||
city = undefined,
|
||||
area = undefined,
|
||||
split = ' / '
|
||||
) {
|
||||
try {
|
||||
let provinceData = CityLinkageJson.filter(
|
||||
(item) => province == item.code
|
||||
)[0]
|
||||
if (!city) {
|
||||
return provinceData.name
|
||||
}
|
||||
let cityData = provinceData.children.filter((item) => city == item.code)[0]
|
||||
|
||||
if (!area) {
|
||||
return [provinceData.name, cityData.name].join(split)
|
||||
}
|
||||
let areaData = cityData.children.filter((item) => area == item.code)[0]
|
||||
|
||||
return [provinceData.name, cityData.name, areaData.name].join(split)
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制对象
|
||||
*/
|
||||
tool.objCopy = (obj) => {
|
||||
if (obj === undefined) {
|
||||
return undefined
|
||||
}
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
/**
|
||||
* 生车随机id
|
||||
*/
|
||||
tool.generateId = function () {
|
||||
return Math.floor(
|
||||
Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成全球唯一标识
|
||||
* @returns uuid
|
||||
*/
|
||||
tool.uuid = () => {
|
||||
const hexList = []
|
||||
for (let i = 0; i <= 15; i++) {
|
||||
hexList[i] = i.toString(16)
|
||||
}
|
||||
let uuid = ''
|
||||
for (let i = 1; i <= 36; i++) {
|
||||
if (i === 9 || i === 14 || i === 19 || i === 24) {
|
||||
uuid += '-'
|
||||
} else if (i === 15) {
|
||||
uuid += 4
|
||||
} else if (i === 20) {
|
||||
uuid += hexList[(Math.random() * 4) | 8]
|
||||
} else {
|
||||
uuid += hexList[(Math.random() * 16) | 0]
|
||||
}
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化
|
||||
*/
|
||||
tool.dateFormat = (date, fmt = 'yyyy-MM-dd hh:mm:ss', isDefault = '-') => {
|
||||
if (!date) date = Number(new Date())
|
||||
if (date.toString().length == 10) {
|
||||
date = date * 1000
|
||||
}
|
||||
date = new Date(date)
|
||||
|
||||
if (date.valueOf() < 1) {
|
||||
return isDefault
|
||||
}
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1, //月份
|
||||
'd+': date.getDate(), //日
|
||||
'h+': date.getHours(), //小时
|
||||
'm+': date.getMinutes(), //分
|
||||
's+': date.getSeconds(), //秒
|
||||
'q+': Math.floor((date.getMonth() + 3) / 3), //季度
|
||||
S: date.getMilliseconds() //毫秒
|
||||
}
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
||||
)
|
||||
}
|
||||
for (let 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)
|
||||
)
|
||||
}
|
||||
}
|
||||
return fmt
|
||||
}
|
||||
|
||||
/**
|
||||
* 千分符
|
||||
*/
|
||||
tool.groupSeparator = (num) => {
|
||||
num = num + ''
|
||||
if (!num.includes('.')) {
|
||||
num += '.'
|
||||
}
|
||||
return num
|
||||
.replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
|
||||
return $1 + ','
|
||||
})
|
||||
.replace(/\.$/, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密
|
||||
*/
|
||||
tool.md5 = (str) => {
|
||||
return CryptoJS.MD5(str).toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64加密解密
|
||||
*/
|
||||
tool.base64 = {
|
||||
encode(data) {
|
||||
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
|
||||
},
|
||||
decode(cipher) {
|
||||
return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES加密解密
|
||||
*/
|
||||
tool.aes = {
|
||||
encode(data, secretKey) {
|
||||
const result = CryptoJS.AES.encrypt(
|
||||
data,
|
||||
CryptoJS.enc.Utf8.parse(secretKey),
|
||||
{
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
}
|
||||
)
|
||||
return result.toString()
|
||||
},
|
||||
decode(cipher, secretKey) {
|
||||
const result = CryptoJS.AES.decrypt(
|
||||
cipher,
|
||||
CryptoJS.enc.Utf8.parse(secretKey),
|
||||
{
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
}
|
||||
)
|
||||
return CryptoJS.enc.Utf8.stringify(result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印信息
|
||||
*/
|
||||
tool.capsule = (title, info, type = 'primary') => {
|
||||
console.log(
|
||||
`%c ${title} %c ${info} %c`,
|
||||
'background:#35495E; padding: 1px; border-radius: 3px 0 0 3px; color: #fff;',
|
||||
`background:${typeColor(
|
||||
type
|
||||
)}; padding: 1px; border-radius: 0 3px 3px 0; color: #fff;`,
|
||||
'background:transparent'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件大小单位处理
|
||||
*/
|
||||
tool.formatSize = (size) => {
|
||||
if (typeof size == 'undefined') {
|
||||
return '0'
|
||||
}
|
||||
let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
|
||||
let index = 0
|
||||
for (let i = 0; size >= 1024 && i < 5; i++) {
|
||||
size /= 1024
|
||||
index = i
|
||||
}
|
||||
return Math.round(size, 2) + units[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载资源
|
||||
*/
|
||||
tool.download = (res, downName = '') => {
|
||||
const aLink = document.createElement('a')
|
||||
let fileName = downName
|
||||
let blob = res //第三方请求返回blob对象
|
||||
|
||||
//通过后端接口返回
|
||||
if (res.headers && res.data) {
|
||||
blob = new Blob([res.data], {
|
||||
type: res.headers['content-type'].replace(';charset=utf8', '')
|
||||
})
|
||||
if (!downName) {
|
||||
const contentDisposition = decodeURI(res.headers['content-disposition'])
|
||||
const result = contentDisposition.match(/filename=\"(.+)/gi)
|
||||
fileName = result[0].replace(/filename=\"/gi, '')
|
||||
fileName = fileName.replace('"', '')
|
||||
}
|
||||
}
|
||||
|
||||
aLink.href = URL.createObjectURL(blob)
|
||||
// 设置下载文件名称
|
||||
aLink.setAttribute('download', fileName)
|
||||
document.body.appendChild(aLink)
|
||||
aLink.click()
|
||||
document.body.removeChild(aLink)
|
||||
URL.revokeObjectURL(aLink.href)
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象转url参数
|
||||
* @param {*} data
|
||||
* @param {*} isPrefix
|
||||
*/
|
||||
tool.httpBuild = (data, isPrefix = false) => {
|
||||
let prefix = isPrefix ? '?' : ''
|
||||
let _result = []
|
||||
for (let key in data) {
|
||||
let value = data[key]
|
||||
// 去掉为空的参数
|
||||
if (['', undefined, null].includes(value)) {
|
||||
continue
|
||||
}
|
||||
if (value.constructor === Array) {
|
||||
value.forEach((_value) => {
|
||||
_result.push(
|
||||
encodeURIComponent(key) + '[]=' + encodeURIComponent(_value)
|
||||
)
|
||||
})
|
||||
} else {
|
||||
_result.push(encodeURIComponent(key) + '=' + encodeURIComponent(value))
|
||||
}
|
||||
}
|
||||
|
||||
return _result.length ? prefix + _result.join('&') : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取URL请求参数
|
||||
*/
|
||||
tool.getRequestParams = (url) => {
|
||||
const theRequest = new Object()
|
||||
if (url.indexOf('?') != -1) {
|
||||
const params = url.split('?')[1].split('&')
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const param = params[i].split('=')
|
||||
theRequest[param[0]] = decodeURIComponent(param[1])
|
||||
}
|
||||
}
|
||||
return theRequest
|
||||
}
|
||||
|
||||
tool.attachUrl = (path) => {
|
||||
// 非完整url地址在此处理
|
||||
return path
|
||||
}
|
||||
|
||||
tool.viewImage = (path) => {
|
||||
// 非完整url地址在此处理
|
||||
return path
|
||||
}
|
||||
|
||||
tool.showFile = (path) => {
|
||||
// 非完整url地址在此处理
|
||||
return path
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token
|
||||
*/
|
||||
tool.getToken = () => {
|
||||
return tool.local.get(import.meta.env.VITE_APP_TOKEN_PREFIX)
|
||||
}
|
||||
|
||||
/**
|
||||
* 转Unix时间戳
|
||||
*/
|
||||
tool.toUnixTime = (date) => {
|
||||
return Math.floor(new Date(date).getTime() / 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过value获取颜色
|
||||
*/
|
||||
tool.getColor = (value, data, colors = []) => {
|
||||
if (!data) {
|
||||
return ''
|
||||
}
|
||||
if (colors && colors.length > 0) {
|
||||
const index = data.findIndex((item) => item.value == value)
|
||||
return colors[index] ?? ''
|
||||
} else {
|
||||
const item = data.find((item) => item.value == value)
|
||||
return item?.color ?? ''
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过value获取label
|
||||
*/
|
||||
tool.getLabel = (value, data) => {
|
||||
if (!data) {
|
||||
return ''
|
||||
}
|
||||
const item = data.find((item) => item.value == value)
|
||||
return item?.label ?? ''
|
||||
}
|
||||
|
||||
export default tool
|
||||
Reference in New Issue
Block a user