Files
EdgeAdmin/web/public/js/utils.js

939 lines
19 KiB
JavaScript
Raw Normal View History

2020-07-22 09:59:40 +08:00
window.teaweb = {
2021-06-08 11:22:44 +08:00
set: function (key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
get: function (key) {
var item = localStorage.getItem(key);
if (item == null || item.length == 0) {
return null;
}
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
return JSON.parse(item);
},
getString: function (key) {
var value = this.get(key);
if (typeof (value) == "string") {
return value;
}
return "";
},
getBool: function (key) {
return Boolean(this.get(key));
},
remove: function (key) {
localStorage.removeItem(key)
},
match: function (source, keyword) {
if (source == null) {
return false;
}
if (keyword == null) {
return true;
}
source = source.trim();
keyword = keyword.trim();
if (keyword.length == 0) {
return true;
}
if (source.length == 0) {
return false;
}
var pieces = keyword.split(/\s+/);
for (var i = 0; i < pieces.length; i++) {
var pattern = pieces[i];
pattern = pattern.replace(/(\+|\*|\?|[|]|{|}|\||\\|\(|\)|\.)/g, "\\$1");
var reg = new RegExp(pattern, "i");
if (!reg.test(source)) {
return false;
}
}
return true;
},
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
loadJS: function (file, callback) {
let element = document.createElement("script")
element.setAttribute("type", "text/javascript")
element.setAttribute("src", file)
if (typeof callback == "function") {
element.addEventListener("load", callback)
}
document.head.append(element)
},
loadCSS: function (file, callback) {
let element = document.createElement("link")
element.setAttribute("rel", "stylesheet")
element.setAttribute("type", "text/css")
element.setAttribute("href", file)
if (typeof callback == "function") {
element.addEventListener("load", callback)
}
document.head.append(element)
},
2021-10-29 14:02:01 +08:00
datepicker: function (element, callback, bottomLeft) {
2021-06-08 11:22:44 +08:00
// 加载
if (typeof Pikaday == "undefined") {
let that = this
this.loadJS("/js/moment.min.js", function () {
that.loadJS("/js/pikaday.js", function () {
2021-10-29 14:02:01 +08:00
that.datepicker(element, callback, bottomLeft)
})
2021-06-08 11:22:44 +08:00
})
this.loadCSS("/js/pikaday.css")
this.loadCSS("/js/pikaday.theme.css")
this.loadCSS("/js/pikaday.triangle.css")
2021-06-08 11:22:44 +08:00
return
}
2021-06-08 11:22:44 +08:00
if (typeof (element) == "string") {
element = document.getElementById(element);
}
2021-10-29 14:02:01 +08:00
let year = new Date().getFullYear();
let picker = new Pikaday({
2021-06-08 11:22:44 +08:00
field: element,
firstDay: 1,
minDate: new Date(year - 1, 0, 1),
maxDate: new Date(year + 10, 11, 31),
yearRange: [year - 1, year + 10],
format: "YYYY-MM-DD",
i18n: {
previousMonth: '上月',
nextMonth: '下月',
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
weekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
weekdaysShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
},
theme: 'triangle-theme',
onSelect: function () {
if (typeof (callback) == "function") {
callback.call(Tea.Vue, picker.toString());
}
2021-10-29 14:02:01 +08:00
},
reposition: !bottomLeft
})
2021-06-08 11:22:44 +08:00
},
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
formatBytes: function (bytes) {
bytes = Math.ceil(bytes);
if (bytes < Math.pow(1024, 1)) {
2021-06-08 11:22:44 +08:00
return bytes + "B";
}
if (bytes < Math.pow(1024, 2)) {
return (Math.round(bytes * 100 / Math.pow(1024, 1)) / 100) + "KB";
2021-06-08 11:22:44 +08:00
}
if (bytes < Math.pow(1024, 3)) {
return (Math.round(bytes * 100 / Math.pow(1024, 2)) / 100) + "MB";
2021-06-08 11:22:44 +08:00
}
if (bytes < Math.pow(1024, 4)) {
return (Math.round(bytes * 100 / Math.pow(1024, 3)) / 100) + "GB";
2021-06-08 11:22:44 +08:00
}
if (bytes < Math.pow(1024, 5)) {
return (Math.round(bytes * 100 / Math.pow(1024, 4)) / 100) + "TB";
2021-06-08 11:22:44 +08:00
}
if (bytes < Math.pow(1024, 6)) {
return (Math.round(bytes * 100 / Math.pow(1024, 5)) / 100) + "PB";
}
return (Math.round(bytes * 100 / Math.pow(1024, 6)) / 100) + "EB";
2021-06-08 11:22:44 +08:00
},
formatNumber: function (x) {
if (x == null) {
return "null"
}
let s = x.toString()
let dotIndex = s.indexOf(".")
if (dotIndex >= 0) {
return this.formatNumber(s.substring(0, dotIndex)) + "." + s.substring(dotIndex + 1)
}
if (s.length <= 3) {
return s;
}
let result = []
for (let i = 0; i < Math.floor(s.length / 3); i++) {
let start = s.length - (i + 1) * 3
result.push(s.substring(start, start + 3))
}
if (s.length % 3 != 0) {
result.push(s.substring(0, s.length % 3))
}
return result.reverse().join(", ")
2021-06-08 11:22:44 +08:00
},
2021-07-12 16:56:56 +08:00
formatCount: function (x) {
let unit = ""
let divider = ""
if (x >= 1000 * 1000 * 1000) {
unit = "B"
divider = 1000 * 1000 * 1000
} else if (x >= 1000 * 1000) {
unit = "M"
divider = 1000 * 1000
} else if (x >= 1000) {
unit = "K"
divider = 1000
}
if (unit.length == 0) {
return x.toString()
}
return (Math.round(x * 100 / divider) / 100) + unit
},
2021-06-08 11:22:44 +08:00
bytesAxis: function (stats, countFunc) {
let max = Math.max.apply(this, stats.map(countFunc))
let divider = 1
let unit = ""
if (max >= Math.pow(1024, 6)) {
2021-12-12 21:13:55 +08:00
unit = "E"
divider = Math.pow(1024, 6)
} else if (max >= Math.pow(1024, 5)) {
2021-12-12 21:13:55 +08:00
unit = "P"
divider = Math.pow(1024, 5)
} else if (max >= Math.pow(1024, 4)) {
2021-12-12 21:13:55 +08:00
unit = "T"
divider = Math.pow(1024, 4)
} else if (max >= Math.pow(1024, 3)) {
2021-12-12 21:13:55 +08:00
unit = "G"
divider = Math.pow(1024, 3)
} else if (max >= Math.pow(1024, 2)) {
2021-12-12 21:13:55 +08:00
unit = "M"
divider = Math.pow(1024, 2)
} else if (max >= Math.pow(1024, 1)) {
2021-12-12 21:13:55 +08:00
unit = "K"
divider = Math.pow(1024, 1)
2021-06-08 11:22:44 +08:00
}
return {
unit: unit,
divider: divider
}
},
countAxis: function (stats, countFunc) {
let max = Math.max.apply(this, stats.map(countFunc))
let divider = 1
let unit = ""
if (max >= 1000 * 1000 * 1000) {
unit = "B"
divider = 1000 * 1000 * 1000
} else if (max >= 1000 * 1000) {
unit = "M"
divider = 1000 * 1000
} else if (max >= 1000) {
unit = "K"
divider = 1000
}
return {
unit: unit,
2021-07-11 18:05:49 +08:00
divider: divider,
max: max
2021-06-08 11:22:44 +08:00
}
},
popup: function (url, options) {
if (url != null && url.length > 0 && url.substring(0, 1) == '.') {
url = Tea.url(url)
}
2021-06-08 11:22:44 +08:00
if (options == null) {
options = {};
}
var width = "40em";
var height = "20em";
window.POPUP_CALLBACK = function () {
Swal.close();
};
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
if (options["width"] != null) {
width = options["width"];
}
if (options["height"] != null) {
height = options["height"];
}
if (typeof (options["callback"]) == "function") {
window.POPUP_CALLBACK = function () {
Swal.close();
options["callback"].apply(Tea.Vue, arguments);
};
}
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
Swal.fire({
html: '<iframe src="' + url + '#popup-' + width + '" style="border:0; width: 100%; height:' + height + '"></iframe>',
width: width,
padding: "0.5em",
showConfirmButton: false,
showCloseButton: true,
focusConfirm: false,
onClose: function (popup) {
if (typeof (options["onClose"]) == "function") {
options["onClose"].apply(Tea.Vue, arguments)
}
}
});
},
2021-10-29 14:02:01 +08:00
popupSuccess: function (url, width, height) {
let options = {}
if (width != null) {
options["width"] = width
}
if (height != null) {
options["height"] = height
}
options["callback"] = function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
this.popup(url, options)
},
2021-06-08 11:22:44 +08:00
popupFinish: function () {
if (window.POPUP_CALLBACK != null) {
window.POPUP_CALLBACK.apply(window, arguments);
}
},
popupTip: function (html) {
Swal.fire({
2021-06-27 21:59:06 +08:00
html: '<div style="line-height: 1.7;text-align: left "><i class="icon question circle"></i>' + html + "</div>",
2021-06-08 11:22:44 +08:00
width: "30em",
2021-06-27 21:59:06 +08:00
padding: "4em",
2021-06-08 11:22:44 +08:00
showConfirmButton: false,
showCloseButton: true,
focusConfirm: false
});
},
isPopup: function () {
var hash = window.location.hash;
return hash != null && hash.startsWith("#popup");
},
closePopup: function () {
if (this.isPopup()) {
window.parent.Swal.close();
}
},
Swal: function () {
return this.isPopup() ? window.parent.Swal : window.Swal;
},
success: function (message, callback) {
var width = "20em";
if (message.length > 30) {
width = "30em";
}
2020-07-22 09:59:40 +08:00
2021-06-08 11:22:44 +08:00
let config = {
confirmButtonText: "确定",
buttonsStyling: false,
icon: "success",
customClass: {
closeButton: "ui button",
cancelButton: "ui button",
confirmButton: "ui button primary"
},
width: width,
onAfterClose: function () {
if (typeof (callback) == "function") {
setTimeout(function () {
callback();
});
} else if (typeof (callback) == "string") {
window.location = callback
}
}
}
2020-10-13 20:05:29 +08:00
2021-06-08 11:22:44 +08:00
if (message.startsWith("html:")) {
config.html = message.substring(5)
} else {
config.text = message
}
2020-10-13 20:05:29 +08:00
2021-06-08 11:22:44 +08:00
Swal.fire(config);
},
2021-07-31 22:23:07 +08:00
toast: function (message, timeout, callback) {
if (timeout == null) {
timeout = 2000
}
var width = "20em";
if (message.length > 30) {
width = "30em";
}
Swal.fire({
text: message,
icon: "info",
width: width,
timer: timeout,
showConfirmButton: false,
onAfterClose: function () {
if (typeof callback == "function") {
callback()
}
}
});
},
2021-07-12 10:21:17 +08:00
successToast: function (message, timeout, callback) {
2021-06-08 11:22:44 +08:00
if (timeout == null) {
timeout = 2000
}
var width = "20em";
if (message.length > 30) {
width = "30em";
}
Swal.fire({
text: message,
icon: "success",
width: width,
timer: timeout,
2021-07-12 10:21:17 +08:00
showConfirmButton: false,
onAfterClose: function () {
if (typeof callback == "function") {
callback()
}
}
2021-06-08 11:22:44 +08:00
});
},
2021-07-03 15:44:49 +08:00
successRefresh: function (message) {
teaweb.success(message, function () {
teaweb.reload()
})
},
2021-06-08 11:22:44 +08:00
warn: function (message, callback) {
var width = "20em";
if (message.length > 30) {
width = "30em";
}
Swal.fire({
text: message,
confirmButtonText: "确定",
buttonsStyling: false,
customClass: {
closeButton: "ui button",
cancelButton: "ui button",
confirmButton: "ui button primary"
},
icon: "warning",
width: width,
onAfterClose: function () {
if (typeof (callback) == "function") {
setTimeout(function () {
callback();
});
}
}
});
},
confirm: function (message, callback) {
let width = "20em";
if (message.length > 30) {
width = "30em";
}
let config = {
confirmButtonText: "确定",
cancelButtonText: "取消",
showCancelButton: true,
showCloseButton: false,
buttonsStyling: false,
customClass: {
closeButton: "ui button",
cancelButton: "ui button",
confirmButton: "ui button primary"
},
icon: "warning",
width: width,
preConfirm: function () {
if (typeof (callback) == "function") {
callback.call(Tea.Vue);
}
}
}
if (message.startsWith("html:")) {
config.html = message.substring(5)
} else {
config.text = message
}
Swal.fire(config);
},
reload: function () {
window.location.reload()
},
renderBarChart: function (options) {
let chartId = options.id
2021-07-12 16:56:56 +08:00
if (chartId == null || chartId.length == 0) {
throw new Error("'options.id' should not be empty")
}
let name = options.name
let values = options.values
2021-07-12 16:56:56 +08:00
if (values == null || !(values instanceof Array)) {
throw new Error("'options.values' should be array")
}
let xFunc = options.x
2021-07-12 16:56:56 +08:00
if (typeof (xFunc) != "function") {
throw new Error("'options.x' should be a function")
}
let tooltipFunc = options.tooltip
2021-07-20 10:55:25 +08:00
if (typeof (tooltipFunc) != "function") {
2021-07-12 16:56:56 +08:00
throw new Error("'options.tooltip' should be a function")
}
let axis = options.axis
2021-07-12 16:56:56 +08:00
if (axis == null) {
axis = {unit: "", count: 1}
}
let valueFunc = options.value
2021-07-12 16:56:56 +08:00
if (typeof (valueFunc) != "function") {
throw new Error("'options.value' should be a function")
}
let click = options.click
2021-07-21 08:07:46 +08:00
let bottom = 24
let rotate = 0
let chartBox = document.getElementById(chartId)
if (chartBox == null) {
return
}
2021-07-21 08:07:46 +08:00
let chart = this.initChart(chartBox)
let result = this.xRotation(chart, values.map(xFunc))
if (result != null) {
bottom = result[0]
rotate = result[1]
}
let option = {
xAxis: {
data: values.map(xFunc),
axisLabel: {
2021-07-21 08:07:46 +08:00
interval: 0,
rotate: rotate
}
},
yAxis: {
axisLabel: {
formatter: function (value) {
return value + axis.unit
}
}
},
tooltip: {
show: true,
trigger: "item",
formatter: function (args) {
return tooltipFunc.apply(this, [args, values])
}
},
grid: {
left: 40,
top: 10,
right: 20,
2021-07-21 08:07:46 +08:00
bottom: bottom
},
series: [
{
name: name,
type: "bar",
data: values.map(valueFunc),
itemStyle: {
color: "#9DD3E8"
},
barWidth: "20em"
}
],
animation: true,
}
chart.setOption(option)
if (click != null) {
chart.on("click", function (args) {
click.call(this, args, values)
})
}
chart.resize()
},
renderLineChart: function (options) {
let chartId = options.id
let name = options.name
let values = options.values
let xFunc = options.x
let tooltipFunc = options.tooltip
let axis = options.axis
let valueFunc = options.value
let max = options.max
let interval = options.interval
let chartBox = document.getElementById(chartId)
if (chartBox == null) {
return
}
2021-07-21 08:07:46 +08:00
let chart = this.initChart(chartBox)
let option = {
xAxis: {
data: values.map(xFunc),
axisLabel: {
interval: interval
}
},
yAxis: {
axisLabel: {
formatter: function (value) {
return value + axis.unit
}
},
max: max
},
tooltip: {
show: true,
trigger: "item",
formatter: function (args) {
return tooltipFunc.apply(this, [args, values])
}
},
grid: {
left: 40,
top: 10,
right: 20,
bottom: 20
},
series: [
{
name: name,
type: "line",
data: values.map(valueFunc),
itemStyle: {
color: "#9DD3E8"
},
2021-07-26 14:32:24 +08:00
areaStyle: {},
smooth: true
}
],
2021-08-17 10:48:38 +08:00
animation: true,
smooth: true
}
chart.setOption(option)
chart.resize()
2021-07-21 08:07:46 +08:00
},
2022-04-07 10:21:38 +08:00
renderGaugeChart: function (options) {
let chartId = options.id
let name = options.name // 标题
let min = options.min // 最小值
let max = options.max // 最大值
let value = options.value // 当前值
let unit = options.unit // 单位
let detail = options.detail // 说明文字
let color = options.color // 颜色
let startAngle = options.startAngle
if (startAngle == null) {
startAngle = 225
}
let endAngle = options.endAngle
if (endAngle == null) {
endAngle = -45
}
color = this.chartColor(color)
let chartBox = document.getElementById(chartId)
if (chartBox == null) {
return
}
let chart = this.initChart(chartBox)
let option = {
textStyle: {
fontFamily: "Lato,'Helvetica Neue',Arial,Helvetica,sans-serif"
},
color: color,
title: (name != null && name.length > 0) ? {
text: name,
top: 1,
bottom: 0,
x: "center",
textStyle: {
fontSize: 12,
fontWeight: "bold",
fontFamily: "Lato,'Helvetica Neue',Arial,Helvetica,sans-serif"
}
} : null,
legend: {
data: [""]
},
xAxis: {
data: []
},
yAxis: {},
series: [{
name: "",
type: "gauge",
min: min,
max: max,
startAngle: startAngle,
endAngle: endAngle,
data: [
{
"name": "",// 不显示名称
"value": Math.round(value * 100) / 100
}
],
radius: "100%",
center: ["50%", (name != null && name.length > 0) ? "60%" : "50%"],
splitNumber: 5,
splitLine: {
length: 4
},
axisLine: {
lineStyle: {
width: 4
}
},
axisTick: {
show: true,
length: 2
},
axisLabel: {
formatter: function (v) {
return v;
},
textStyle: {
fontSize: 8
}
},
progress: {
show: true,
width: 4
},
detail: {
formatter: function (v) {
return unit;
},
textStyle: {
fontSize: 12,
fontWeight: "normal",
fontFamily: "Arial,Helvetica,sans-serif",
color: "grey"
//lineHeight: 16
},
valueAnimation: true
},
pointer: {
width: 2
}
}],
grid: {
left: -2,
right: 0,
bottom: 0,
top: 0
},
axisPointer: {
show: false
},
tooltip: {
formatter: 'X:{b0} Y:{c0}',
show: false
},
animation: true
};
chart.setOption(option)
},
renderPercentChart: function (options) {
let chartId = options.id
let color = this.chartColor(options.color)
let value = options.value
let name = options.name
let total = options.total
if (total == null) {
total = 100
}
let unit = options.unit
if (unit == null) {
unit = ""
}
let max = options.max
if (max != null && max <= value) {
max = null
}
let maxColor = this.chartColor(options.maxColor)
let maxName = options.maxName
let chartBox = document.getElementById(chartId)
if (chartBox == null) {
return
}
let chart = this.initChart(chartBox)
let option = {
tooltip: {
formatter: "{a} <br/>{b} : {c}" + unit
},
series: [
{
name: name,
max: total,
type: "gauge",
radius: "100%",
detail: {
formatter: "{value}",
show: false,
valueAnimation: true
},
data: [
{
value: value,
name: name
}
],
pointer: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
width: 4
}
},
progress: {
show: true,
width: 4,
itemStyle: {
color: color
}
},
splitNumber: {
show: false
},
title: {
show: false
},
startAngle: 270,
endAngle: -90
}
]
}
if (max != null) {
option.series.push({
name: maxName,
max: total,
type: "gauge",
radius: "100%",
detail: {
formatter: "{value}",
show: false,
valueAnimation: true
},
data: [
{
value: max,
name: maxName
}
],
pointer: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
width: 4
}
},
progress: {
show: true,
width: 4,
itemStyle: {
color: maxColor,
opacity: 0.3
}
},
splitNumber: {
show: false
},
title: {
show: false
},
startAngle: 270,
endAngle: -90
})
}
chart.setOption(option)
},
2021-07-21 08:07:46 +08:00
xRotation: function (chart, names) {
let chartWidth = chart.getWidth()
let width = 0
names.forEach(function (name) {
width += name.length * 10
})
if (width <= chartWidth) {
return null
}
return [40, -20]
},
2022-04-07 10:21:38 +08:00
chartMap: {}, // dom id => chart
2021-07-21 08:07:46 +08:00
initChart: function (dom) {
2022-04-07 10:21:38 +08:00
let domId = dom.getAttribute("id")
if (domId != null && domId.length > 0 && typeof (this.chartMap[domId]) == "object") {
return this.chartMap[domId]
}
2021-07-21 08:07:46 +08:00
let instance = echarts.init(dom)
window.addEventListener("resize", function () {
instance.resize()
})
2022-04-07 10:21:38 +08:00
this.chartMap[domId] = instance
2021-07-21 08:07:46 +08:00
return instance
},
encodeHTML: function (s) {
2022-02-23 17:34:54 +08:00
s = s.replace(/&/g, "&amp;")
s = s.replace(/</g, "&lt;")
s = s.replace(/>/g, "&gt;")
s = s.replace(/"/, "&quot;")
return s
2022-04-07 10:21:38 +08:00
},
chartColor: function (color) {
if (color == null || color.length == 0) {
color = "#5470c6"
}
if (color == "red") {
color = "#ee6666"
}
if (color == "yellow") {
color = "#fac858"
}
if (color == "blue") {
color = "#5470c6"
}
if (color == "green") {
color = "#3ba272"
}
return color
2021-06-08 11:22:44 +08:00
}
}
2021-07-20 10:55:25 +08:00
String.prototype.quoteIP = function () {
let ip = this.toString()
if (ip.length == 0) {
return ""
}
if (ip.indexOf(":") < 0) {
return ip
}
if (ip.substring(0, 1) == "[") {
return ip
}
return "[" + ip + "]"
2021-07-21 08:07:46 +08:00
}