mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 13:32:24 +00:00
refactor: merging all util functions into classes
This commit is contained in:
parent
26bf693dbd
commit
0a207b8a2c
15 changed files with 225 additions and 267 deletions
|
@ -62,20 +62,20 @@ const supportLangs = [
|
||||||
];
|
];
|
||||||
|
|
||||||
function getLang() {
|
function getLang() {
|
||||||
let lang = getCookie("lang");
|
let lang = CookieManager.getCookie("lang");
|
||||||
|
|
||||||
if (!lang) {
|
if (!lang) {
|
||||||
if (window.navigator) {
|
if (window.navigator) {
|
||||||
lang = window.navigator.language || window.navigator.userLanguage;
|
lang = window.navigator.language || window.navigator.userLanguage;
|
||||||
|
|
||||||
if (isSupportLang(lang)) {
|
if (isSupportLang(lang)) {
|
||||||
setCookie("lang", lang, 150);
|
CookieManager.setCookie("lang", lang, 150);
|
||||||
} else {
|
} else {
|
||||||
setCookie("lang", "en-US", 150);
|
CookieManager.setCookie("lang", "en-US", 150);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setCookie("lang", "en-US", 150);
|
CookieManager.setCookie("lang", "en-US", 150);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ function setLang(lang) {
|
||||||
lang = "en-US";
|
lang = "en-US";
|
||||||
}
|
}
|
||||||
|
|
||||||
setCookie("lang", lang, 150);
|
CookieManager.setCookie("lang", lang, 150);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,11 @@ class DBInbound {
|
||||||
}
|
}
|
||||||
|
|
||||||
get totalGB() {
|
get totalGB() {
|
||||||
return toFixed(this.total / ONE_GB, 2);
|
return NumberFormatter.toFixed(this.total / SizeFormatter.ONE_GB, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
set totalGB(gb) {
|
set totalGB(gb) {
|
||||||
this.total = toFixed(gb * ONE_GB, 0);
|
this.total = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
get isVMess() {
|
get isVMess() {
|
||||||
|
|
|
@ -1837,11 +1837,11 @@ Inbound.VmessSettings.VMESS = class extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get _totalGB() {
|
get _totalGB() {
|
||||||
return toFixed(this.totalGB / ONE_GB, 2);
|
return NumberFormatter.toFixed(this.totalGB / SizeFormatter.ONE_GB, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
set _totalGB(gb) {
|
set _totalGB(gb) {
|
||||||
this.totalGB = toFixed(gb * ONE_GB, 0);
|
this.totalGB = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1947,11 +1947,11 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get _totalGB() {
|
get _totalGB() {
|
||||||
return toFixed(this.totalGB / ONE_GB, 2);
|
return NumberFormatter.toFixed(this.totalGB / SizeFormatter.ONE_GB, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
set _totalGB(gb) {
|
set _totalGB(gb) {
|
||||||
this.totalGB = toFixed(gb * ONE_GB, 0);
|
this.totalGB = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {
|
Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {
|
||||||
|
@ -2099,11 +2099,11 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get _totalGB() {
|
get _totalGB() {
|
||||||
return toFixed(this.totalGB / ONE_GB, 2);
|
return NumberFormatter.toFixed(this.totalGB / SizeFormatter.ONE_GB, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
set _totalGB(gb) {
|
set _totalGB(gb) {
|
||||||
this.totalGB = toFixed(gb * ONE_GB, 0);
|
this.totalGB = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -2263,11 +2263,11 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get _totalGB() {
|
get _totalGB() {
|
||||||
return toFixed(this.totalGB / ONE_GB, 2);
|
return NumberFormatter.toFixed(this.totalGB / SizeFormatter.ONE_GB, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
set _totalGB(gb) {
|
set _totalGB(gb) {
|
||||||
this.totalGB = toFixed(gb * ONE_GB, 0);
|
this.totalGB = NumberFormatter.toFixed(gb * SizeFormatter.ONE_GB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,183 +0,0 @@
|
||||||
const ONE_KB = 1024;
|
|
||||||
const ONE_MB = ONE_KB * 1024;
|
|
||||||
const ONE_GB = ONE_MB * 1024;
|
|
||||||
const ONE_TB = ONE_GB * 1024;
|
|
||||||
const ONE_PB = ONE_TB * 1024;
|
|
||||||
|
|
||||||
function sizeFormat(size) {
|
|
||||||
if (size <= 0) return "0 B";
|
|
||||||
|
|
||||||
if (size < ONE_KB) {
|
|
||||||
return size.toFixed(0) + " B";
|
|
||||||
} else if (size < ONE_MB) {
|
|
||||||
return (size / ONE_KB).toFixed(2) + " KB";
|
|
||||||
} else if (size < ONE_GB) {
|
|
||||||
return (size / ONE_MB).toFixed(2) + " MB";
|
|
||||||
} else if (size < ONE_TB) {
|
|
||||||
return (size / ONE_GB).toFixed(2) + " GB";
|
|
||||||
} else if (size < ONE_PB) {
|
|
||||||
return (size / ONE_TB).toFixed(2) + " TB";
|
|
||||||
} else {
|
|
||||||
return (size / ONE_PB).toFixed(2) + " PB";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cpuSpeedFormat(speed) {
|
|
||||||
if (speed > 1000) {
|
|
||||||
const GHz = speed / 1000;
|
|
||||||
return GHz.toFixed(2) + " GHz";
|
|
||||||
} else {
|
|
||||||
return speed.toFixed(2) + " MHz";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cpuCoreFormat(cores) {
|
|
||||||
if (cores === 1) {
|
|
||||||
return "1 Core";
|
|
||||||
} else {
|
|
||||||
return cores + " Cores";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatSecond(second) {
|
|
||||||
if (second < 60) {
|
|
||||||
return second.toFixed(0) + 's';
|
|
||||||
} else if (second < 3600) {
|
|
||||||
return (second / 60).toFixed(0) + 'm';
|
|
||||||
} else if (second < 3600 * 24) {
|
|
||||||
return (second / 3600).toFixed(0) + 'h';
|
|
||||||
} else {
|
|
||||||
day = Math.floor(second / 3600 / 24);
|
|
||||||
remain = ((second / 3600) - (day * 24)).toFixed(0);
|
|
||||||
return day + 'd' + (remain > 0 ? ' ' + remain + 'h' : '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addZero(num) {
|
|
||||||
if (num < 10) {
|
|
||||||
return "0" + num;
|
|
||||||
} else {
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toFixed(num, n) {
|
|
||||||
n = Math.pow(10, n);
|
|
||||||
return Math.floor(num * n) / n;
|
|
||||||
}
|
|
||||||
|
|
||||||
function debounce(fn, delay) {
|
|
||||||
var timeoutID = null;
|
|
||||||
return function () {
|
|
||||||
clearTimeout(timeoutID);
|
|
||||||
var args = arguments;
|
|
||||||
var that = this;
|
|
||||||
timeoutID = setTimeout(function () {
|
|
||||||
fn.apply(that, args);
|
|
||||||
}, delay);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCookie(cname) {
|
|
||||||
let name = cname + '=';
|
|
||||||
let ca = document.cookie.split(';');
|
|
||||||
for (let i = 0; i < ca.length; i++) {
|
|
||||||
let c = ca[i];
|
|
||||||
while (c.charAt(0) == ' ') {
|
|
||||||
c = c.substring(1);
|
|
||||||
}
|
|
||||||
if (c.indexOf(name) == 0) {
|
|
||||||
// decode cookie value only
|
|
||||||
return decodeURIComponent(c.substring(name.length, c.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function setCookie(cname, cvalue, exdays) {
|
|
||||||
const d = new Date();
|
|
||||||
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
|
|
||||||
let expires = 'expires=' + d.toUTCString();
|
|
||||||
// encode cookie value
|
|
||||||
document.cookie = cname + '=' + encodeURIComponent(cvalue) + ';' + expires + ';path=/';
|
|
||||||
}
|
|
||||||
|
|
||||||
function usageColor(data, threshold, total) {
|
|
||||||
switch (true) {
|
|
||||||
case data === null:
|
|
||||||
return "purple";
|
|
||||||
case total < 0:
|
|
||||||
return "green";
|
|
||||||
case total == 0:
|
|
||||||
return "purple";
|
|
||||||
case data < total - threshold:
|
|
||||||
return "green";
|
|
||||||
case data < total:
|
|
||||||
return "orange";
|
|
||||||
default:
|
|
||||||
return "red";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clientUsageColor(clientStats, trafficDiff) {
|
|
||||||
switch (true) {
|
|
||||||
case !clientStats || clientStats.total == 0:
|
|
||||||
return "#7a316f"; // purple
|
|
||||||
case clientStats.up + clientStats.down < clientStats.total - trafficDiff:
|
|
||||||
return "#008771"; // Green
|
|
||||||
case clientStats.up + clientStats.down < clientStats.total:
|
|
||||||
return "#f37b24"; // Orange
|
|
||||||
default:
|
|
||||||
return "#cf3c3c"; // Red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function userExpiryColor(threshold, client, isDark = false) {
|
|
||||||
if (!client.enable) {
|
|
||||||
return isDark ? '#2c3950' : '#bcbcbc';
|
|
||||||
}
|
|
||||||
now = new Date().getTime(),
|
|
||||||
expiry = client.expiryTime;
|
|
||||||
switch (true) {
|
|
||||||
case expiry === null:
|
|
||||||
return "#7a316f"; // purple
|
|
||||||
case expiry < 0:
|
|
||||||
return "#008771"; // Green
|
|
||||||
case expiry == 0:
|
|
||||||
return "#7a316f"; // purple
|
|
||||||
case now < expiry - threshold:
|
|
||||||
return "#008771"; // Green
|
|
||||||
case now < expiry:
|
|
||||||
return "#f37b24"; // Orange
|
|
||||||
default:
|
|
||||||
return "#cf3c3c"; // Red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function doAllItemsExist(array1, array2) {
|
|
||||||
for (let i = 0; i < array1.length; i++) {
|
|
||||||
if (!array2.includes(array1[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildURL({ host, port, isTLS, base, path }) {
|
|
||||||
if (!host || host.length === 0) host = window.location.hostname;
|
|
||||||
if (!port || port.length === 0) port = window.location.port;
|
|
||||||
|
|
||||||
if (isTLS === undefined) isTLS = window.location.protocol === "https:";
|
|
||||||
|
|
||||||
const protocol = isTLS ? "https:" : "http:";
|
|
||||||
|
|
||||||
port = String(port);
|
|
||||||
if (port === "" || (isTLS && port === "443") || (!isTLS && port === "80")) {
|
|
||||||
port = "";
|
|
||||||
} else {
|
|
||||||
port = `:${port}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${protocol}//${host}${port}${base}${path}`;
|
|
||||||
}
|
|
|
@ -108,14 +108,14 @@ Date.prototype.setMaxTime = function () {
|
||||||
* Formatting date
|
* Formatting date
|
||||||
*/
|
*/
|
||||||
Date.prototype.formatDate = function () {
|
Date.prototype.formatDate = function () {
|
||||||
return this.getFullYear() + "-" + addZero(this.getMonth() + 1) + "-" + addZero(this.getDate());
|
return this.getFullYear() + "-" + NumberFormatter.addZero(this.getMonth() + 1) + "-" + NumberFormatter.addZero(this.getDate());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format time
|
* Format time
|
||||||
*/
|
*/
|
||||||
Date.prototype.formatTime = function () {
|
Date.prototype.formatTime = function () {
|
||||||
return addZero(this.getHours()) + ":" + addZero(this.getMinutes()) + ":" + addZero(this.getSeconds());
|
return NumberFormatter.addZero(this.getHours()) + ":" + NumberFormatter.addZero(this.getMinutes()) + ":" + NumberFormatter.addZero(this.getSeconds());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -527,4 +527,146 @@ class Base64 {
|
||||||
static decode(content = "") {
|
static decode(content = "") {
|
||||||
return window.atob(content)
|
return window.atob(content)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SizeFormatter {
|
||||||
|
static ONE_KB = 1024;
|
||||||
|
static ONE_MB = this.ONE_KB * 1024;
|
||||||
|
static ONE_GB = this.ONE_MB * 1024;
|
||||||
|
static ONE_TB = this.ONE_GB * 1024;
|
||||||
|
static ONE_PB = this.ONE_TB * 1024;
|
||||||
|
|
||||||
|
static sizeFormat(size) {
|
||||||
|
if (size <= 0) return "0 B";
|
||||||
|
if (size < this.ONE_KB) return size.toFixed(0) + " B";
|
||||||
|
if (size < this.ONE_MB) return (size / this.ONE_KB).toFixed(2) + " KB";
|
||||||
|
if (size < this.ONE_GB) return (size / this.ONE_MB).toFixed(2) + " MB";
|
||||||
|
if (size < this.ONE_TB) return (size / this.ONE_GB).toFixed(2) + " GB";
|
||||||
|
if (size < this.ONE_PB) return (size / this.ONE_TB).toFixed(2) + " TB";
|
||||||
|
return (size / this.ONE_PB).toFixed(2) + " PB";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPUFormatter {
|
||||||
|
static cpuSpeedFormat(speed) {
|
||||||
|
return speed > 1000 ? (speed / 1000).toFixed(2) + " GHz" : speed.toFixed(2) + " MHz";
|
||||||
|
}
|
||||||
|
|
||||||
|
static cpuCoreFormat(cores) {
|
||||||
|
return cores === 1 ? "1 Core" : cores + " Cores";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeFormatter {
|
||||||
|
static formatSecond(second) {
|
||||||
|
if (second < 60) return second.toFixed(0) + 's';
|
||||||
|
if (second < 3600) return (second / 60).toFixed(0) + 'm';
|
||||||
|
if (second < 3600 * 24) return (second / 3600).toFixed(0) + 'h';
|
||||||
|
let day = Math.floor(second / 3600 / 24);
|
||||||
|
let remain = ((second / 3600) - (day * 24)).toFixed(0);
|
||||||
|
return day + 'd' + (remain > 0 ? ' ' + remain + 'h' : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NumberFormatter {
|
||||||
|
static addZero(num) {
|
||||||
|
return num < 10 ? "0" + num : num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static toFixed(num, n) {
|
||||||
|
n = Math.pow(10, n);
|
||||||
|
return Math.floor(num * n) / n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Utils {
|
||||||
|
static debounce(fn, delay) {
|
||||||
|
let timeoutID = null;
|
||||||
|
return function () {
|
||||||
|
clearTimeout(timeoutID);
|
||||||
|
let args = arguments;
|
||||||
|
let that = this;
|
||||||
|
timeoutID = setTimeout(() => fn.apply(that, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CookieManager {
|
||||||
|
static getCookie(cname) {
|
||||||
|
let name = cname + '=';
|
||||||
|
let ca = document.cookie.split(';');
|
||||||
|
for (let c of ca) {
|
||||||
|
c = c.trim();
|
||||||
|
if (c.indexOf(name) === 0) {
|
||||||
|
return decodeURIComponent(c.substring(name.length, c.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
static setCookie(cname, cvalue, exdays) {
|
||||||
|
const d = new Date();
|
||||||
|
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
|
||||||
|
let expires = 'expires=' + d.toUTCString();
|
||||||
|
document.cookie = cname + '=' + encodeURIComponent(cvalue) + ';' + expires + ';path=/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColorUtils {
|
||||||
|
static usageColor(data, threshold, total) {
|
||||||
|
switch (true) {
|
||||||
|
case data === null: return "purple";
|
||||||
|
case total < 0: return "green";
|
||||||
|
case total == 0: return "purple";
|
||||||
|
case data < total - threshold: return "green";
|
||||||
|
case data < total: return "orange";
|
||||||
|
default: return "red";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static clientUsageColor(clientStats, trafficDiff) {
|
||||||
|
switch (true) {
|
||||||
|
case !clientStats || clientStats.total == 0: return "#7a316f";
|
||||||
|
case clientStats.up + clientStats.down < clientStats.total - trafficDiff: return "#008771";
|
||||||
|
case clientStats.up + clientStats.down < clientStats.total: return "#f37b24";
|
||||||
|
default: return "#cf3c3c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static userExpiryColor(threshold, client, isDark = false) {
|
||||||
|
if (!client.enable) return isDark ? '#2c3950' : '#bcbcbc';
|
||||||
|
let now = new Date().getTime(), expiry = client.expiryTime;
|
||||||
|
switch (true) {
|
||||||
|
case expiry === null: return "#7a316f";
|
||||||
|
case expiry < 0: return "#008771";
|
||||||
|
case expiry == 0: return "#7a316f";
|
||||||
|
case now < expiry - threshold: return "#008771";
|
||||||
|
case now < expiry: return "#f37b24";
|
||||||
|
default: return "#cf3c3c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArrayUtils {
|
||||||
|
static doAllItemsExist(array1, array2) {
|
||||||
|
return array1.every(item => array2.includes(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class URLBuilder {
|
||||||
|
static buildURL({ host, port, isTLS, base, path }) {
|
||||||
|
if (!host || host.length === 0) host = window.location.hostname;
|
||||||
|
if (!port || port.length === 0) port = window.location.port;
|
||||||
|
if (isTLS === undefined) isTLS = window.location.protocol === "https:";
|
||||||
|
|
||||||
|
const protocol = isTLS ? "https:" : "http:";
|
||||||
|
port = String(port);
|
||||||
|
if (port === "" || (isTLS && port === "443") || (!isTLS && port === "80")) {
|
||||||
|
port = "";
|
||||||
|
} else {
|
||||||
|
port = `:${port}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${protocol}//${host}${port}${base}${path}`;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -5,9 +5,8 @@
|
||||||
<script src="{{ .base_path }}assets/axios/axios.min.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/axios/axios.min.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/qs/qs.min.js"></script>
|
<script src="{{ .base_path }}assets/qs/qs.min.js"></script>
|
||||||
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/util/common.js?{{ .cur_ver }}"></script>
|
|
||||||
<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/util/date-util.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/util/utils.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/langs.js"></script>
|
<script src="{{ .base_path }}assets/js/langs.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const basePath = '{{ .base_path }}';
|
const basePath = '{{ .base_path }}';
|
||||||
|
|
|
@ -126,10 +126,10 @@
|
||||||
<a-input-number v-model.number="client._totalGB" :min="0"></a-input-number>
|
<a-input-number v-model.number="client._totalGB" :min="0"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="isEdit && clientStats" label='{{ i18n "usage" }}'>
|
<a-form-item v-if="isEdit && clientStats" label='{{ i18n "usage" }}'>
|
||||||
<a-tag :color="clientUsageColor(clientStats, app.trafficDiff)">
|
<a-tag :color="ColorUtils.clientUsageColor(clientStats, app.trafficDiff)">
|
||||||
[[ sizeFormat(clientStats.up) ]] /
|
[[ SizeFormatter.sizeFormat(clientStats.up) ]] /
|
||||||
[[ sizeFormat(clientStats.down) ]]
|
[[ SizeFormatter.sizeFormat(clientStats.down) ]]
|
||||||
([[ sizeFormat(clientStats.up + clientStats.down) ]])
|
([[ SizeFormatter.sizeFormat(clientStats.up + clientStats.down) ]])
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">{{ i18n "pages.inbounds.resetTraffic" }}</template>
|
<template slot="title">{{ i18n "pages.inbounds.resetTraffic" }}</template>
|
||||||
|
|
|
@ -55,18 +55,18 @@
|
||||||
<template slot="content" v-if="client.email">
|
<template slot="content" v-if="client.email">
|
||||||
<table cellpadding="2" width="100%">
|
<table cellpadding="2" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>↑[[ sizeFormat(getUpStats(record, client.email)) ]]</td>
|
<td>↑[[ SizeFormatter.sizeFormat(getUpStats(record, client.email)) ]]</td>
|
||||||
<td>↓[[ sizeFormat(getDownStats(record, client.email)) ]]</td>
|
<td>↓[[ SizeFormatter.sizeFormat(getDownStats(record, client.email)) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="client.totalGB > 0">
|
<tr v-if="client.totalGB > 0">
|
||||||
<td>{{ i18n "remained" }}</td>
|
<td>{{ i18n "remained" }}</td>
|
||||||
<td>[[ sizeFormat(getRemStats(record, client.email)) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(getRemStats(record, client.email)) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
<table>
|
<table>
|
||||||
<tr class="tr-table-box">
|
<tr class="tr-table-box">
|
||||||
<td class="tr-table-rt"> [[ sizeFormat(getSumStats(record, client.email)) ]] </td>
|
<td class="tr-table-rt"> [[ SizeFormatter.sizeFormat(getSumStats(record, client.email)) ]] </td>
|
||||||
<td class="tr-table-bar" v-if="!client.enable">
|
<td class="tr-table-bar" v-if="!client.enable">
|
||||||
<a-progress :stroke-color="themeSwitcher.isDarkTheme ? 'rgb(72 84 105)' : '#bcbcbc'" :show-info="false" :percent="statsProgress(record, client.email)" />
|
<a-progress :stroke-color="themeSwitcher.isDarkTheme ? 'rgb(72 84 105)' : '#bcbcbc'" :show-info="false" :percent="statsProgress(record, client.email)" />
|
||||||
</td>
|
</td>
|
||||||
|
@ -124,9 +124,9 @@
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<a-tag style="min-width: 50px; border: none;" :color="userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)"> [[ remainedDays(client.expiryTime) ]] </a-tag>
|
<a-tag style="min-width: 50px; border: none;" :color="ColorUtils.userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)"> [[ remainedDays(client.expiryTime) ]] </a-tag>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-tag v-else :color="userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)" style="border: none;" class="infinite-tag">
|
<a-tag v-else :color="ColorUtils.userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)" style="border: none;" class="infinite-tag">
|
||||||
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
||||||
<path d="M484.4 96C407 96 349.2 164.1 320 208.5C290.8 164.1 233 96 155.6 96C69.75 96 0 167.8 0 256s69.75 160 155.6 160C233.1 416 290.8 347.9 320 303.5C349.2 347.9 407 416 484.4 416C570.3 416 640 344.2 640 256S570.3 96 484.4 96zM155.6 368C96.25 368 48 317.8 48 256s48.25-112 107.6-112c67.75 0 120.5 82.25 137.1 112C276 285.8 223.4 368 155.6 368zM484.4 368c-67.75 0-120.5-82.25-137.1-112C364 226.2 416.6 144 484.4 144C543.8 144 592 194.2 592 256S543.8 368 484.4 368z" fill="currentColor"></path>
|
<path d="M484.4 96C407 96 349.2 164.1 320 208.5C290.8 164.1 233 96 155.6 96C69.75 96 0 167.8 0 256s69.75 160 155.6 160C233.1 416 290.8 347.9 320 303.5C349.2 347.9 407 416 484.4 416C570.3 416 640 344.2 640 256S570.3 96 484.4 96zM155.6 368C96.25 368 48 317.8 48 256s48.25-112 107.6-112c67.75 0 120.5 82.25 137.1 112C276 285.8 223.4 368 155.6 368zM484.4 368c-67.75 0-120.5-82.25-137.1-112C364 226.2 416.6 144 484.4 144C543.8 144 592 194.2 592 256S543.8 368 484.4 368z" fill="currentColor"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
<td colspan="3" style="text-align: center;">{{ i18n "pages.inbounds.traffic" }}</td>
|
<td colspan="3" style="text-align: center;">{{ i18n "pages.inbounds.traffic" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="80px" style="margin:0; text-align: right;font-size: 1em;"> [[ sizeFormat(getUpStats(record, client.email) + getDownStats(record, client.email)) ]] </td>
|
<td width="80px" style="margin:0; text-align: right;font-size: 1em;"> [[ SizeFormatter.sizeFormat(getUpStats(record, client.email) + getDownStats(record, client.email)) ]] </td>
|
||||||
<td width="120px" v-if="!client.enable">
|
<td width="120px" v-if="!client.enable">
|
||||||
<a-progress :stroke-color="themeSwitcher.isDarkTheme ? 'rgb(72 84 105)' : '#bcbcbc'" :show-info="false" :percent="statsProgress(record, client.email)" />
|
<a-progress :stroke-color="themeSwitcher.isDarkTheme ? 'rgb(72 84 105)' : '#bcbcbc'" :show-info="false" :percent="statsProgress(record, client.email)" />
|
||||||
</td>
|
</td>
|
||||||
|
@ -181,12 +181,12 @@
|
||||||
<template slot="content" v-if="client.email">
|
<template slot="content" v-if="client.email">
|
||||||
<table cellpadding="2" width="100%">
|
<table cellpadding="2" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>↑[[ sizeFormat(getUpStats(record, client.email)) ]]</td>
|
<td>↑[[ SizeFormatter.sizeFormat(getUpStats(record, client.email)) ]]</td>
|
||||||
<td>↓[[ sizeFormat(getDownStats(record, client.email)) ]]</td>
|
<td>↓[[ SizeFormatter.sizeFormat(getDownStats(record, client.email)) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i18n "remained" }}</td>
|
<td>{{ i18n "remained" }}</td>
|
||||||
<td>[[ sizeFormat(getRemStats(record, client.email)) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(getRemStats(record, client.email)) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<a-tag style="min-width: 50px; border: none;" :color="userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)"> [[ remainedDays(client.expiryTime) ]] </a-tag>
|
<a-tag style="min-width: 50px; border: none;" :color="ColorUtils.userExpiryColor(app.expireDiff, client, themeSwitcher.isDarkTheme)"> [[ remainedDays(client.expiryTime) ]] </a-tag>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-tag v-else :color="client.enable ? 'purple' : themeSwitcher.isDarkTheme ? '#2c3950' : '#bcbcbc'" class="infinite-tag">
|
<a-tag v-else :color="client.enable ? 'purple' : themeSwitcher.isDarkTheme ? '#2c3950' : '#bcbcbc'" class="infinite-tag">
|
||||||
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
||||||
|
|
|
@ -181,8 +181,8 @@
|
||||||
<tr v-if="infoModal.clientStats">
|
<tr v-if="infoModal.clientStats">
|
||||||
<td>{{ i18n "usage" }}</td>
|
<td>{{ i18n "usage" }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a-tag color="green">[[ sizeFormat(infoModal.clientStats.up + infoModal.clientStats.down) ]]</a-tag>
|
<a-tag color="green">[[ SizeFormatter.sizeFormat(infoModal.clientStats.up + infoModal.clientStats.down) ]]</a-tag>
|
||||||
<a-tag>↑ [[ sizeFormat(infoModal.clientStats.up) ]] / [[ sizeFormat(infoModal.clientStats.down) ]] ↓</a-tag>
|
<a-tag>↑ [[ SizeFormatter.sizeFormat(infoModal.clientStats.up) ]] / [[ SizeFormatter.sizeFormat(infoModal.clientStats.down) ]] ↓</a-tag>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="infoModal.clientSettings.comment">
|
<tr v-if="infoModal.clientSettings.comment">
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
<a-tag v-if="infoModal.clientStats && infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)"> [[ getRemStats() ]] </a-tag>
|
<a-tag v-if="infoModal.clientStats && infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)"> [[ getRemStats() ]] </a-tag>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a-tag v-if="infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)"> [[ sizeFormat(infoModal.clientSettings.totalGB) ]] </a-tag>
|
<a-tag v-if="infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)"> [[ SizeFormatter.sizeFormat(infoModal.clientSettings.totalGB) ]] </a-tag>
|
||||||
<a-tag v-else color="purple" class="infinite-tag">
|
<a-tag v-else color="purple" class="infinite-tag">
|
||||||
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
||||||
<path d="M484.4 96C407 96 349.2 164.1 320 208.5C290.8 164.1 233 96 155.6 96C69.75 96 0 167.8 0 256s69.75 160 155.6 160C233.1 416 290.8 347.9 320 303.5C349.2 347.9 407 416 484.4 416C570.3 416 640 344.2 640 256S570.3 96 484.4 96zM155.6 368C96.25 368 48 317.8 48 256s48.25-112 107.6-112c67.75 0 120.5 82.25 137.1 112C276 285.8 223.4 368 155.6 368zM484.4 368c-67.75 0-120.5-82.25-137.1-112C364 226.2 416.6 144 484.4 144C543.8 144 592 194.2 592 256S543.8 368 484.4 368z" fill="currentColor"></path>
|
<path d="M484.4 96C407 96 349.2 164.1 320 208.5C290.8 164.1 233 96 155.6 96C69.75 96 0 167.8 0 256s69.75 160 155.6 160C233.1 416 290.8 347.9 320 303.5C349.2 347.9 407 416 484.4 416C570.3 416 640 344.2 640 256S570.3 96 484.4 96zM155.6 368C96.25 368 48 317.8 48 256s48.25-112 107.6-112c67.75 0 120.5 82.25 137.1 112C276 285.8 223.4 368 155.6 368zM484.4 368c-67.75 0-120.5-82.25-137.1-112C364 226.2 416.6 144 484.4 144C543.8 144 592 194.2 592 256S543.8 368 484.4 368z" fill="currentColor"></path>
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<template v-if="infoModal.clientSettings.expiryTime > 0">
|
<template v-if="infoModal.clientSettings.expiryTime > 0">
|
||||||
<a-tag :color="usageColor(new Date().getTime(), app.expireDiff, infoModal.clientSettings.expiryTime)">
|
<a-tag :color="ColorUtils.usageColor(new Date().getTime(), app.expireDiff, infoModal.clientSettings.expiryTime)">
|
||||||
<template v-if="app.datepicker === 'gregorian'">
|
<template v-if="app.datepicker === 'gregorian'">
|
||||||
[[ DateUtil.formatMillis(infoModal.clientSettings.expiryTime) ]]
|
[[ DateUtil.formatMillis(infoModal.clientSettings.expiryTime) ]]
|
||||||
</template>
|
</template>
|
||||||
|
@ -540,11 +540,11 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
statsColor(stats) {
|
statsColor(stats) {
|
||||||
return usageColor(stats.up + stats.down, app.trafficDiff, stats.total);
|
return ColorUtils.usageColor(stats.up + stats.down, app.trafficDiff, stats.total);
|
||||||
},
|
},
|
||||||
getRemStats() {
|
getRemStats() {
|
||||||
remained = this.infoModal.clientStats.total - this.infoModal.clientStats.up - this.infoModal.clientStats.down;
|
remained = this.infoModal.clientStats.total - this.infoModal.clientStats.up - this.infoModal.clientStats.down;
|
||||||
return remained > 0 ? sizeFormat(remained) : '-';
|
return remained > 0 ? SizeFormatter.sizeFormat(remained) : '-';
|
||||||
},
|
},
|
||||||
refreshIPs() {
|
refreshIPs() {
|
||||||
this.refreshing = true;
|
this.refreshing = true;
|
||||||
|
|
|
@ -141,11 +141,11 @@
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :xs="24" :sm="24" :lg="12">
|
<a-col :xs="24" :sm="24" :lg="12">
|
||||||
{{ i18n "pages.inbounds.totalDownUp" }}:
|
{{ i18n "pages.inbounds.totalDownUp" }}:
|
||||||
<a-tag color="green">[[ sizeFormat(total.up) ]] / [[ sizeFormat(total.down) ]]</a-tag>
|
<a-tag color="green">[[ SizeFormatter.sizeFormat(total.up) ]] / [[ SizeFormatter.sizeFormat(total.down) ]]</a-tag>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :lg="12">
|
<a-col :xs="24" :sm="24" :lg="12">
|
||||||
{{ i18n "pages.inbounds.totalUsage" }}:
|
{{ i18n "pages.inbounds.totalUsage" }}:
|
||||||
<a-tag color="green">[[ sizeFormat(total.up + total.down) ]]</a-tag>
|
<a-tag color="green">[[ SizeFormatter.sizeFormat(total.up + total.down) ]]</a-tag>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :lg="12">
|
<a-col :xs="24" :sm="24" :lg="12">
|
||||||
{{ i18n "pages.inbounds.inboundCount" }}:
|
{{ i18n "pages.inbounds.inboundCount" }}:
|
||||||
|
@ -375,19 +375,19 @@
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<table cellpadding="2" width="100%">
|
<table cellpadding="2" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>↑[[ sizeFormat(dbInbound.up) ]]</td>
|
<td>↑[[ SizeFormatter.sizeFormat(dbInbound.up) ]]</td>
|
||||||
<td>↓[[ sizeFormat(dbInbound.down) ]]</td>
|
<td>↓[[ SizeFormatter.sizeFormat(dbInbound.down) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="dbInbound.total > 0 && dbInbound.up + dbInbound.down < dbInbound.total">
|
<tr v-if="dbInbound.total > 0 && dbInbound.up + dbInbound.down < dbInbound.total">
|
||||||
<td>{{ i18n "remained" }}</td>
|
<td>{{ i18n "remained" }}</td>
|
||||||
<td>[[ sizeFormat(dbInbound.total - dbInbound.up - dbInbound.down) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(dbInbound.total - dbInbound.up - dbInbound.down) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
<a-tag :color="usageColor(dbInbound.up + dbInbound.down, app.trafficDiff, dbInbound.total)">
|
<a-tag :color="ColorUtils.usageColor(dbInbound.up + dbInbound.down, app.trafficDiff, dbInbound.total)">
|
||||||
[[ sizeFormat(dbInbound.up + dbInbound.down) ]] /
|
[[ SizeFormatter.sizeFormat(dbInbound.up + dbInbound.down) ]] /
|
||||||
<template v-if="dbInbound.total > 0">
|
<template v-if="dbInbound.total > 0">
|
||||||
[[ sizeFormat(dbInbound.total) ]]
|
[[ SizeFormatter.sizeFormat(dbInbound.total) ]]
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
||||||
|
@ -408,7 +408,7 @@
|
||||||
<template v-else slot="content">
|
<template v-else slot="content">
|
||||||
[[ DateUtil.convertToJalalian(moment(dbInbound.expiryTime)) ]]
|
[[ DateUtil.convertToJalalian(moment(dbInbound.expiryTime)) ]]
|
||||||
</template>
|
</template>
|
||||||
<a-tag style="min-width: 50px;" :color="usageColor(new Date().getTime(), app.expireDiff, dbInbound._expiryTime)">
|
<a-tag style="min-width: 50px;" :color="ColorUtils.usageColor(new Date().getTime(), app.expireDiff, dbInbound._expiryTime)">
|
||||||
[[ remainedDays(dbInbound._expiryTime) ]]
|
[[ remainedDays(dbInbound._expiryTime) ]]
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
|
@ -474,19 +474,19 @@
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<table cellpadding="2" width="100%">
|
<table cellpadding="2" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>↑[[ sizeFormat(dbInbound.up) ]]</td>
|
<td>↑[[ SizeFormatter.sizeFormat(dbInbound.up) ]]</td>
|
||||||
<td>↓[[ sizeFormat(dbInbound.down) ]]</td>
|
<td>↓[[ SizeFormatter.sizeFormat(dbInbound.down) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="dbInbound.total > 0 && dbInbound.up + dbInbound.down < dbInbound.total">
|
<tr v-if="dbInbound.total > 0 && dbInbound.up + dbInbound.down < dbInbound.total">
|
||||||
<td>{{ i18n "remained" }}</td>
|
<td>{{ i18n "remained" }}</td>
|
||||||
<td>[[ sizeFormat(dbInbound.total - dbInbound.up - dbInbound.down) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(dbInbound.total - dbInbound.up - dbInbound.down) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
<a-tag :color="usageColor(dbInbound.up + dbInbound.down, app.trafficDiff, dbInbound.total)">
|
<a-tag :color="ColorUtils.usageColor(dbInbound.up + dbInbound.down, app.trafficDiff, dbInbound.total)">
|
||||||
[[ sizeFormat(dbInbound.up + dbInbound.down) ]] /
|
[[ SizeFormatter.sizeFormat(dbInbound.up + dbInbound.down) ]] /
|
||||||
<template v-if="dbInbound.total > 0">
|
<template v-if="dbInbound.total > 0">
|
||||||
[[ sizeFormat(dbInbound.total) ]]
|
[[ SizeFormatter.sizeFormat(dbInbound.total) ]]
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
<svg height="10px" width="14px" viewBox="0 0 640 512" fill="currentColor">
|
||||||
|
@ -1274,9 +1274,9 @@
|
||||||
return remained>0 ? remained : 0;
|
return remained>0 ? remained : 0;
|
||||||
},
|
},
|
||||||
clientStatsColor(dbInbound, email) {
|
clientStatsColor(dbInbound, email) {
|
||||||
if (email.length == 0) return clientUsageColor();
|
if (email.length == 0) return ColorUtils.clientUsageColor();
|
||||||
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
|
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
|
||||||
return clientUsageColor(clientStats, app.trafficDiff)
|
return ColorUtils.clientUsageColor(clientStats, app.trafficDiff)
|
||||||
},
|
},
|
||||||
statsProgress(dbInbound, email) {
|
statsProgress(dbInbound, email) {
|
||||||
if (email.length == 0) return 100;
|
if (email.length == 0) return 100;
|
||||||
|
@ -1294,17 +1294,17 @@
|
||||||
},
|
},
|
||||||
remainedDays(expTime){
|
remainedDays(expTime){
|
||||||
if (expTime == 0) return null;
|
if (expTime == 0) return null;
|
||||||
if (expTime < 0) return formatSecond(expTime/-1000);
|
if (expTime < 0) return TimeFormatter.formatSecond(expTime/-1000);
|
||||||
now = new Date().getTime();
|
now = new Date().getTime();
|
||||||
if (expTime < now) return '{{ i18n "depleted" }}';
|
if (expTime < now) return '{{ i18n "depleted" }}';
|
||||||
return formatSecond((expTime-now)/1000);
|
return TimeFormatter.formatSecond((expTime-now)/1000);
|
||||||
},
|
},
|
||||||
statsExpColor(dbInbound, email){
|
statsExpColor(dbInbound, email){
|
||||||
if (email.length == 0) return '#7a316f';
|
if (email.length == 0) return '#7a316f';
|
||||||
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
|
clientStats = dbInbound.clientStats.find(stats => stats.email === email);
|
||||||
if (!clientStats) return '#7a316f';
|
if (!clientStats) return '#7a316f';
|
||||||
statsColor = usageColor(clientStats.down + clientStats.up, this.trafficDiff, clientStats.total);
|
statsColor = ColorUtils.usageColor(clientStats.down + clientStats.up, this.trafficDiff, clientStats.total);
|
||||||
expColor = usageColor(new Date().getTime(), this.expireDiff, clientStats.expiryTime);
|
expColor = ColorUtils.usageColor(new Date().getTime(), this.expireDiff, clientStats.expiryTime);
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case statsColor == "red" || expColor == "red":
|
case statsColor == "red" || expColor == "red":
|
||||||
return "#cf3c3c"; // Red
|
return "#cf3c3c"; // Red
|
||||||
|
@ -1438,7 +1438,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
searchKey: debounce(function (newVal) {
|
searchKey: Utils.debounce(function (newVal) {
|
||||||
this.searchInbounds(newVal);
|
this.searchInbounds(newVal);
|
||||||
}, 500)
|
}, 500)
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,11 +45,11 @@
|
||||||
<a-progress type="dashboard" status="normal"
|
<a-progress type="dashboard" status="normal"
|
||||||
:stroke-color="status.cpu.color"
|
:stroke-color="status.cpu.color"
|
||||||
:percent="status.cpu.percent"></a-progress>
|
:percent="status.cpu.percent"></a-progress>
|
||||||
<div><b>CPU:</b> [[ cpuCoreFormat(status.cpuCores) ]] <a-tooltip>
|
<div><b>CPU:</b> [[ CPUFormatter.cpuCoreFormat(status.cpuCores) ]] <a-tooltip>
|
||||||
<a-icon type="area-chart"></a-icon>
|
<a-icon type="area-chart"></a-icon>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<div><b>Logical Processors:</b> [[ (status.logicalPro) ]]</div>
|
<div><b>Logical Processors:</b> [[ (status.logicalPro) ]]</div>
|
||||||
<div><b>Speed:</b> [[ cpuSpeedFormat(status.cpuSpeedMhz) ]]</div>
|
<div><b>Speed:</b> [[ CPUFormatter.cpuSpeedFormat(status.cpuSpeedMhz) ]]</div>
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip></div>
|
</a-tooltip></div>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
:stroke-color="status.mem.color"
|
:stroke-color="status.mem.color"
|
||||||
:percent="status.mem.percent"></a-progress>
|
:percent="status.mem.percent"></a-progress>
|
||||||
<div>
|
<div>
|
||||||
<b>{{ i18n "pages.index.memory"}}:</b> [[ sizeFormat(status.mem.current) ]] / [[ sizeFormat(status.mem.total) ]]
|
<b>{{ i18n "pages.index.memory"}}:</b> [[ SizeFormatter.sizeFormat(status.mem.current) ]] / [[ SizeFormatter.sizeFormat(status.mem.total) ]]
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
:stroke-color="status.swap.color"
|
:stroke-color="status.swap.color"
|
||||||
:percent="status.swap.percent"></a-progress>
|
:percent="status.swap.percent"></a-progress>
|
||||||
<div>
|
<div>
|
||||||
<b>Swap:</b> [[ sizeFormat(status.swap.current) ]] / [[ sizeFormat(status.swap.total) ]]
|
<b>Swap:</b> [[ SizeFormatter.sizeFormat(status.swap.current) ]] / [[ SizeFormatter.sizeFormat(status.swap.total) ]]
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" style="text-align: center">
|
<a-col :span="12" style="text-align: center">
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
:stroke-color="status.disk.color"
|
:stroke-color="status.disk.color"
|
||||||
:percent="status.disk.percent"></a-progress>
|
:percent="status.disk.percent"></a-progress>
|
||||||
<div>
|
<div>
|
||||||
<b>{{ i18n "pages.index.hard"}}:</b> [[ sizeFormat(status.disk.current) ]] / [[ sizeFormat(status.disk.total) ]]
|
<b>{{ i18n "pages.index.hard"}}:</b> [[ SizeFormatter.sizeFormat(status.disk.current) ]] / [[ SizeFormatter.sizeFormat(status.disk.total) ]]
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
@ -99,8 +99,8 @@
|
||||||
<a-col :sm="24" :lg="12">
|
<a-col :sm="24" :lg="12">
|
||||||
<a-card hoverable>
|
<a-card hoverable>
|
||||||
<b>{{ i18n "pages.index.operationHours" }}:</b>
|
<b>{{ i18n "pages.index.operationHours" }}:</b>
|
||||||
<a-tag :color="status.xray.color">Xray: [[ formatSecond(status.appStats.uptime) ]]</a-tag>
|
<a-tag :color="status.xray.color">Xray: [[ TimeFormatter.formatSecond(status.appStats.uptime) ]]</a-tag>
|
||||||
<a-tag color="green">OS: [[ formatSecond(status.uptime) ]]</a-tag>
|
<a-tag color="green">OS: [[ TimeFormatter.formatSecond(status.uptime) ]]</a-tag>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :sm="24" :lg="12">
|
<a-col :sm="24" :lg="12">
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
<a-col :sm="24" :lg="12">
|
<a-col :sm="24" :lg="12">
|
||||||
<a-card hoverable>
|
<a-card hoverable>
|
||||||
<b>{{ i18n "usage"}}:</b>
|
<b>{{ i18n "usage"}}:</b>
|
||||||
<a-tag color="green"> RAM: [[ sizeFormat(status.appStats.mem) ]] </a-tag>
|
<a-tag color="green"> RAM: [[ SizeFormatter.sizeFormat(status.appStats.mem) ]] </a-tag>
|
||||||
<a-tag color="green"> Threads: [[ status.appStats.threads ]] </a-tag>
|
<a-tag color="green"> Threads: [[ status.appStats.threads ]] </a-tag>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -207,7 +207,7 @@
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-tag>
|
<a-tag>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<a-icon type="arrow-up"></a-icon> Up: [[ sizeFormat(status.netIO.up) ]]/s
|
<a-icon type="arrow-up"></a-icon> Up: [[ SizeFormatter.sizeFormat(status.netIO.up) ]]/s
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.upSpeed" }}
|
{{ i18n "pages.index.upSpeed" }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-tag>
|
<a-tag>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<a-icon type="arrow-down"></a-icon> Down: [[ sizeFormat(status.netIO.down) ]]/s
|
<a-icon type="arrow-down"></a-icon> Down: [[ SizeFormatter.sizeFormat(status.netIO.down) ]]/s
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.downSpeed" }}
|
{{ i18n "pages.index.downSpeed" }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -236,7 +236,7 @@
|
||||||
<a-icon type="cloud-upload"></a-icon>
|
<a-icon type="cloud-upload"></a-icon>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.totalSent" }}
|
{{ i18n "pages.index.totalSent" }}
|
||||||
</template> Out: [[ sizeFormat(status.netTraffic.sent) ]]
|
</template> Out: [[ SizeFormatter.sizeFormat(status.netTraffic.sent) ]]
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -246,7 +246,7 @@
|
||||||
<a-icon type="cloud-download"></a-icon>
|
<a-icon type="cloud-download"></a-icon>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.totalReceive" }}
|
{{ i18n "pages.index.totalReceive" }}
|
||||||
</template> In: [[ sizeFormat(status.netTraffic.recv) ]]
|
</template> In: [[ SizeFormatter.sizeFormat(status.netTraffic.recv) ]]
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -353,7 +353,7 @@
|
||||||
if (this.total === 0) {
|
if (this.total === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return toFixed(this.current / this.total * 100, 2);
|
return NumberFormatter.toFixed(this.current / this.total * 100, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
get color() {
|
get color() {
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
this.logicalPro = data.logicalPro;
|
this.logicalPro = data.logicalPro;
|
||||||
this.cpuSpeedMhz = data.cpuSpeedMhz;
|
this.cpuSpeedMhz = data.cpuSpeedMhz;
|
||||||
this.disk = new CurTotal(data.disk.current, data.disk.total);
|
this.disk = new CurTotal(data.disk.current, data.disk.total);
|
||||||
this.loads = data.loads.map(load => toFixed(load, 2));
|
this.loads = data.loads.map(load => NumberFormatter.toFixed(load, 2));
|
||||||
this.mem = new CurTotal(data.mem.current, data.mem.total);
|
this.mem = new CurTotal(data.mem.current, data.mem.total);
|
||||||
this.netIO = data.netIO;
|
this.netIO = data.netIO;
|
||||||
this.netTraffic = data.netTraffic;
|
this.netTraffic = data.netTraffic;
|
||||||
|
|
|
@ -832,7 +832,7 @@
|
||||||
if (host == this.oldAllSetting.webDomain) host = null;
|
if (host == this.oldAllSetting.webDomain) host = null;
|
||||||
if (port == this.oldAllSetting.webPort) port = null;
|
if (port == this.oldAllSetting.webPort) port = null;
|
||||||
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
||||||
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
const url = URLBuilder.buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||||
window.location.replace(url);
|
window.location.replace(url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -65,15 +65,15 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>WARP+ Data</td>
|
<td>WARP+ Data</td>
|
||||||
<td>[[ sizeFormat(warpModal.warpConfig.account.premium_data) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(warpModal.warpConfig.account.premium_data) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="client-table-odd-row">
|
<tr class="client-table-odd-row">
|
||||||
<td>Quota</td>
|
<td>Quota</td>
|
||||||
<td>[[ sizeFormat(warpModal.warpConfig.account.quota) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(warpModal.warpConfig.account.quota) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="!ObjectUtil.isEmpty(warpModal.warpConfig.account.usage)">
|
<tr v-if="!ObjectUtil.isEmpty(warpModal.warpConfig.account.usage)">
|
||||||
<td>Usage</td>
|
<td>Usage</td>
|
||||||
<td>[[ sizeFormat(warpModal.warpConfig.account.usage) ]]</td>
|
<td>[[ SizeFormatter.sizeFormat(warpModal.warpConfig.account.usage) ]]</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1177,10 +1177,10 @@
|
||||||
findOutboundTraffic(o) {
|
findOutboundTraffic(o) {
|
||||||
for (const otraffic of this.outboundsTraffic) {
|
for (const otraffic of this.outboundsTraffic) {
|
||||||
if (otraffic.tag == o.tag) {
|
if (otraffic.tag == o.tag) {
|
||||||
return sizeFormat(otraffic.up) + ' / ' + sizeFormat(otraffic.down);
|
return SizeFormatter.sizeFormat(otraffic.up) + ' / ' + SizeFormatter.sizeFormat(otraffic.down);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sizeFormat(0) + ' / ' + sizeFormat(0);
|
return SizeFormatter.sizeFormat(0) + ' / ' + SizeFormatter.sizeFormat(0);
|
||||||
},
|
},
|
||||||
findOutboundAddress(o) {
|
findOutboundAddress(o) {
|
||||||
serverObj = null;
|
serverObj = null;
|
||||||
|
@ -1929,7 +1929,7 @@
|
||||||
},
|
},
|
||||||
torrentSettings: {
|
torrentSettings: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return doAllItemsExist(this.settingsData.protocols.bittorrent, this.blockedProtocols);
|
return ArrayUtils.doAllItemsExist(this.settingsData.protocols.bittorrent, this.blockedProtocols);
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set: function (newValue) {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
|
@ -1942,7 +1942,7 @@
|
||||||
familyProtectSettings: {
|
familyProtectSettings: {
|
||||||
get: function () {
|
get: function () {
|
||||||
if (!this.templateSettings || !this.templateSettings.dns || !this.templateSettings.dns.servers) return false;
|
if (!this.templateSettings || !this.templateSettings.dns || !this.templateSettings.dns.servers) return false;
|
||||||
return doAllItemsExist(this.settingsData.familyProtectDNS.servers, this.templateSettings.dns.servers);
|
return ArrayUtils.doAllItemsExist(this.settingsData.familyProtectDNS.servers, this.templateSettings.dns.servers);
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set: function (newValue) {
|
||||||
newTemplateSettings = this.templateSettings;
|
newTemplateSettings = this.templateSettings;
|
||||||
|
|
Loading…
Reference in a new issue