first commit

This commit is contained in:
cieanyau committed 2026-11-06 00:04:38 +08:00
commit db5762abd4
687 files changed
+171307

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
var e = (e, t) => {
let n = e.__vccOpts || e;
for (let [e, r] of t) n[e] = r;
return n;
};
export { e as t };
+29
View File
@@ -0,0 +1,29 @@
function e(e) {
if (
typeof e != `string` ||
!e.startsWith(`/`) ||
e.startsWith(`//`) ||
/[\\\u0000-\u0020\u007f]/.test(e)
)
return `/`;
try {
let t = decodeURIComponent(e.split(/[?#]/, 1)[0] || ``);
if (t.startsWith(`//`) || /[\\\u0000-\u0020\u007f]/.test(t)) return `/`;
} catch {
return `/`;
}
return e;
}
function t(t) {
let n = e(t);
return n === `/`
? {}
: {
redirect: n,
};
}
function n(t, n) {
let r = e(n);
return r === `/` ? t : `${t}?redirect=${encodeURIComponent(r)}`;
}
export { t as n, e as r, n as t };
+856
View File
@@ -0,0 +1,856 @@
import CryptoJS from "crypto-js";
import { defineStore } from "pinia";
import { navigateTo, useRuntimeConfig } from "#app";
import { computed, ref } from "vue";
var ce = [
[/产品类型错误.{0,30}安全组[^\n]*/g, `该商品未接入安全组`],
[/商品未关联.{0,20}模块接口/g, `该商品暂不可用`],
[/未关联.{0,12}模块接口/g, `该商品暂不可用`],
[/尚未接入.{0,12}模块/g, `该商品暂不可用`],
];
var le = [
[/快快云-弹性云|弹性云/g, ``],
[/快快云|快快/g, ``],
[/魔方云|魔方财务|智简魔方|智简/g, ``],
[/美得云|美德云|meidecloud/gi, ``],
[/dwvps[a-z0-9_]*/gi, ``],
[/miloce[a-z0-9_]*/gi, ``],
[/jinghanyun[a-z0-9_]*/gi, ``],
[/kkidc[a-z0-9_]*/gi, ``],
[/kky[a-z0-9_]*/gi, ``],
[/idcsmart[a-z0-9_]*/gi, ``],
[/mf[_-]?cloud[a-z0-9_]*/gi, ``],
[/mf[_-]?dcim[a-z0-9_]*/gi, ``],
[/common[_-]?cloud[a-z0-9_]*/gi, ``],
[/pve[_-]?cloud[a-z0-9_]*/gi, ``],
];
var ue =
/模块接口|自定义配置|模块未关联|模块标识|上游|第三方云|[a-z]{2,}[_-][a-z0-9_]+|\bDCIM\b|whmcs|reserver|https?:\/\//i;
function W(e) {
let t = typeof e == `string` ? e : ``;
if (!t) return ``;
let n = t;
for (let [e, t] of ce) n = n.replace(e, t);
for (let [e, t] of le) n = n.replace(e, t);
return (
(n = n
.replace(/\s{2,}/g, ` `)
.replace(/[,,、]{2,}/g, `,`)
.replace(/^[\s,,、::;;-]+|[\s,,、::;;-]+$/g, ``)
.trim()),
n.length < 2 || ue.test(n) ? `操作失败,请稍后重试或联系客服` : n
);
}
function de(e) {
let t = typeof e == `string` ? e : ``;
return /^\s*上游熔断解除[::]/u.test(t)
? `服务连接已恢复正常`
: /^\s*上游熔断[::]/u.test(t)
? `服务连接暂时异常,请稍后重试`
: t;
}
var fe = 32;
var pe = 200;
var me = 6e4;
var G = new Map();
var he = Symbol(`uninitialized`);
var ge = 0;
function _e() {
(ge++, G.clear());
}
function ve() {
return ge;
}
function ye(e, t, n = ``) {
return JSON.stringify([e, n, t], (e, t) =>
t && typeof t == `object` && !Array.isArray(t)
? Object.fromEntries(
Object.keys(t)
.sort()
.map((e) => [e, t[e]]),
)
: t,
);
}
function be(e) {
return JSON.parse(JSON.stringify(e));
}
function xe(e, t, n = Date.now()) {
he !== e && (_e(), (he = e));
for (let [e, t] of G) t.expires <= n && G.delete(e);
let r = G.get(t);
if (r) return (G.delete(t), G.set(t, r), be(r.data));
}
function Se(e, t, n, r, i = Date.now()) {
if (e === he && r === ge) {
if (!Array.isArray(n.list) || n.list.length > pe) {
G.delete(t);
return;
}
try {
let e = be(n);
(G.delete(t),
G.size >= fe && G.delete(G.keys().next().value),
G.set(t, {
data: e,
expires: i + me,
}));
} catch {
G.delete(t);
}
}
}
var Ce = 2147483647;
function K(e, t) {
let n =
typeof e == `number`
? e
: typeof e == `string` && /^\d+$/.test(e)
? Number(e)
: NaN;
if (!Number.isSafeInteger(n) || n < t || n > Ce)
throw Error(`购买信息无效,请重新确认后重试`);
return n;
}
function we(e) {
if (!e || typeof e != `object` || Array.isArray(e))
throw Error(`购买信息无效,请重新确认后重试`);
return e;
}
function Te(e) {
let t = we(e);
return {
product_id: K(t.product_id, 1),
qty: K(t.qty, 1),
};
}
function Ee(e, t, n) {
if (e === `POST` && t === `/product/settle`)
return {
mode: `single`,
...Te(n),
};
if (e === `POST` && t === `/cart`) {
let e = we(n);
if (e.products !== void 0) {
if (
!Array.isArray(e.products) ||
!e.products.length ||
e.products.length > 1e3
)
throw Error(`购买信息无效,请重新确认后重试`);
return {
mode: `cart_add`,
products: e.products.map(Te),
};
}
return {
mode: `cart_add`,
...Te(e),
};
}
if (e === `POST` && t === `/cart/settle`) {
let e = we(n);
if (!Array.isArray(e.positions) || !e.positions.length)
throw Error(`请选择要结算的商品`);
return {
mode: `cart_settle`,
positions: [...new Set(e.positions.map((e) => K(e, 0)))],
};
}
let r = e === `PUT` ? /^\/cart\/(\d+)(\/qty)?$/.exec(t) : null;
if (r) {
let e = we(n);
return {
mode: `cart_update`,
position: K(r[1], 0),
qty: K(e.qty, 1),
...(r[2]
? {}
: {
product_id: K(e.product_id, 1),
}),
};
}
return null;
}
function De(e) {
if (!e || typeof e != `object` || Array.isArray(e)) return !1;
let t = e;
return (
typeof t.allowed == `boolean` &&
typeof t.message == `string` &&
(t.allowed || !!t.message.trim())
);
}
class ApiError extends Error {
status;
data;
constructor(status, message, data) {
super(message);
this.status = status;
this.data = data;
this.name = "ApiError";
}
}
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
const FILE_TRANSFER_TIMEOUT_MS = 120_000;
function requestTimeoutError() {
return new ApiError(408, "请求超时,请稍后重试");
}
async function withRequestDeadline(
operation,
timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS,
controller = new AbortController(),
) {
const duration =
Number.isFinite(timeoutMs) && timeoutMs > 0 && timeoutMs <= 2_147_483_647
? timeoutMs
: DEFAULT_REQUEST_TIMEOUT_MS;
let timer;
const deadline = new Promise((_, reject) => {
timer = setTimeout(() => {
controller.abort();
reject(requestTimeoutError());
}, duration);
});
try {
// The deadline also covers response-body decoding and any purchase preflight.
return await Promise.race([
Promise.resolve().then(() => operation(controller.signal)),
deadline,
]);
} finally {
clearTimeout(timer);
}
}
function assertRequestActive(signal) {
if (signal.aborted) throw requestTimeoutError();
}
function normalizeRequestError(error) {
return error instanceof ApiError
? error
: new ApiError(0, "网络异常,请检查网络后重试");
}
function useApi() {
const config = useRuntimeConfig();
const auth = useAuth();
function clearUnauthorizedSession(requestToken) {
if (
!requestToken ||
localStorage.getItem("jwt") !== requestToken ||
auth.token !== requestToken
)
return;
auth.clear();
if (window.location.pathname === "/login") return;
const redirect = window.location.pathname + window.location.search;
try {
void Promise.resolve(
navigateTo({
path: "/login",
query: redirect === "/" ? undefined : { redirect },
}),
).catch(() => {});
} catch {}
}
function responseObject(value) {
return value && typeof value === "object" && !Array.isArray(value)
? value
: {};
}
function responseError(response, payload, requestToken, fallbackMessage) {
const envelope = responseObject(payload);
const status =
response.status === 401
? 401
: typeof envelope.status === "number" && envelope.status !== 200
? envelope.status
: response.status;
if (status === 401) clearUnauthorizedSession(requestToken);
return new ApiError(
status,
W(envelope.msg || envelope.message) || fallbackMessage,
envelope.data,
);
}
async function decodeResponse(
response,
requestToken,
fallbackMessage,
signal,
allowStatuslessDataArray = false,
) {
const payload = await response.json().catch(() => null);
assertRequestActive(signal);
const envelope = responseObject(payload);
if (response.ok && envelope.status === 200) return payload;
if (
response.ok &&
allowStatuslessDataArray &&
!("status" in envelope) &&
Array.isArray(envelope.data)
) {
return { status: 200, msg: "", data: envelope.data };
}
throw responseError(response, payload, requestToken, fallbackMessage);
}
function apiUrl(path, query, keepEmpty = false) {
let url = `${String(config.public.apiBase ?? "")}/console/v1${path}`;
const search = new URLSearchParams();
for (const [key, value] of Object.entries(query ?? {})) {
if (value == null || (value === "" && !keepEmpty)) continue;
if (Array.isArray(value)) {
for (const item of value) {
if (item != null && item !== "")
search.append(`${key}[]`, String(item));
}
} else {
search.append(key, String(value));
}
}
if (search.size) url += `?${search}`;
return url;
}
async function request(method, path, options = {}) {
// Capture identity before the first await, including when logout clears it immediately.
const requestToken = auth.token;
const headers = { Accept: "application/json" };
if (requestToken) headers.Authorization = `Bearer ${requestToken}`;
if (options.body !== undefined)
headers["Content-Type"] = "application/json";
try {
const serializedBody =
options.body === undefined ? undefined : JSON.stringify(options.body);
return await withRequestDeadline(async (signal) => {
if (requestToken) {
let purchase;
try {
purchase = Ee(method, path, options.body);
} catch (error) {
throw new ApiError(
422,
error instanceof Error
? error.message
: "购买信息无效,请重新确认后重试",
);
}
if (purchase) {
const authToken = auth.token;
const permission = await request("POST", "/purchase_limit/check", {
body: purchase,
timeoutMs: options.timeoutMs ?? 15_000,
});
assertRequestActive(signal);
if (
localStorage.getItem("jwt") !== requestToken ||
auth.token !== authToken
) {
throw new ApiError(409, "登录状态已变化,请重新确认后重试");
}
if (JSON.stringify(options.body) !== serializedBody) {
throw new ApiError(409, "购买信息已变化,请重新确认后重试");
}
if (!De(permission))
throw new ApiError(502, "限购验证暂不可用,请稍后重试");
if (!permission.allowed)
throw new ApiError(422, permission.message);
}
}
assertRequestActive(signal);
const response = await fetch(
apiUrl(path, options.query, options.keepEmpty),
{
method,
headers,
body: serializedBody,
signal,
},
);
assertRequestActive(signal);
const envelope = await decodeResponse(
response,
requestToken,
response.ok
? "响应格式异常,请稍后重试"
: `请求失败(HTTP ${response.status})`,
signal,
options.allowStatuslessDataArray,
);
assertRequestActive(signal);
if (
method !== "GET" &&
path !== "/purchase_limit/check" &&
!/^\/product\/\d+\/config_option$/.test(path)
) {
_e();
}
return options.raw ? envelope : envelope.data;
}, options.timeoutMs);
} catch (error) {
throw normalizeRequestError(error);
}
}
async function upload(file) {
const body = new FormData();
body.append("file", file);
const headers = { Accept: "application/json" };
const requestToken = auth.token;
if (requestToken) headers.Authorization = `Bearer ${requestToken}`;
try {
return await withRequestDeadline(async (signal) => {
const response = await fetch(apiUrl("/upload"), {
method: "POST",
headers,
body,
signal,
});
assertRequestActive(signal);
const envelope = await decodeResponse(
response,
requestToken,
"上传失败",
signal,
);
assertRequestActive(signal);
return envelope.data;
}, FILE_TRANSFER_TIMEOUT_MS);
} catch (error) {
throw normalizeRequestError(error);
}
}
async function download(path, data, filename = "export.xlsx", options = {}) {
const method = options.method ?? "GET";
const headers = { Accept: "*/*" };
const requestToken = auth.token;
if (requestToken) headers.Authorization = `Bearer ${requestToken}`;
if (method === "POST") headers["Content-Type"] = "application/json";
try {
await withRequestDeadline(async (signal) => {
const response = await fetch(
apiUrl(path, method === "GET" ? data : undefined),
{
method,
headers,
...(method === "POST" ? { body: JSON.stringify(data ?? {}) } : {}),
signal,
},
);
assertRequestActive(signal);
const isJson = /\bapplication\/(?:[\w.-]+\+)?json\b/i.test(
response.headers.get("content-type") || "",
);
if (!response.ok || isJson) {
const payload = await response
.clone()
.json()
.catch(() => null);
assertRequestActive(signal);
const envelope = responseObject(payload);
if (
!response.ok ||
(typeof envelope.status === "number" && envelope.status !== 200)
) {
throw responseError(
response,
payload,
requestToken,
`下载失败(HTTP ${response.status})`,
);
}
}
const disposition = response.headers.get("content-disposition") || "";
const match = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i.exec(disposition);
if (match?.[1]) {
try {
filename = decodeURIComponent(match[1]);
} catch {
filename = match[1];
}
}
const blob = await response.blob();
assertRequestActive(signal);
const objectUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
try {
link.href = objectUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
} finally {
link.remove();
URL.revokeObjectURL(objectUrl);
}
}, options.timeoutMs ?? FILE_TRANSFER_TIMEOUT_MS);
} catch (error) {
throw normalizeRequestError(error);
}
}
return {
identity: () => auth.token,
request,
upload,
download,
get: (path, query, keepEmpty = false, options = {}) =>
request("GET", path, {
...options,
query,
keepEmpty,
}),
getRaw: (path, query, options = {}) =>
request("GET", path, {
...options,
query,
raw: true,
}),
post: (path, body, raw = false, options = {}) =>
request("POST", path, {
...options,
body,
raw,
}),
put: (path, body, query) => request("PUT", path, { body, query }),
del: (path, query, body) => request("DELETE", path, { query, body }),
};
}
var ot = CryptoJS.enc.Utf8.parse(`idcsmart.finance`);
var st = CryptoJS.enc.Utf8.parse(`9311019310287172`);
function ct(e) {
return CryptoJS.AES.encrypt(e, ot, {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: st,
}).toString();
}
function lt(e, t = `登录失败,请稍后重试`) {
let n = e && typeof e == `object` ? e : {},
r = typeof n.message == `string` ? n.message.trim() : ``,
i = n.data && typeof n.data == `object` ? n.data : {};
return i.need_security_verify || i.ip_exception_verify
? `本次登录需要额外的安全验证,请联系客服协助完成验证。`
: n.status === 429
? `登录尝试过于频繁,请稍后再试`
: n.status === 408 || /超时|timeout/i.test(r)
? `登录请求超时,请检查网络后重试`
: n.status === 0 ||
/网络异常|Failed to fetch|NetworkError|Load failed/i.test(r)
? `网络连接失败,请检查网络后重试`
: (n.status ?? 0) >= 500 ||
/页面错误|响应格式异常|Internal Server Error|Bad Gateway|Service Unavailable/i.test(
r,
)
? `登录服务暂时异常,请稍后重试;若持续失败,请联系客服。`
: !r ||
/<[^>]+>|SQLSTATE|\b(?:TypeError|ReferenceError|Exception)\b/.test(
r,
)
? t
: r;
}
function ut(e) {
return (
typeof e == `string` && e.length > 0 && e.length <= 8192 && !/\s/.test(e)
);
}
function dt(e) {
if (!e || typeof e != `object`) return null;
let t = e,
n = [t, t.data, t.error, t.response];
for (let e of n) {
if (!e || typeof e != `object`) continue;
let t = e,
n = t.data && typeof t.data == `object` ? t.data : t;
if (
n.need_security_verify === !0 ||
n.need_security_verify === 1 ||
n.need_security_verify === `1` ||
(Array.isArray(n.available_methods) && n.available_methods.length > 0)
)
return n;
}
return null;
}
function ft(e) {
let t = dt(e);
if (t)
throw Object.assign(Error(`安全验证尚未完成,请重试`), {
data: t,
});
}
var pt = {
operate_password: `操作密码`,
email_code: `邮箱验证码`,
phone_code: `手机验证码`,
certification: `实名认证`,
};
function mt(e) {
return (
Array.isArray(e.available_methods) ? e.available_methods : []
).flatMap((t) => {
let n =
typeof t == `string`
? {
value: t,
}
: t && typeof t == `object`
? t
: {},
r = String(n.value ?? ``);
return pt[r]
? [
{
value: r,
label: pt[r],
tip: String(n.tip ?? ``),
account: String(n.account ?? ``),
phone_code: String(n.phone_code ?? ``),
security_verify_token: String(
n.security_verify_token ?? e.security_verify_token ?? ``,
),
},
]
: [];
});
}
const useAuth = defineStore("auth", () => {
const token = ref(localStorage.getItem("jwt"));
const overview = ref(null);
const loading = ref(false);
const legacyLoginPending = ref(false);
const isLoggedIn = computed(() => !!token.value);
let overviewPromise = null;
let sessionVersion = 0;
let legacySession = null;
function loginWithJwt(jwt) {
if (!ut(jwt))
throw Error("登录响应无效,请重新登录;若持续失败,请联系客服。");
resetSessionState();
token.value = jwt;
localStorage.setItem("jwt", jwt);
}
function prepareLegacyLogin(jwt = localStorage.getItem("jwt")) {
clear();
legacySession = {
jwt: ut(jwt) ? jwt : null,
version: sessionVersion,
controller: null,
promise: null,
};
legacyLoginPending.value = true;
}
function cancelLegacyLogin() {
legacySession?.controller?.abort();
legacySession = null;
legacyLoginPending.value = false;
}
function verifyLegacyLogin() {
const session = legacySession;
if (!session?.jwt) {
return Promise.reject(
Error("缺少有效登录凭证,请返回原平台重新进入,或使用账号登录。"),
);
}
if (session.promise) return session.promise;
const apiBase = String(useRuntimeConfig().public.apiBase ?? "");
const controller = new AbortController();
session.controller = controller;
const isCurrentSession = () =>
legacySession === session && sessionVersion === session.version;
const promise = withRequestDeadline(
async (signal) => {
let response;
try {
response = await fetch(`${apiBase}/console/v1/index`, {
headers: {
Accept: "application/json",
Authorization: `Bearer ${session.jwt}`,
},
credentials: "omit",
cache: "no-store",
referrerPolicy: "no-referrer",
signal,
});
} catch {
throw Error("网络连接失败或验证超时,请检查网络后重试。");
}
const envelope = await response.json().catch(() => null);
assertRequestActive(signal);
if (!isCurrentSession()) throw Error("登录状态已变化,请重新进入。");
if (response.status === 401 || envelope?.status === 401) {
throw Error("登录凭证已失效,请返回原平台重新进入,或使用账号登录。");
}
const account = envelope?.data?.account;
if (
!response.ok ||
envelope?.status !== 200 ||
!account ||
typeof account !== "object" ||
!Number.isSafeInteger(account.id) ||
account.id <= 0
)
throw Error("暂时无法验证登录身份,请稍后重试。");
loginWithJwt(session.jwt);
overview.value = account;
},
15_000,
controller,
)
.catch((error) => {
if (error instanceof ApiError && error.status === 408) {
throw Error("网络连接失败或验证超时,请检查网络后重试。");
}
throw error;
})
.finally(() => {
if (isCurrentSession()) {
session.controller = null;
session.promise = null;
}
});
session.promise = promise;
return promise;
}
async function login(
account,
password,
captcha = "",
captchaToken = "",
type = "password",
code = "",
phoneCode = "86",
verification,
) {
if (type === "code" && account.includes("@"))
throw Error("验证码登录仅支持手机号");
const api = useApi();
const version = sessionVersion;
loading.value = true;
try {
const result = await api.post(
"/login",
{
type,
account,
...(account.includes("@") ? {} : { phone_code: phoneCode }),
code,
password: type === "password" ? ct(password) : "",
remember_password: "0",
captcha,
token: captchaToken,
...(verification || {}),
},
false,
{ timeoutMs: 15_000 },
);
if (version !== sessionVersion) throw Error("登录状态已变化,请重试");
ft(result);
if (!ut(result?.jwt))
throw Error("登录响应无效,请重新登录;若持续失败,请联系客服。");
loginWithJwt(result.jwt);
} finally {
loading.value = false;
}
}
function loadOverview() {
if (!overviewPromise) {
const version = sessionVersion;
const promise = useApi()
.get("/index", undefined, false, { timeoutMs: 10_000 })
.then((result) => {
if (version !== sessionVersion) throw Error("登录状态已变化,请重试");
overview.value = result.account;
return result.account;
})
.finally(() => {
if (overviewPromise === promise) overviewPromise = null;
});
overviewPromise = promise;
}
return overviewPromise;
}
async function fetchOverview() {
return overview.value ?? loadOverview();
}
async function refreshOverview() {
return loadOverview();
}
function logout() {
// request() captures the original Bearer synchronously; remote revocation never owns local logout.
const revocation = useApi().post("/logout");
clear();
void revocation.catch(() => {});
}
function resetSessionState() {
_e();
cancelLegacyLogin();
sessionVersion += 1;
overview.value = null;
overviewPromise = null;
}
function clear() {
resetSessionState();
token.value = null;
localStorage.removeItem("jwt");
}
return {
token,
overview,
loading,
isLoggedIn,
login,
loginWithJwt,
fetchOverview,
refreshOverview,
logout,
clear,
legacyLoginPending,
prepareLegacyLogin,
verifyLegacyLogin,
cancelLegacyLogin,
};
});
export {
lt as loginErrorMessage,
ApiError,
ye as apiCacheKey,
ve as apiCacheVersion,
W as sanitizeMessage,
de as operationMessage,
mt as securityMethods,
useApi,
Se as writeApiCache,
ft as assertSecurityComplete,
ut as isValidJwt,
xe as readApiCache,
dt as securityChallenge,
useAuth,
_e as clearApiCache,
};
+380
View File
@@ -0,0 +1,380 @@
function e(e) {
let t = (e) =>
e.some(
(e) =>
e.to === `/finance` ||
e.to === `/finance?tab=bills` ||
(e.children && t(e.children)),
),
n = t(e);
function r(e) {
return e.flatMap((e) => {
if (e.children) {
let t = r(e.children);
return t.length
? [
{
...e,
children: t,
},
]
: [];
}
return e.to?.split(`?`)[0] === `/bills`
? n
? []
: ((n = !0),
[
{
...e,
label: `财务`,
to: `/finance`,
},
])
: [e];
});
}
return r(e);
}
function t(e, t, n = []) {
let r =
t.path === `/products/cvm`
? `/products/cloud-server`
: t.path === `/bills` || t.path.startsWith(`/bills/`)
? t.path.replace(`/bills`, `/finance`)
: t.path;
function i(e) {
let [n = ``, i = ``] = e.split(`?`);
if (r !== n && !r.startsWith(`${n}/`)) return -1;
let a = [...new URLSearchParams(i)];
return a.every(([e, n]) => String(t.query[e] ?? ``) === n)
? n.length * 100 + a.length
: -1;
}
let a = i(e);
return a >= 0 && !n.some((e) => i(e.to) > a);
}
var n = new Set(
`/./products./products/cloud-server./products/dedicated-server./cart./cloud-servers./dedicated-servers./security/groups./security/ssh-keys./security/domains./transfer./finance./orders./bills./invoices./invoices/settings./invoices/request./recommend./vouchers./account./account/api-keys./account/connections./account/realname./messages./logbook./tickets./tickets/create./help./notices./news./resources`.split(
`.`,
),
),
r = {
"index.htm": `/`,
"home.htm": `/`,
"cart/goodsList.htm": `/products`,
"cart/cart.htm": `/cart`,
"finance.htm": `/finance`,
"order.htm": `/orders`,
"account.htm": `/account`,
"security.htm": `/account/api-keys`,
"ticket.htm": `/tickets`,
"help.htm": `/help`,
"news.htm": `/news`,
"announcement.htm": `/notices`,
"api.htm": `/account/api-keys`,
"log.htm": `/logbook`,
"invoice.htm": `/invoices`,
"recommend.htm": `/recommend`,
"voucher.htm": `/vouchers`,
"host_transfer.htm": `/transfer`,
"security_group.htm": `/security/groups`,
"ssh_key.htm": `/security/ssh-keys`,
"message.htm": `/messages`,
"msgDetail.htm": `/messages`,
"group_rules.htm": `/security/groups`,
"withdrawal.htm": `/finance?tab=withdraw`,
"orderDetail.htm": `/orders/order`,
"addTicket.htm": `/tickets/create`,
"ticketDetails.htm": `/tickets/ticket`,
"issuedInvoice.htm": `/invoices/request`,
"security_ssh.htm": `/security/ssh-keys`,
"security_log.htm": `/logbook?type=api`,
},
i = {
45: `/transfer`,
},
a = new Set(
Object.values(r).filter(
(e) => ![`/`, `/security/groups`, `/vouchers`, `/logbook`].includes(e),
),
);
function o(e) {
let t = e.to?.split(`?`)[0];
return (
(t &&
{
"/": `lucide:house`,
"/products": `lucide:shopping-cart`,
"/cart": `lucide:shopping-basket`,
"/cloud-servers": `lucide:server`,
"/dedicated-servers": `lucide:server`,
"/bills": `lucide:receipt-text`,
"/finance": `lucide:wallet`,
"/orders": `lucide:clipboard-list`,
"/invoices": `lucide:receipt`,
"/recommend": `lucide:gift`,
"/vouchers": `lucide:ticket`,
"/account": `lucide:user`,
"/account/api-keys": `lucide:key-round`,
"/account/connections": `lucide:link`,
"/messages": `lucide:mail`,
"/logbook": `lucide:scroll-text`,
"/tickets": `lucide:headphones`,
"/help": `lucide:circle-help`,
"/resources": `lucide:book-open`,
"/notices": `lucide:megaphone`,
"/news": `lucide:newspaper`,
"/transfer": `lucide:truck`,
}[t]) ||
(e.href
? `lucide:external-link`
: e.children?.length
? `lucide:folder`
: `lucide:circle-help`)
);
}
function s(e, t) {
if (![`/cloud-servers`, `/dedicated-servers`].includes(t.path)) return;
let n = new Set(),
r;
function i(e) {
for (let a of e) {
a.children && i(a.children);
let [e, o = ``] = a.to?.split(`?`) ?? [],
s = new URLSearchParams(o).get(`m`);
(s &&
s === String(t.query.m ?? ``) &&
e &&
[`/cloud-servers`, `/dedicated-servers`].includes(e) &&
e !== t.path &&
(r = {
path: e,
query: {
...t.query,
m: s,
},
}),
e === t.path && s && /^[1-9]\d*$/.test(s) && n.add(s));
}
}
if ((i(e), r)) return r;
if (!(n.size !== 1 || n.has(String(t.query.m ?? ``))))
return {
path: t.path,
query: {
...t.query,
m: [...n][0],
},
};
}
function c(e, t, n) {
let r = e.map((e) => ({
...e,
items: [...(t.find((t) => t.label === e.label)?.items ?? [])],
})),
i = (e) => e.children?.flatMap(i) ?? (e.to ? [e.to.split(`?`)[0]] : []);
for (let t of n) {
let n = i(t),
a = e.findIndex((e) =>
e.items.some((e) =>
[e.to, ...(e.children?.map((e) => e.to) ?? [])].some(
(e) => e && n.includes(e),
),
),
);
(a < 0 &&
n.some((e) => e.startsWith(`/account/`)) &&
(a = e.findIndex((e) => e.items.some((e) => e.to === `/account`))),
a < 0 &&
n.includes(`/resources`) &&
(a = e.findIndex((e) => e.items.some((e) => e.to === `/help`))),
a < 0 && (a = r.length - 1),
!(a < 0) &&
r[a].items.push({
label: t.label,
icon: o(t),
backend: t,
}));
}
return r.filter((e) => e.items.length);
}
function l(e, n) {
let r = [];
function i(e, a) {
let o = e
.filter((e) => e.to)
.map((e) => ({
to: e.to,
}));
for (let s of e) {
let e = [...a, s.label];
if (s.to && t(s.to, n, o)) {
let [t = ``, n = ``] = s.to.split(`?`);
r.push({
labels: e,
path: t,
score: t.length * 100 + [...new URLSearchParams(n)].length,
});
}
s.children && i(s.children, e);
}
}
return (i(e, []), r.sort((e, t) => t.score - e.score)[0]?.labels ?? []);
}
function u(e, t) {
let n = new Set(),
r = (e) =>
e.forEach((e) => {
(e.to && n.add(e.to.split(`?`)[0]), e.children && r(e.children));
});
r(t);
let i = (e) => !a.has(e) && !n.has(e);
return e
.map((e) => ({
...e,
items: e.items.flatMap((e) => {
if (e.children) {
let t = e.children.filter((e) => i(e.to));
return t.length
? [
{
...e,
children: t,
},
]
: [];
}
return !e.to || i(e.to) ? [e] : [];
}),
}))
.filter((e) => e.items.length);
}
function d(e) {
if (
typeof e != `string` ||
!/^https?:\/\//i.test(e) ||
/[\u0000-\u0020\\]/.test(e)
)
return ``;
try {
let t = new URL(e);
return t.username || t.password ? `` : t.href;
} catch {
return ``;
}
}
function f(e, t = ``, a = 0) {
if (!Array.isArray(e) || a > 2) return [];
let o = e.slice(0, 100).flatMap((e, o) => {
if (
!e ||
typeof e != `object` ||
typeof e.name != `string` ||
!e.name.trim()
)
return [];
let s = {
key: `${t}${e.id ?? o}`,
label: e.name.slice(0, 100),
confirm: Number(e.second_reminder) === 1,
},
c = f(e.child, `${s.key}-`, a + 1);
if (c.length) return ((s.children = c), [s]);
if ([`module`, `res_module`].includes(e.menu_type)) {
let t = {
云服务器: `/cloud-servers`,
物理服务器: `/dedicated-servers`,
}[e.name.trim()],
n = Number(e.id);
return (
t && Number.isSafeInteger(n) && n > 0
? (s.to = `${t}?m=${n}`)
: (s.disabledReason = `此菜单暂未适配当前控制台`),
[s]
);
}
if (e.menu_type === `embedded`)
return ((s.disabledReason = `此菜单暂未适配当前控制台`), [s]);
let l = typeof e.url == `string` ? e.url.trim() : ``,
u = l.split(`?`)[0] || ``,
p = u.replace(/^\//, ``).replace(/^clientarea\//, ``),
m = /^plugin\/([1-9]\d*)\/([a-zA-Z_]+\.htm)$/.exec(p),
h = r[p] || (m ? (m[2] === `index.htm` ? i[m[1]] : r[m[2]]) : void 0),
g = /^plugin\/([1-9]\d*)\/source\.htm$/.exec(p);
if (g) s.to = `/resources?plugin=${g[1]}`;
else if (h || n.has(u)) {
let [e, t = ``] = (h || u).split(`?`),
n = new URLSearchParams(l.split(`?`)[1] ?? ``),
r = new URLSearchParams(t);
for (let t of {
"/bills": [`status`],
"/orders": [`status`],
"/finance": [`tab`, `status`],
"/logbook": [`type`],
"/security/groups": [`id`],
"/orders/order": [`id`],
"/tickets/ticket": [`id`],
"/messages": [`id`],
}[e] ?? []) {
let e = n.getAll(t),
i = e[0] ?? ``,
a =
t === `id`
? /^[1-9]\d*$/.test(i)
: t === `tab`
? [
`bills`,
`transaction`,
`credit`,
`withdraw`,
`freeze`,
].includes(i)
: t === `status`
? [
`all`,
`Unpaid`,
`Paid`,
`Refunded`,
`WaitUpload`,
`WaitReview`,
`ReviewFail`,
].includes(i)
: [`api`, `system`].includes(i);
!r.has(t) && e.length === 1 && a && r.set(t, i);
}
s.to = e + (r.size ? `?${r}` : ``);
} else
e.menu_type === `custom` && d(l)
? (s.href = d(l))
: (s.disabledReason = `此功能暂未开放`);
return [s];
}),
s = o.filter((e) => e.to === `/account`);
return s.length < 2
? o
: o.flatMap((e) =>
e.to === `/account`
? e === s[0]
? [
{
...e,
label: `账户`,
confirm: s.some((e) => e.confirm),
},
]
: []
: [e],
);
}
export {
c as a,
t as c,
f as i,
e as l,
o as n,
d as o,
s as r,
u as s,
l as t,
};
+7
View File
@@ -0,0 +1,7 @@
function e(e) {
return e.replace(
/(?<![A-Za-z0-9_.+−-])(\d+(?:\.\d+)?)\s*Mbps\s*突发峰值带宽(?![A-Za-z0-9_])/gi,
`峰值$1Mbps`,
);
}
export { e as t };
+104
View File
@@ -0,0 +1,104 @@
function e(e, t = {}) {
let n = {
...e,
...t,
};
return {
product_id: Number(n.product_id),
config_options: n.config_options ?? {},
qty: Math.max(1, Number(n.qty ?? 1)),
customfield: n.customfield ?? {},
self_defined_field: n.self_defined_field ?? {},
};
}
function t(e) {
return JSON.parse(JSON.stringify(e));
}
function n(n) {
return n.map((n) => t(e(n)));
}
function r(e) {
return Array.isArray(e)
? e.map(r)
: e && typeof e == `object`
? Object.fromEntries(
Object.entries(e)
.filter(([, e]) => e !== void 0)
.sort(([e], [t]) => e.localeCompare(t))
.map(([e, t]) => [e, r(t)]),
)
: e;
}
function i(t) {
return JSON.stringify(r(e(t)));
}
function a(e, t) {
if (!e) return;
let n = e.item.self_defined_field ?? {};
if (Object.keys(n).some((e) => !t.includes(e)))
throw Error(`商品自定义字段已调整,请返回购物车删除该项后重新配置`);
}
var o = null;
async function s(e) {
let t = new TextEncoder().encode(i(e));
return Array.from(
new Uint8Array(await crypto.subtle.digest(`SHA-256`, t)),
(e) => e.toString(16).padStart(2, `0`),
).join(``);
}
async function c(e, t) {
let n = [...t];
o = {
fingerprints: await Promise.all(e.map(s)),
indices: n,
};
}
async function l(e) {
let t = o;
if (!t) return null;
o = null;
let n = await Promise.all(e.map(s)),
r = new Set();
return t.indices.flatMap((e) => {
let i = t.fingerprints
.slice(0, e)
.filter((n) => n === t.fingerprints[e]).length,
a = n.flatMap((n, r) => (n === t.fingerprints[e] ? [r] : []))[i];
return a === void 0 || r.has(a) ? [] : (r.add(a), [a]);
});
}
function u(n, r) {
let a = r ? t(r.item) : null,
c = !1;
return async (l, u) => {
if (!r || !a) throw Error(`购物车编辑上下文缺失`);
if (c) throw Error(`正在保存,请勿重复操作`);
c = !0;
let d = t(e(a, l));
try {
let c = (await n.get(`/cart`)).list?.[r.position];
if (!c || i(c) !== i(a))
throw Error(`购物车商品已变化,请返回购物车刷新后重新编辑`);
if (!u()) throw Error(`配置已改变,请重新确认报价后保存`);
let l = await n.put(`/cart/${r.position}`, {
...d,
expected_item: e(a),
}),
f = a;
a = t({
...a,
...d,
});
let p = o;
return (
p &&
p.fingerprints[r.position] === (await s(f)) &&
(p.fingerprints[r.position] = await s(a)),
l
);
} finally {
c = !1;
}
};
}
export { l as a, c as i, t as n, a as o, u as r, n as t };
+162
View File
@@ -0,0 +1,162 @@
var e = (e) => e === `mf_cloud` || e === `remf_cloud`;
function t(e) {
let t = () => {
throw Error(`防御配置无效,请重试`);
};
if (!e || typeof e != `object` || Array.isArray(e)) return t();
let n = e;
if (!Object.keys(n).length)
return {
options: [],
current: ``,
};
let r = n.defence;
if (
!r ||
typeof r != `object` ||
(!Array.isArray(r) && Object.keys(r).some((e) => !/^(0|[1-9]\d*)$/.test(e)))
)
return t();
let i = Object.values(r).map((e) => {
if (!e || typeof e != `object`) return t();
let { value: n, desc: r } = e;
return ![`string`, `number`].includes(typeof n) ||
String(n).trim() === `` ||
!Number.isFinite(Number(n)) ||
Number(n) < 0 ||
![`string`, `number`].includes(typeof r) ||
String(r).trim() === ``
? t()
: {
value: String(n),
desc: String(r),
};
}),
a = n.current_defence == null ? `` : String(n.current_defence);
return a !== `` && (!Number.isFinite(Number(a)) || Number(a) < 0 || !a.trim())
? t()
: {
options: i,
current: a,
};
}
function n(e) {
if (
e == null ||
String(e).trim() === `` ||
!Number.isFinite(Number(e)) ||
Number(e) < 0
)
throw Error(`未获得有效报价,请重试`);
return String(e);
}
function r(e) {
if (
(typeof e != `string` && typeof e != `number`) ||
!/^[1-9]\d*$/.test(String(e))
)
throw Error(`订单编号未返回,请先在订单管理中检查,避免重复下单`);
return e;
}
function i(e, t) {
if (!Number.isInteger(t.int_port) || t.int_port < 1 || t.int_port > 65535)
throw Error(`内部端口应为 1–65535 的整数`);
if (e === `web`) {
let e = t.domain.trim().toLowerCase();
if (
!/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(
e,
)
)
throw Error(`请输入有效域名,不含协议和路径`);
return {
domain: e,
int_port: t.int_port,
};
}
if (!t.name.trim()) throw Error(`请输入转发名称`);
if (![1, 2, 3].includes(t.protocol)) throw Error(`请选择有效协议`);
if (
t.ext_port !== null &&
(!Number.isInteger(t.ext_port) ||
t.ext_port < 0 ||
t.ext_port > 65535 ||
[22, 80, 443].includes(t.ext_port))
)
throw Error(`外部端口应为 0–65535,且不能使用 22、80、443`);
return {
name: t.name.trim(),
int_port: t.int_port,
protocol: t.protocol,
...(t.ext_port === null
? {}
: {
ext_port: t.ext_port,
}),
};
}
function a(e, t, n = []) {
if (!e.trim()) throw Error(`请输入 VPC 名称`);
if (!t.trim())
return {
name: e.trim(),
};
let r = t.trim().match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/);
if (!r) throw Error(`请输入有效 IPv4 CIDR 网段`);
let i = r.slice(1, 5).map(Number),
a = Number(r[5]);
if (
i.some((e) => e < 0 || e > 255) ||
a < 1 ||
a > 32 ||
(n.length && !n.includes(a))
)
throw Error(`网段地址或掩码不在允许范围内`);
return {
name: e.trim(),
ips: t.trim(),
};
}
function o(e, t = {}) {
return e.flatMap((e, n) => {
let r = e.type === `step` || e.type === `total`,
i =
Number(t.disk_range_limit_switch) === 1 &&
Number(t.disk_range_limit) > 0
? Number(t.disk_range_limit)
: 1,
a = r
? Math.ceil(Number(e.min_value ?? e.value) / i) * i
: Number(e.value),
o = r
? Math.floor(Number(e.max_value ?? e.value) / i) * i
: Number(e.value),
s = String(e.other_config?.disk_type ?? ``);
return !Number.isInteger(a) ||
!Number.isInteger(o) ||
a < 1 ||
o < a ||
!Number.isFinite(i) ||
i <= 0
? []
: [
{
id: n,
type: s,
min: a,
max: o,
step: i,
label: `${s || `默认类型`} · ${a === o ? a : `${a}–${o}`} GB`,
},
];
});
}
function s(e, t) {
return (
Number.isInteger(e) &&
e >= t.min &&
e <= t.max &&
Math.abs((e - t.min) / t.step - Math.round((e - t.min) / t.step)) < 1e-7
);
}
export { i as a, a as c, e as i, t as n, s as o, o as r, r as s, n as t };
+261
View File
@@ -0,0 +1,261 @@
var e = (e) => (e && typeof e == `object` && !Array.isArray(e) ? e : {}),
t = (t) => (Array.isArray(t) ? t.map(e) : []),
n = (e) => JSON.parse(JSON.stringify(e)),
r = (e) => [`quantity`, `quantity_range`].includes(String(e.option_type)),
i = (e) => String(e.id ?? e.configoption_id ?? ``),
a = (e) =>
(Array.isArray(e) ? e : [e])
.filter((e) => e != null && e !== ``)
.map(Number),
o = (e = `商品高级规则数据不完整`) => {
throw Error(e);
};
function s(n) {
return n == null
? []
: Array.isArray(n)
? n.flatMap((n) => {
let r = e(n);
if (![!0, 1, `1`].includes(r.enabled)) return [];
[`all`, `any`].includes(String(r.combine_mode)) || o();
let i = t(r.terms).map(
(e) => (
(![`condition`, `result`].includes(String(e.role)) ||
![`in`, `not_in`].includes(String(e.operator)) ||
!Number.isSafeInteger(Number(e.configoption_id)) ||
Number(e.configoption_id) <= 0 ||
!t(e.values).length) &&
o(),
{
id: String(e.configoption_id),
role: e.role,
operator: e.operator,
values: t(e.values),
}
),
);
return (
(!i.some((e) => e.role === `condition`) ||
!i.some((e) => e.role === `result`)) &&
o(),
[
{
mode: r.combine_mode,
terms: i,
},
]
);
})
: o();
}
function c(e, t, n) {
return n.values.some((n) => {
if (r(e))
return (
(n.qty_min === null ||
n.qty_min === void 0 ||
n.qty_max === null ||
n.qty_max === void 0 ||
!Number.isFinite(Number(n.qty_min)) ||
!Number.isFinite(Number(n.qty_max)) ||
Number(n.qty_max) < Number(n.qty_min)) &&
o(),
t >= Number(n.qty_min) && t <= Number(n.qty_max)
);
let i = Number(n.configoption_sub_id);
return ((!Number.isSafeInteger(i) || i <= 0) && o(), t === i);
});
}
function l(e, t, n) {
let r = a(t).map((t) => c(e, t, n));
return n.operator === `not_in`
? !r.some(Boolean)
: n.role === `condition`
? r.some(Boolean)
: !!r.length && r.every(Boolean);
}
function u(e) {
return e.option_type === `os`
? t(e.subs).flatMap((e) => t(e.version).map((e) => Number(e.id)))
: t(e.subs).map((e) => Number(e.id));
}
function d(e) {
let n = {};
for (let o of e) {
let e = i(o);
if (!e || o.option_type === `cascade`) continue;
let s = (
r(o)
? [Number(o.qty)]
: o.configoption_sub_id === void 0
? t(o.subs).some((e) => e.id !== void 0)
? t(o.subs).map((e) => Number(e.id))
: u(o)
: [Number(o.configoption_sub_id)]
).filter(Number.isFinite);
n[e] =
r(o) || o.option_type === `multi_select`
? [...a(n[e]), ...s]
: (s[0] ?? null);
}
return n;
}
function f(e, n, i) {
if (
(e.option_type === `cascade` && o(`高级规则不能将级联项作为普通配置提交`),
!r(e))
) {
let r = (t) =>
n.operator === `not_in` ? !c(e, Number(t), n) : c(e, Number(t), n);
e.subs =
e.option_type === `os`
? t(e.subs)
.map((e) => ({
...e,
version: t(e.version).filter((e) => r(e.id)),
}))
.filter((e) => e.version.length)
: t(e.subs).filter((e) => r(e.id));
return;
}
let a = Number(i.qty_min ?? 0),
s = Math.max(1, Number(i.qty_change || 1));
((!Number.isSafeInteger(a) || !Number.isSafeInteger(s)) && o(),
(e.subs = (
t(e.subs).length
? t(e.subs)
: [
{
qty_min: e.qty_min,
qty_max: e.qty_max,
},
]
).flatMap((t) => {
let r = a + Math.ceil((Number(t.qty_min) - a) / s) * s,
i = a + Math.floor((Number(t.qty_max) - a) / s) * s;
if (!Number.isSafeInteger(r) || !Number.isSafeInteger(i) || i < r)
return [];
let o = Math.floor((i - r) / s) + 1,
l = [
...new Set([
0,
o,
...n.values.flatMap(
(t) => (
c(e, r, {
...n,
values: [t],
}),
[
Math.ceil((Number(t.qty_min) - r) / s),
Math.floor((Number(t.qty_max) - r) / s) + 1,
]
),
),
]),
]
.filter((e) => e >= 0 && e <= o)
.sort((e, t) => e - t);
return l.slice(0, -1).flatMap((i, a) => {
let o = r + i * s,
u = r + (l[a + 1] - 1) * s,
d = c(e, o, n);
return u >= o && (n.operator === `not_in` ? !d : d)
? [
{
...t,
qty_min: o,
qty_max: u,
},
]
: [];
});
})));
let l = t(e.subs);
l.length &&
((e.qty_min = Math.min(...l.map((e) => Number(e.qty_min)))),
(e.qty_max = Math.max(...l.map((e) => Number(e.qty_max)))));
}
function p(e, n, s) {
let c = i(e),
l = String(e.option_name || c),
d = n[c];
if (r(e)) {
let r = t(e.subs),
i = Number(s.qty_min ?? 0),
u = Math.max(1, Number(s.qty_change || 1));
r.length || o(`${l}没有符合当前条件的配置`);
let f = Number(r[0].qty_min),
p = a(d).map((e) =>
r.some(
(t) =>
e >= Number(t.qty_min) &&
e <= Number(t.qty_max) &&
(e - i) % u === 0,
)
? e
: f,
);
n[c] = Array.isArray(d) ? (p.length ? p : [f]) : (p[0] ?? f);
} else {
let t = u(e);
if (
(t.length || o(`${l}没有符合当前条件的配置`),
e.option_type === `multi_select`)
) {
let e = a(d).filter((e) => t.includes(e));
n[c] = e.length ? e : [t[0]];
} else t.includes(Number(d)) || (n[c] = t[0]);
}
}
function m(r, a, c, u = []) {
let m = r.map((t) => n(e(t))),
h = s(c);
if (!h.length)
return {
options: r,
form: a,
};
let g = t(u),
_ = new Map([...g, ...m].map((e) => [i(e), e])),
v = d(g),
y = n(a),
b = new Set();
for (let e = 0; e <= m.length + h.length + 2; e++) {
let e = JSON.stringify(y);
(b.has(e) && o(`商品高级规则相互冲突,请重新选择配置`), b.add(e));
let t = n(m),
r = {
...v,
...y,
},
a = new Set();
for (let e of h) {
let n = e.terms
.filter((e) => e.role === `condition`)
.map((e) => {
let t = _.get(e.id);
return t ? l(t, r[e.id], e) : null;
});
if (e.mode === `any` ? n.some((e) => e === !0) : n.every((e) => e === !0))
for (let n of e.terms.filter((e) => e.role === `result`)) {
let e = t.find((e) => i(e) === n.id);
if (e) (f(e, n, _.get(n.id)), a.add(n.id));
else {
let e = _.get(n.id);
e &&
!l(e, r[n.id], n) &&
o(`所选配置与当前实例配置不兼容,请重新选择`);
}
}
}
for (let e of t) a.has(i(e)) && p(e, y, _.get(i(e)));
if (JSON.stringify(y) === e)
return {
options: t,
form: y,
};
}
return o(`商品高级规则无法确定,请重新选择配置`);
}
export { m as t };
+44
View File
@@ -0,0 +1,44 @@
async function e(e, t = () => !0) {
let n = [],
r = new Set();
for (let i = 1; ; i++) {
if (!t()) return [];
let a = await e(i, 100);
if (!t()) return [];
if (!a || !Array.isArray(a.list)) throw Error(`列表响应无效,请重试`);
let o = a.count === void 0 ? null : Number(a.count);
if (o !== null && (!Number.isSafeInteger(o) || o < 0))
throw Error(`分页信息无效,请重试`);
let s = n.length;
for (let e of a.list) {
if (!e || !Number.isSafeInteger(Number(e.id)) || Number(e.id) <= 0)
throw Error(`列表项目无效,请重试`);
r.has(String(e.id)) || (r.add(String(e.id)), n.push(e));
}
if (o === null ? a.list.length < 100 : n.length >= o) return n;
if (s === n.length) throw Error(`未能加载完整列表,请刷新重试`);
}
}
function t(e, t) {
let n = (
Array.isArray(e) ? e : e && typeof e == `object` && `id` in e ? [e] : []
).filter((e) => !!e && typeof e == `object`),
r = [],
i = [],
a = [];
for (let e of t) {
let t = n.filter((t) => Number(t.id) === e);
t.length === 1 && Number(t[0].status) === 200
? r.push(e)
: (i.push(e),
a.push(
`#${e}:${t.length === 1 ? String(t[0].msg || `关联失败`) : `未取得明确结果,请刷新核对`}`,
));
}
return {
succeeded: r,
failed: i,
details: a,
};
}
export { e as n, t };
+2
View File
@@ -0,0 +1,2 @@
var e = (e) => {};
export { e as t };
+100
View File
@@ -0,0 +1,100 @@
function e(e, t) {
let n = typeof e == `string` ? e.trim() : ``;
return t === `area` || Number(t) === 12
? `区域`
: t === `os` || Number(t) === 5
? `操作系统`
: /^(区域|地区|地域|数据中心|机房)$/.test(n)
? `区域`
: /^(线路|网络线路)$/.test(n)
? `线路`
: /^(带宽|网络带宽|带宽上限)$/.test(n)
? `带宽上限`
: /^(镜像|系统|系统镜像|镜像名称|操作系统)$/.test(n)
? `操作系统`
: /^(系统版本|镜像版本)$/.test(n)
? `镜像版本`
: n;
}
function t(e) {
let t = typeof e == `string` ? e.trim() : ``;
return /^(normal|classic|经典网络)$/i.test(t)
? `经典网络`
: /^(vpc(?:\s*网络)?|私有网络)$/i.test(t)
? `VPC 网络`
: t;
}
function n(e) {
if (typeof e == `string`)
try {
return n(JSON.parse(e));
} catch {
return {};
}
return e && typeof e == `object` && !Array.isArray(e) ? e : {};
}
function r(e) {
return typeof e == `string` ? e.trim() : ``;
}
function i(i, a, o) {
let s = n(a),
c = n(o),
l = n(s.data_center ?? c.data_center),
u =
s.config_options ??
s.configoptions ??
c.config_options ??
c.configoptions,
d = [];
if (Array.isArray(u)) d = u.map(n);
else if (typeof u == `string`)
try {
let e = JSON.parse(u);
Array.isArray(e) && (d = e.map(n));
} catch {}
let f = (t) => d.find((n) => e(n.option_name ?? n.name, n.option_type) === t),
p = (e) => {
let t = f(e);
return t
? r(t.sub_name ?? t.value ?? t.cascade_path) ||
(Array.isArray(t.subs)
? t.subs
.map((e) => r(n(e).option_name))
.filter(Boolean)
.join(` / `)
: ``)
: ``;
},
m = [r(l.city), r(l.area)].filter(Boolean),
h = m.length
? [...new Set(m)].join(` / `)
: r(l.name) || r(l.country) || r(s.data_center) || r(c.data_center);
return i === `kky_ecs`
? {
region: r(s.line_name) || r(c.line_name) || h,
line: r(s.network_name) || r(c.network_name),
networkType: `经典网络`,
}
: i === `jy_cloud` || i === `jy_dcim`
? {
region:
h ||
r(s.region_name) ||
r(s.area_name) ||
p(`区域`) ||
r(s.line_name) ||
r(c.line_name),
line: r(n(s.line).name) || r(s.line_name) || r(c.line_name),
networkType: t(s.network_type ?? c.network_type),
}
: {
region: h || p(`区域`),
line:
r(n(s.line).name) ||
r(s.line_name) ||
r(n(c.line).name) ||
p(`线路`),
networkType: t(s.network_type ?? c.network_type) || t(p(`网络类型`)),
};
}
export { i as n, t as r, e as t };
+25
View File
@@ -0,0 +1,25 @@
function e(e) {
if (typeof e != `string` || !/^[1-9]\d*$/.test(e)) return null;
let t = Number(e);
return Number.isSafeInteger(t) ? t : null;
}
function t(e) {
return e === `help` || e === `news` || e === `notices` ? e : null;
}
function n(t, n) {
let r = e(t);
return r
? ({
IdcsmartHelp: `help`,
IdcsmartNews: `news`,
IdcsmartAnnouncement: `notices`,
}[
n.find(
(e) =>
Number(e.id) === r &&
(e.status === void 0 || Number(e.status) === 1),
)?.name ?? ``
] ?? null)
: null;
}
export { n, t as r, e as t };
+127
View File
@@ -0,0 +1,127 @@
import { n as product_name_n } from "~/lib/product-name.js";
var t = {
Unpaid: {
label: `未付款`,
severity: `warn`,
},
Pending: {
label: `开通中`,
severity: `info`,
},
Active: {
label: `使用中`,
severity: `success`,
},
Suspended: {
label: `暂停`,
severity: `danger`,
},
Deleted: {
label: `删除`,
severity: `secondary`,
},
Failed: {
label: `开通失败`,
severity: `danger`,
},
},
n = {
Unpaid: {
label: `未付款`,
severity: `warn`,
},
Paid: {
label: `已付款`,
severity: `success`,
},
WaitUpload: {
label: `待上传`,
severity: `warn`,
},
WaitReview: {
label: `待审核`,
severity: `warn`,
},
ReviewFail: {
label: `审核失败`,
severity: `danger`,
},
Cancelled: {
label: `已取消`,
severity: `secondary`,
},
Refunded: {
label: `已退款`,
severity: `info`,
},
},
r = {
new: `新订单`,
renew: `续费订单`,
upgrade: `升降级订单`,
artificial: `人工订单`,
recharge: `充值订单`,
combine: `合并订单`,
credit_limit: `还款订单`,
on_demand: `按需订单`,
change_billing_cycle: `变更计费周期`,
},
i = {
Recharge: `充值`,
Applied: `扣费`,
Refund: `退款`,
Withdraw: `提现`,
Artificial: `人工`,
Freeze: `冻结`,
Unfreeze: `解冻`,
DeveloperWithdraw: `开发者提现`,
};
function a(e) {
return i[e] ?? e;
}
function o(t) {
let n = t.product_names;
if (Array.isArray(n)) {
let t = n.map(product_name_n).filter(Boolean).join(`、`);
if (t) return t;
} else if (n) return product_name_n(n);
return t.name || t.description || `--`;
}
function s(e) {
return t[e]?.label ?? e;
}
function c(e) {
return t[e]?.severity ?? `secondary`;
}
function l(e) {
return r[e] ?? e;
}
function u(e) {
return n[e]?.label ?? e;
}
function d(e) {
return n[e]?.severity ?? `secondary`;
}
function f(e) {
if (!e) return `--`;
let t = new Date(e * 1e3),
n = (e) => String(e).padStart(2, `0`);
return `${t.getFullYear()}-${n(t.getMonth() + 1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`;
}
function p(e) {
if (!e) return `--`;
let t = new Date(e * 1e3),
n = (e) => String(e).padStart(2, `0`);
return `${t.getFullYear()}-${n(t.getMonth() + 1)}-${n(t.getDate())}`;
}
export {
u as a,
s as c,
o as i,
c as l,
p as n,
d as o,
f as r,
l as s,
a as t,
};
+41
View File
@@ -0,0 +1,41 @@
function e(e) {
if (typeof e != `number` && (typeof e != `string` || !e.trim())) return null;
let t = Number(e);
return Number.isFinite(t) ? t : null;
}
function t(t, n) {
let r = t.list ?? [],
i = t.label ?? [],
a = i.findIndex((e) => /已用|使用|used|usage|utilization/i.test(e)),
o = (t) => {
let n = e(t);
return n === null
? null
: Number(Math.min(100, Math.max(0, n)).toFixed(2));
},
s = (e) => e.map((e) => String(e.time ?? ``).slice(11, 16));
if (n === `cpu` || /%|percent/i.test(t.unit ?? ``)) {
let e = r[n === `memory` && a >= 0 ? a : 0] ?? [];
return {
labels: s(e),
data: e.map((e) => o(e.value)),
};
}
let c = i.findIndex((e) => /总|total|allocated/i.test(e)),
l = c >= 0 ? c : 0,
u = i.findIndex((e) => /空闲|可用|free|available/i.test(e)),
d = a >= 0 ? a : u >= 0 ? u : 1,
f = r[l] ?? [],
p = new Map((r[d] ?? []).map((e) => [String(e.time ?? ``), e.value]));
return {
labels: s(f),
data: f.map((t) => {
let n = e(t.value),
r = t.time ? e(p.get(t.time)) : null;
if (l === d || n === null || n <= 0 || r === null || r < 0) return null;
let i = a < 0 && u >= 0 ? n - r : r;
return o((i / n) * 100);
}),
};
}
export { t as n, e as t };
+250
View File
@@ -0,0 +1,250 @@
function e(e) {
if (e == null || e === ``) return null;
let t = Number(e);
return Number.isFinite(t) ? t : null;
}
function t(t) {
if (typeof t != `number` && typeof t != `string`) return null;
let n = e(t);
return n !== null && Number.isInteger(n) && n >= 1 && n <= 65535 ? n : null;
}
function n(e) {
if (typeof e == `string`)
try {
return n(JSON.parse(e));
} catch {
return {};
}
return e && typeof e == `object` && !Array.isArray(e) ? e : {};
}
function r(e) {
if (typeof e == `string`)
try {
return r(JSON.parse(e));
} catch {
return [];
}
return Array.isArray(e) ? e.filter((e) => e && typeof e == `object`) : [];
}
function i(t) {
let n = e(t);
if (n !== null) return n > 0xe8d4a51000 ? Math.floor(n / 1e3) : n || void 0;
let r = Date.parse(String(t ?? ``).replace(` `, `T`));
return Number.isFinite(r) ? Math.floor(r / 1e3) : void 0;
}
function a(e, t = `GB`) {
if (typeof e == `string` && /不限|unlimited/i.test(e)) return 0;
let n = /^\s*(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)\s*([KMGT]?B)?\s*$/i.exec(
String(e ?? ``),
);
if (!n) return null;
let r = (n[2] || t).toUpperCase(),
i =
Number(n[1]) *
({
B: 1 / 1024 ** 3,
KB: 1 / 1024 ** 2,
MB: 1 / 1024,
GB: 1,
TB: 1024,
}[r] ?? 1);
return Number.isFinite(i) ? i : null;
}
function o(t, r, i) {
let o = n(r),
s = n(i),
c = n(o.host_data),
l = n(s.billing),
u = n(s.quota),
d =
t === `kky_ecs`
? l.mode === `traffic` || l.mode === `bandwidth`
? l.mode
: Number(o.bill_method) === 1
? `bandwidth`
: Number(o.bill_method) === 2
? `traffic`
: ``
: ``,
f = t === `kky_ecs` ? e(l.unit_price) : null,
p = f !== null && f >= 0 ? f : null,
m = t === `kky_ecs` ? a(l.monthly_quota) : null,
h = m !== null && m >= 0 ? m : null,
g = a(u.total),
_ = a(u.used),
v = a(u.remaining),
y =
t === `kky_ecs` &&
g !== null &&
g >= 0 &&
_ !== null &&
_ >= 0 &&
v !== null &&
v >= 0
? {
total: g,
used: _,
remaining: v,
percent: g > 0 ? Math.min(100, (_ / g) * 100) : null,
start: String(u.start_time ?? ``),
end: String(u.end_time ?? ``),
}
: null,
b =
t === `kky_ecs` &&
[`available`, `none`, `not_applicable`].includes(
String(s.quota_status ?? ``),
),
x = null,
S = null,
C = null,
w = ``,
T = !1,
E = t === `kky_ecs` && !!s.start_time && !!s.end_time,
D = E ? a(s.incoming) : null;
if (t === `mf_cloud` || t === `remf_cloud`)
((x = a(s.total_num ?? s.total)),
(S = a(s.used_num ?? s.used)),
(C = a(s.leave)),
(w = String(s.reset_flow_date ?? ``)));
else if (t === `remf_finance`)
((x = a(c.bwlimit, String(c.bwunit ?? `GB`))),
(S = a(c.bwusage, String(c.bwunit ?? `GB`))),
(w = String(c.reset_flow_date ?? o.reset_flow_date ?? ``)));
else {
let e = n(o.traffic);
((x = a(
o.traffic_total ??
o.total_traffic ??
e.total ??
(typeof o.traffic == `object` ? null : o.traffic),
)),
(S = a(
E
? s.used
: (o.traffic_used ?? o.used_traffic ?? o.traffic_usage ?? e.used),
)),
(C = a(o.traffic_remain ?? o.remain_traffic ?? e.remain)),
(w = String(o.traffic_reset_time ?? o.reset_flow_date ?? ``)),
(T =
Number(o.bill_method) === 2 ||
Number(o.traffic_show) === 1 ||
/流量/.test(String(o.bill_method_name ?? ``))),
(l.mode === `traffic` || l.mode === `bandwidth`) &&
(T = l.mode === `traffic`),
d && (T = d === `traffic`));
}
return (
!E &&
x !== null &&
x > 0 &&
S === null &&
C !== null &&
(S = Math.max(0, x - C)),
!E &&
x !== null &&
x > 0 &&
C === null &&
S !== null &&
(C = Math.max(0, x - S)),
{
total: x,
used: S,
remaining: C,
reset: w,
unlimited: !T && (x === null ? d === `bandwidth` : x <= 0),
metered: T,
incoming: D,
quota: y,
quotaLoaded: b,
unitPrice: p,
monthlyQuota: h,
periodStart: E ? String(s.start_time) : ``,
periodEnd: E ? String(s.end_time) : ``,
usedLabel: E ? `最近完整小时出站流量` : `已用流量`,
percent:
!E && x !== null && x > 0 && S !== null
? Math.max(0, Math.min(100, (S / x) * 100))
: null,
packageRemaining:
t === `kky_ecs` && Number(o.traffic_show) !== 1
? null
: a(o.traffic_package_remain),
}
);
}
function s(e) {
return e === null
? `—`
: Math.abs(e) >= 1024
? `${(e / 1024).toFixed(2)} TB`
: `${e.toFixed(2)} GB`;
}
function c(e) {
return e === null
? `—`
: e === 0
? `0 B`
: Math.abs(e) >= 1
? s(e)
: Math.abs(e) >= 1 / 1024
? `${(e * 1024).toFixed(2)} MB`
: Math.abs(e) >= 1 / 1024 ** 2
? `${(e * 1024 ** 2).toFixed(2)} KB`
: `${(e * 1024 ** 3).toFixed(0)} B`;
}
function l(t) {
let o = n(t);
return r(o.disk ?? o.disks ?? o.disk_list).map((t, n) => {
let r = String(t.type2 ?? t.type ?? t.disk_property ?? ``).toLowerCase(),
o =
[`system`, `sys`, `1`].includes(r) || /系统/.test(String(t.name ?? ``));
return {
ident: String(t.id ?? t.disk_id ?? t.identity ?? n),
name: String(t.name ?? t.disk_name ?? (o ? `系统盘` : `数据盘`)),
size: a(t.size ?? t.disk_size) ?? 0,
type: String(t.fs_type ?? t.disk_type ?? `—`),
type2: o ? `system` : `data`,
status: e(t.status) ?? -1,
createTime: i(t.create_time ?? t.created_at),
raw: t,
};
});
}
function u(e) {
let t = n(e),
i = n(t.image),
a = n(t.host_data),
o = r(t.config_options).find((e) => Number(e.option_type) === 5);
return {
name: String(
t.image_name ?? i.name ?? t.os_name ?? t.os ?? o?.sub_name ?? a.os ?? ``,
),
icon: String(t.image_icon ?? i.icon ?? ``),
url: String(t.image_icon_url ?? i.icon_url ?? ``),
};
}
function d(e, t) {
let r = n(e);
return {
id: String(r.id ?? r.log_id ?? t),
description: String(
r.description ?? r.content ?? r.detail ?? r.message ?? r.des ?? `—`,
),
create_time: i(r.create_time ?? r.created_at ?? r.time ?? r.date),
ip: String(r.ip ?? r.ip_address ?? ``),
};
}
export {
u as a,
t as c,
o as d,
r as i,
n as l,
s as n,
d as o,
c as r,
e as s,
l as t,
i as u,
};
+95
View File
@@ -0,0 +1,95 @@
function e(e, t) {
let n =
typeof t == `string` &&
[`suspend`, `suspended`, `paused`].includes(t.trim().toLowerCase());
return e.status !== `Suspended` && !(e.status === `Active` && n)
? ``
: e.suspend_reason?.trim() ||
{
overtraffic: `流量用尽,服务已暂停`,
overdue: `服务到期,已暂停`,
certification_not_complete: `实名认证未完成,服务已暂停`,
upstream: `上游暂停服务`,
downstream: `下游暂停服务`,
}[e.suspend_type || ``] ||
`暂停原因暂未提供,请联系支持`;
}
function t(e, t = `Active`, n = !1) {
let r = {
Unpaid: `未付款`,
Pending: `开通中`,
Suspended: `暂停`,
Deleted: `已删除`,
Failed: `开通失败`,
Grace: `宽限期`,
Keep: `保留期`,
};
if (t && t !== `Active`)
return {
label: r[t] || `状态未知`,
tone: `warning`,
severity: `warn`,
};
let i = typeof e == `string` ? e.trim().toLowerCase() : ``;
return i === `on`
? {
label: `运行中`,
tone: `running`,
severity: `success`,
}
: i === `off`
? {
label: `已关机`,
tone: `stopped`,
severity: `danger`,
}
: {
label:
{
suspend: `暂停`,
suspended: `暂停`,
paused: `暂停`,
pending: `开通中`,
operating: `操作中`,
fault: `故障`,
}[i] || (n ? `查询中` : `状态未知`),
tone: `warning`,
severity: `warn`,
};
}
function n(e, t) {
if (!/^[1-9]\d*$/.test(String(t))) return null;
let n = e.replace(/^mf_finance(?=$|_)/, `remf_finance`);
return n === `idcsmart_common` || n === `reidcsmart_common`
? {
method: `post`,
path: `/${n}/host/${t}/provision/status`,
}
: [
`mf_cloud`,
`kky_ecs`,
`mf_dcim`,
`remf_dcim`,
`remf_cloud`,
`remf_finance`,
`remf_finance_dcim`,
`remf_finance_common`,
`jy_cloud`,
`jy_dcim`,
].includes(n)
? {
method: `get`,
path: `/${n}/${t}/status`,
}
: null;
}
async function r(e, t, r) {
let i = n(t, r);
if (!i) return ``;
let a = await e[i.method](i.path, void 0, !1, {
timeoutMs: 12e3,
}),
o = a && typeof a == `object` ? a.status : void 0;
return typeof o == `string` ? o : ``;
}
export { e as n, r, t };
+2
View File
@@ -0,0 +1,2 @@
var e = globalThis.setInterval;
export { e as t };
+28
View File
@@ -0,0 +1,28 @@
async function e(e) {
let t = [],
n = new Set();
for (let r = 1; ; r++) {
let i = await e(r, 50);
if (!i || !Array.isArray(i.list))
throw Error(`发票资料格式异常,请重新加载`);
let a = i.count === void 0 ? null : Number(i.count);
if (a !== null && (!Number.isSafeInteger(a) || a < 0))
throw Error(`发票资料分页信息异常,请重新加载`);
let o = t.length;
for (let e of i.list) {
if (
!e ||
![`number`, `string`].includes(typeof e.id) ||
!String(e.id).trim()
)
throw Error(`发票资料格式异常,请重新加载`);
let r = String(e.id);
n.has(r) || (n.add(r), t.push(e));
}
if ((a !== null && t.length >= a) || (a === null && i.list.length < 50))
return t;
if (t.length === o)
throw Error(`未能加载完整发票资料,分页数据可能已变化,请重试`);
}
}
export { e as t };
+62
View File
@@ -0,0 +1,62 @@
var e = {
cloud: [
`mf_cloud`,
`kky_ecs`,
`whmcs_cloud`,
`mf_finance`,
`remf_finance`,
`jy_cloud`,
],
dcim: [
`mf_dcim`,
`remf_dcim`,
`mf_finance_dcim`,
`remf_finance_dcim`,
`whmcs_dcim`,
`jy_dcim`,
],
common: [`idcsmart_common`, `mf_finance_common`],
};
function t(e, t, n) {
let r = String(e ?? ``).trim();
if (r && !/[\u0000-\u0020\u007f\\]/.test(r)) {
if (/^\/(?!\/)/.test(r)) return r;
try {
let e = new URL(r.startsWith(`//`) ? `https:${r}` : r);
if (/^(https?:)$/.test(e.protocol) && !e.username && !e.password)
return r;
} catch {}
}
let i = [
[`Windows`, [`windows`, `winserver`]],
[`Ubuntu`, [`ubuntu`]],
[`Debian`, [`debian`]],
[`TencentOS-Server`, [`tencentos`]],
[`CentOS`, [`centos`]],
[`Rocky`, [`rocky`]],
[`AlmaLinux`, [`almalinux`]],
[`OpenEuler`, [`openeuler`, `euleros`]],
[`RedHat`, [`redhat`, `rhel`]],
[`Fedora`, [`fedora`, `fedroa`]],
[`ArchLinux`, [`archlinux`]],
[`FreeBSD`, [`freebsd`]],
[`ESXi`, [`esxi`]],
[`XenServer`, [`xenserver`]],
[`OpenClaw`, [`openclaw`]],
],
a = [e, n].map((e) =>
String(e ?? ``)
.toLowerCase()
.replace(/[\s_.\-/]+/g, ``),
);
for (let e of a) {
let t = i.find(([, t]) => t.some((t) => e.includes(t)));
if (t) return `/images/os/${t[0]}.svg`;
}
return a.some((e) => /linux|alpine|opensuse|suse/.test(e))
? `/images/os/Linux.svg`
: e || n
? `/images/os/Other.svg`
: ``;
}
export { t as n, e as t };
+76
View File
@@ -0,0 +1,76 @@
import { watch } from "vue";
import { ref } from "vue";
import { effectScope } from "vue";
import { i as backend_menu_i } from "~/lib/backend-menu.js";
import { l as backend_menu_l } from "~/lib/backend-menu.js";
function a(a, o) {
let s = ref([]),
c = ref(!1),
l = ref(!1),
u = ref(!1),
d = ref(``),
f = 0,
p = null;
effectScope(!0).run(() =>
watch(
() => a.token,
() => {
(f++,
(p = null),
(s.value = []),
(c.value = !1),
(l.value = !1),
(u.value = !1),
(d.value = ``));
},
{
flush: `sync`,
},
),
);
function m(e = !1) {
if (!a.isLoggedIn) return Promise.resolve();
if (p) return p;
if (l.value && !e) return Promise.resolve();
let t = f,
n = a.token;
((u.value = !0), (d.value = ``));
let m = o
.get(`/menu`, void 0, !1, {
timeoutMs: 8e3,
})
.then((e) => {
if (t === f && n === a.token) {
if (!Array.isArray(e?.menu)) throw Error(`站点导航响应异常`);
((s.value = backend_menu_l(backend_menu_i(e.menu))),
(c.value =
e.menu.length === 0 ||
e.menu.some((e) => e && typeof e == `object` && `id` in e)),
(l.value = !0));
}
})
.catch((e) => {
t === f &&
n === a.token &&
(d.value = e instanceof Error ? e.message : `站点导航加载失败`);
})
.finally(() => {
p === m && ((p = null), (u.value = !1));
});
return ((p = m), m);
}
return {
entries: s,
authoritative: c,
loaded: l,
loading: u,
error: d,
load: m,
};
}
var o = new WeakMap();
function s(e, t) {
let n = o.get(e);
return (n || ((n = a(e, t)), o.set(e, n)), n);
}
export { s as t };
+67
View File
@@ -0,0 +1,67 @@
import { o as backend_menu_o } from "~/lib/backend-menu.js";
function t(t) {
return Array.isArray(t)
? t.flatMap((t) => {
if (
!t ||
typeof t != `object` ||
typeof t.name != `string` ||
!/^[a-z][a-z0-9_]*$/i.test(t.name)
)
return [];
let n = typeof t.img == `string` ? t.img : ``,
r =
/^\/(?!\/)/.test(n) && !/[\\\u0000-\u0020]/.test(n)
? n
: backend_menu_o(n);
return [
{
name: t.name,
title: typeof t.title == `string` ? t.title : t.name,
image: r,
linked: t.link === !0 || t.link === 1 || t.link === `1`,
},
];
})
: [];
}
function n(t, n) {
return typeof t == `string`
? /^\/(?!\/)/.test(t) && !/[\\\u0000-\u0020]/.test(t)
? new URL(t, n).href
: backend_menu_o(t)
: ``;
}
function r(e, t, r = t) {
if (!e || typeof e != `object` || Array.isArray(e))
return {
kind: `expired`,
};
let i = e;
if (typeof i.jwt == `string` && i.jwt.trim())
return {
kind: `login`,
jwt: i.jwt.trim(),
};
let a = n(i.url, t);
if (a) {
let e = new URL(a);
if (e.pathname === `/oauth.htm` && [t, r].includes(e.origin))
return (
(e.pathname = `/oauth/bind`),
{
kind: `bind`,
url: t + e.pathname + e.search + e.hash,
}
);
if (e.origin === t && e.pathname === `/oauth/bind`)
return {
kind: `bind`,
url: a,
};
}
return {
kind: `expired`,
};
}
export { r as n, n as r, t };
+42
View File
@@ -0,0 +1,42 @@
var e = Symbol(`order-login-continuation`);
function t(e) {
if (typeof e != `number` && typeof e != `string`) return;
let t = Number(e);
if (!(
!Number.isSafeInteger(t) ||
t <= 0 ||
(typeof e == `string` && String(t) !== e)
))
return t;
}
function n(e) {
let t = decodeURIComponent(e);
return (
t.startsWith(`/`) &&
!t.startsWith(`//`) &&
!/[\\\u0000-\u0020\u007f]/.test(t)
);
}
function r(e, r) {
try {
if (
typeof e != `string` ||
/[\\\u0000-\u0020\u007f]/.test(e) ||
!n(e.split(/[?#]/, 1)[0] || ``)
)
return `/products`;
let i = new URL(e, `https://console.invalid`);
if (i.origin !== `https://console.invalid` || !n(i.pathname))
return `/products`;
let a = t(r);
return (
a === void 0
? i.searchParams.delete(`order_image`)
: i.searchParams.set(`order_image`, String(a)),
`${i.pathname}${i.search}${i.hash}`
);
} catch {
return `/products`;
}
}
export { r as n, t as r, e as t };
+78
View File
@@ -0,0 +1,78 @@
var e = {
debian: `Debian`,
ubuntu: `Ubuntu`,
centos: `CentOS`,
windows: `Windows`,
rocky: `Rocky`,
"rocky linux": `Rocky Linux`,
almalinux: `AlmaLinux`,
fedora: `Fedora`,
openeuler: `openEuler`,
freebsd: `FreeBSD`,
tencentos: `TencentOS`,
alpine: `Alpine`,
"alpine linux": `Alpine Linux`,
},
t = {
server: `Server`,
stream: `Stream`,
datacenter: `Datacenter`,
standard: `Standard`,
enterprise: `Enterprise`,
professional: `Professional`,
essentials: `Essentials`,
education: `Education`,
desktop: `Desktop`,
minimal: `Minimal`,
core: `Core`,
pro: `Pro`,
home: `Home`,
lts: `LTS`,
uefi: `UEFI`,
bios: `BIOS`,
gpt: `GPT`,
bt: `BT`,
};
function n(n) {
let r = n.match(
/^(Debian|Ubuntu|CentOS|Windows|Rocky(?:[ _-]+Linux)?|AlmaLinux|Fedora|openEuler|FreeBSD|TencentOS|Alpine(?:[ _-]+Linux)?)(?=$|[\d\s_-])/i,
);
if (!r) return n;
let i = n.slice(r[0].length),
a = !1,
o = [e[r[0].replace(/[ _-]+/g, ` `).toLowerCase()]],
s =
/^[\s_-]*(x86[_-]64|64[ _-]?(?:bits?|位)|32[ _-]?(?:bits?|位)|\d+(?:\.\d+)*(?:R2)?|Server|Stream|Datacenter|Standard|Enterprise|Professional|Essentials|Education|Desktop|Minimal|Core|Pro|Home|R2|LTS|SP\d+|UEFI|BIOS|GPT|BT|ARM64|aarch64|x64|amd64|x86|x32|i386|i686|ARM|cn|en|zh(?:[ _-](?:CN|TW))?|专业版|标准版|数据中心版|企业版|家庭版|教育版|中文版|英文版)(?=$|[\s_()()\[\]【】-])/i;
for (let e = i.match(s); e; e = i.match(s)) {
let n = t[e[1].toLowerCase()] ?? e[1];
(/^\d+(?:\.\d+)*(?:R2)?$/i.test(n) &&
(o[0] === `CentOS` &&
!a &&
(n = n.replace(/^(\d+\.\d+)(?:\.\d+)+$/, `$1`)),
(n = n.replace(/^(\d+(?:\.\d+)*)R2$/i, `$1 R2`)),
(a = !0)),
o.push(n),
(i = i.slice(e[0].length)));
}
return o.join(` `) + i;
}
function r(e) {
if (typeof e != `string`) return ``;
let t = e.trim();
if (!t) return ``;
let r = `(?:x86[_-]64|x64|amd64|64[ _-]?(?:bit|bits|位))`;
return (
n(t.replace(/\.(?:iso|qcow2?|img|raw|vhdx?|vmdk)$/i, ``))
.replace(
/[\s_-]*(?:[((【\[]\s*)?纯净优化版(?:\s*[))】\]])?(?=$|[\s_-])/g,
``,
)
.replace(RegExp(`[((\\[【]\\s*${r}\\s*[))\\]】]`, `gi`), ` `)
.replace(RegExp(`(^|[\\s_])${r}(?=$|[\\s_])`, `gi`), `$1`)
.replace(RegExp(`-${r}$`, `i`), ``)
.replace(/_+/g, ` `)
.replace(/\s+/g, ` `)
.trim() || (t.includes(`纯净优化版`) ? `默认镜像` : t)
);
}
export { r as t };
+21
View File
@@ -0,0 +1,21 @@
function e(e = 12) {
let t = (e) => e[Math.floor(Math.random() * e.length)],
n = [
t(`abcdefghjkmnpqrstuvwxyz`),
t(`ABCDEFGHJKMNPQRSTUVWXYZ`),
t(`23456789`),
],
r = Array.from(
{
length: Math.max(0, e - n.length),
},
() => t(`abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789`),
),
i = [...n, ...r];
for (let e = i.length - 1; e > 0; e--) {
let t = Math.floor(Math.random() * (e + 1));
[i[e], i[t]] = [i[t], i[e]];
}
return i.join(``);
}
export { e as t };
+26
View File
@@ -0,0 +1,26 @@
async function e(e, t) {
if (typeof t.description == `string`) return t.description;
let n = Number(t.id);
if (!Number.isSafeInteger(n) || n <= 0) return ``;
try {
let t = await e.get(
`/product`,
{
product_ids: [n],
page: 1,
limit: 1,
},
!1,
{
timeoutMs: 5e3,
},
),
r = Array.isArray(t?.list)
? t.list.find((e) => e && Number(e.id) === n)
: void 0;
return typeof r?.description == `string` ? r.description : ``;
} catch {
return ``;
}
}
export { e as t };
+214
View File
@@ -0,0 +1,214 @@
function e(e) {
return e && typeof e == `object` && !Array.isArray(e) ? e : null;
}
function t(e) {
return typeof e == `string` || typeof e == `number` ? String(e) : ``;
}
function n(e) {
return e === !0 || e === 1 || e === `1`;
}
function r(n) {
return (
Array.isArray(n)
? n.flatMap((n) => {
let r = e(n);
return r
? [
{
value: t(r.value ?? r.id ?? r.option_value),
label: t(r.label ?? r.name ?? r.option_name ?? r.value),
},
]
: [t(n)];
})
: t(n).split(/[,\n]/)
)
.map((e) =>
typeof e == `string`
? {
value: e.trim(),
label: e.trim(),
}
: e,
)
.filter((e) => e.value !== ``);
}
function i(e) {
let n = t(e).trim();
if (!n) return {};
let r = ``,
i = n[0],
a = {
"(": `)`,
"[": `]`,
"{": `}`,
"<": `>`,
};
if (/[^a-zA-Z0-9\\\s\0]/.test(i)) {
let e = a[i] ?? i,
t = 1,
o = -1;
for (let r = 1; r < n.length; r++) {
if (n[r] === `\\`) {
r++;
continue;
}
if ((a[i] && n[r] === i && t++, n[r] === e && --t === 0)) {
o = r;
break;
}
a[i] || (t = 1);
}
if (o > 0 && /^[a-zA-Z\s]*$/.test(n.slice(o + 1)))
((r = n.slice(o + 1).replace(/\s/g, ``)),
(n = n.slice(1, o)),
`\\^$.*+?()[]{}|/`.includes(e) || (n = n.split(`\\${e}`).join(e)));
else if (`/#~%!`.includes(i)) throw Error(`自定义字段验证规则无效`);
}
if (!/^[imsuxADSUXJnr]*$/.test(r))
throw Error(`自定义字段验证规则修饰符无效`);
let o = /^\(\?([imsx]+)\)/.exec(n);
o && ((r += o[1]), (n = n.slice(o[0].length)));
let s = [...new Set(r.replace(/[^imsu]/g, ``))].join(``);
if (
/\(\?(?:[>('|&R0-9]|P[=>]|[imsx-]+:)|\(\*|\\[KCG]|(?:[+*?]|\{\d+(?:,\d*)?\})\+/.test(
n,
) ||
r.includes(`r`) ||
(r.includes(`J`) && /\(\?</.test(n))
)
return {
pattern: n,
patternFlags: s || void 0,
patternServerOnly: !0,
};
let c = ``,
l = !1;
for (let e = 0; e < n.length; e++) {
let t = n[e];
if (t === `\\`) {
let t = n[++e],
r = {
A: `(?<![\\s\\S])`,
z: `(?![\\s\\S])`,
Z: `(?=\\n?(?![\\s\\S]))`,
};
c += !l && t && r[t] ? r[t] : `\\${t ?? ``}`;
continue;
}
if (
(t === `[` && !l ? (l = !0) : t === `]` && l && (l = !1),
!l && r.includes(`x`))
) {
if (/\s/.test(t)) continue;
if (t === `#`) {
for (
;
e < n.length &&
n[e] !==
`
`;
)
e++;
continue;
}
}
if (!l && t === `$` && r.includes(`D`) && !s.includes(`m`)) {
c += `(?![\\s\\S])`;
continue;
}
if (!l && t === `(` && r.includes(`n`) && n[e + 1] !== `?`) {
c += `(?:`;
continue;
}
((c += t),
!l &&
r.includes(`U`) &&
(`*+`.includes(t) ||
(t === `?` && e > 0 && n[e - 1] !== `(`) ||
(t === `}` && /\{\d+(?:,\d*)?\}$/.test(c))) &&
(n[e + 1] === `?` ? e++ : (c += `?`)));
}
r.includes(`A`) && (c = `(?<![\\s\\S])(?:${c})`);
try {
new RegExp(c, s);
} catch {
throw Error(`自定义字段验证规则无效`);
}
return {
pattern: c,
patternFlags: s || void 0,
};
}
function a(a) {
let o = e(a),
s = Array.isArray(a) ? a : Array.isArray(o?.data) ? o.data : [],
c = [];
for (let a of s) {
let o = e(a);
if (!o || o.id === void 0) continue;
let s = t(o.field_type || o.type).toLowerCase();
if (
![
`text`,
`password`,
`textarea`,
`dropdown`,
`checkbox`,
`tickbox`,
`link`,
`explain`,
].includes(s)
)
continue;
let l =
s === `dropdown`
? `select`
: s === `checkbox` || s === `tickbox`
? `boolean`
: s;
c.push({
id: String(o.id),
label: t(o.field_name || o.name).trim() || `自定义字段`,
kind: l,
required: n(o.is_required ?? o.required),
...i(o.regexpr),
description: t(o.description).trim() || void 0,
explain: t(o.explain_content).trim() || void 0,
options: l === `select` ? r(o.field_option ?? o.options) : [],
});
}
return c.filter((e, t, n) => n.findIndex((t) => t.id === e.id) === t);
}
function o(e) {
return Object.fromEntries(
e.filter((e) => e.kind !== `explain`).map((e) => [e.id, (e.kind, ``)]),
);
}
function s(e, t) {
for (let n of e) {
if (n.kind === `explain`) continue;
let e = t[n.id],
r =
n.kind === `boolean`
? e === !0 || e === 1 || e === `1`
? `1`
: ``
: String(e ?? ``).trim();
if (n.required && !r) throw Error(`请填写${n.label}`);
if (r) {
if (n.kind === `select` && !n.options.some((e) => e.value === r))
throw Error(`${n.label}选项无效`);
if (n.pattern && !n.patternServerOnly) {
let e;
try {
e = new RegExp(n.pattern, n.patternFlags);
} catch {
throw Error(`${n.label}验证规则无效`);
}
if (!e.test(r)) throw Error(`${n.label}格式不正确`);
}
}
}
}
export { s as i, i as n, a as r, o as t };
+17
View File
@@ -0,0 +1,17 @@
function e(e) {
return typeof e == `string` && /-L\s*$/.test(e);
}
function t(e) {
return typeof e == `string` ? e.replace(/-L\s*$/, ``).trim() : ``;
}
function n(n, r) {
if (!n) return ``;
let i = [...new Set(r.filter((t) => e(t)).map((e) => e.trim()))].sort(
(e, t) => t.length - e.length,
);
if (!i.length) return n;
let a = i.map((e) => e.replace(/[.*+?^${}()|[\]\\]/g, `\\$&`)).join(`|`),
o = RegExp(`(?<![A-Za-z0-9_-])(?:${a})(?![A-Za-z0-9_-])`, `g`);
return n.replace(o, (e) => t(e));
}
export { t as n, n as r, e as t };
+23
View File
@@ -0,0 +1,23 @@
function e(e) {
let t = typeof e.module == `string` ? e.module.trim() : ``,
n = typeof e.res_module == `string` ? e.res_module.trim() : ``;
if (t === `mf_dcim`) return `mf_dcim`;
if (t === `remf_dcim` || (!t && n === `mf_dcim`)) return `remf_dcim`;
}
async function t(t, n) {
let r = typeof n.module == `string` ? n.module.trim() : ``,
i = e(n);
if (i) return i;
if (r && r !== `mf_cloud`) return r;
let a = await t.get(`/product/${n.id}/config_option`),
o = typeof a?.module == `string` ? a.module.trim() : ``,
s =
e({
module: o,
res_module: typeof a?.res_module == `string` ? a.res_module.trim() : ``,
}) || (!r && n.res_module === `mf_dcim` ? `remf_dcim` : void 0);
if (s) return s;
if (!o) throw Error(`商品配置类型加载失败,请重试`);
return o;
}
export { t };
+48
View File
@@ -0,0 +1,48 @@
import { ref } from "vue";
function t(t) {
let n = ref(!1),
r = ref(!1),
i = ref(!1),
a = ref(``),
o = 0;
function s() {
(o++, (n.value = !1), (r.value = !1), (i.value = !1), (a.value = ``));
}
async function c(e) {
let s = ++o;
((n.value = !0), (r.value = !1), (i.value = !1), (a.value = ``));
try {
let n = await t(e);
if (s !== o) return;
if (
!n ||
typeof n != `object` ||
!(`allowed` in n) ||
typeof n.allowed != `boolean` ||
!(`message` in n) ||
typeof n.message != `string`
)
throw Error(`限购检查暂时不可用,请重试`);
((i.value = n.allowed),
(a.value = n.allowed
? ``
: n.message || `此商品已达到购买限制,请调整数量后重试`));
} catch (e) {
s === o &&
(a.value =
(e instanceof Error ? e.message : ``) ||
`限购检查暂时不可用,请重试`);
} finally {
s === o && ((n.value = !1), (r.value = !0));
}
}
return {
pending: n,
checked: r,
allowed: i,
message: a,
check: c,
reset: s,
};
}
export { t };
+21
View File
@@ -0,0 +1,21 @@
var e = new Set([
`kky_ecs`,
`mf_cloud`,
`remf_cloud`,
`mf_dcim`,
`remf_dcim`,
`remf_finance`,
`remf_finance_dcim`,
`remf_finance_common`,
`idcsmart_common`,
]);
function t(t, n) {
let r = String(t);
if (!/^[1-9]\d{0,9}$/.test(r) || !e.has(n))
throw Error(`实例信息无效,请刷新后重试`);
return `/remote-console?hostId=${r}&module=${n}`;
}
function n(e, n) {
window.open(t(e, n), `_blank`, `noopener,noreferrer`);
}
export { n as t };
+34
View File
@@ -0,0 +1,34 @@
function e(e) {
return (e ?? []).map((e) => ({
...e,
name_show: e.name_show?.trim() || e.billing_cycle,
}));
}
function t(e) {
if (!e || typeof e != `object` || !(`status` in e)) return !1;
let t = e.status;
return typeof t == `number`
? [0, 408, 429, 500, 502, 503, 504].includes(t)
? !0
: t === 400 &&
`message` in e &&
typeof e.message == `string` &&
/稍后重试|服务暂不可用|系统繁忙/u.test(e.message)
: !1;
}
function n(e) {
return t(e)
? `暂时无法获取续费价格,请重新获取或稍后重试`
: e instanceof Error
? e.message
: `获取续费信息失败`;
}
async function r(e, n) {
try {
return await e();
} catch (r) {
if (!n() || !t(r)) throw r;
return e();
}
}
export { n, e as r, r as t };
+72
View File
@@ -0,0 +1,72 @@
var e = Object.create,
t = Object.defineProperty,
n = Object.getOwnPropertyDescriptor,
r = Object.getOwnPropertyNames,
i = Object.getPrototypeOf,
a = Object.prototype.hasOwnProperty,
o = (e, t) => () => (
t ||
(e(
(t = {
exports: {},
}).exports,
t,
),
(e = null)),
t.exports
),
s = (e, n) => {
let r = {};
for (var i in e)
t(r, i, {
get: e[i],
enumerable: !0,
});
return (
n ||
t(r, Symbol.toStringTag, {
value: `Module`,
}),
r
);
},
c = (e, i, o, s) => {
if ((i && typeof i == `object`) || typeof i == `function`)
for (var c = r(i), l = 0, u = c.length, d; l < u; l++)
((d = c[l]),
!a.call(e, d) &&
d !== o &&
t(e, d, {
get: ((e) => i[e]).bind(null, d),
enumerable: !(s = n(i, d)) || s.enumerable,
}));
return e;
},
l = (n, r, o) => (
(o = n == null ? {} : e(i(n))),
c(
r || !n || !n.__esModule || !a.call(n, `default`)
? t(o, `default`, {
value: n,
enumerable: !0,
})
: o,
n,
)
),
u = ((e) =>
typeof require < `u`
? require
: typeof Proxy < `u`
? new Proxy(e, {
get: (e, t) => (typeof require < `u` ? require : e)[t],
})
: e)(function (e) {
if (typeof require < `u`) return require.apply(this, arguments);
throw Error(
'Calling `require` for "' +
e +
"\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.",
);
});
export { l as i, s as n, u as r, o as t };
+122
View File
@@ -0,0 +1,122 @@
var e = new Set(
`a.p.br.hr.div.span.h1.h2.h3.h4.h5.h6.b.strong.i.em.u.s.del.ins.sub.sup.small.mark.blockquote.pre.code.kbd.ul.ol.li.dl.dt.dd.table.thead.tbody.tfoot.tr.th.td.caption.colgroup.col.img.figure.figcaption`.split(
`.`,
),
),
t = new Set([
`script`,
`style`,
`iframe`,
`object`,
`embed`,
`link`,
`meta`,
`base`,
`form`,
`input`,
`button`,
`textarea`,
`select`,
`option`,
`template`,
`noscript`,
`noembed`,
`noframes`,
`xmp`,
`plaintext`,
`svg`,
`math`,
`audio`,
`video`,
`source`,
]);
function n(e, t = !1) {
if (!e || /[\u0000-\u001f\u007f]/.test(e)) return !1;
if (
t &&
/^data:image\/(?:png|jpeg|gif|webp|avif);base64,[a-z\d+/]+={0,2}$/i.test(e)
)
return !0;
try {
let n = new URL(e, `https://sanitizer.invalid/`).protocol;
return (
n === `https:` ||
n === `http:` ||
(!t && (n === `mailto:` || n === `tel:`))
);
} catch {
return !1;
}
}
function r(r) {
if (!r) return ``;
let i = new DOMParser().parseFromString(r, `text/html`),
a = i.createElement(`div`);
function o(r, a) {
if (r.nodeType === 3) {
a.appendChild(i.createTextNode(r.textContent ?? ``));
return;
}
if (r.nodeType !== 1) return;
let s = r,
c = s.localName;
if (s.namespaceURI !== `http://www.w3.org/1999/xhtml` || t.has(c)) return;
let l = a;
if (e.has(c)) {
let e = i.createElement(c);
for (let t of Array.from(s.attributes)) {
let r = t.name.toLowerCase(),
i = t.value.trim();
t.namespaceURI === null &&
(r === `title` || (r === `alt` && c === `img`)
? e.setAttribute(r, t.value)
: r === `style` &&
/^(p|div|h[1-6])$/.test(c) &&
/^text-align:\s*(left|center|right|justify);?$/i.test(i)
? e.setAttribute(`style`, i.toLowerCase())
: ((r === `dir` && /^(ltr|rtl|auto)$/.test(i)) ||
(r === `href` && c === `a` && n(i)) ||
(r === `src` && c === `img` && n(i, !0)) ||
(r === `target` &&
c === `a` &&
/^(?:_blank|_self)$/.test(i)) ||
(r === `scope` &&
c === `th` &&
/^(?:row|col|rowgroup|colgroup)$/.test(i)) ||
((((r === `colspan` || r === `rowspan`) &&
(c === `td` || c === `th`)) ||
((r === `width` || r === `height`) && c === `img`) ||
(r === `span` && (c === `col` || c === `colgroup`)) ||
(r === `start` && c === `ol`)) &&
/^\d{1,4}$/.test(i) &&
Number(i) > 0)) &&
e.setAttribute(r, i));
}
(c === `a` &&
e.getAttribute(`target`) === `_blank` &&
e.setAttribute(`rel`, `noopener noreferrer`),
a.appendChild(e),
(l = e));
}
for (let e of Array.from(r.childNodes)) o(e, l);
}
for (let e of Array.from(i.body.childNodes)) o(e, a);
return a.innerHTML;
}
function i(e) {
if (!e) return ``;
let t = e;
for (
let e = 0;
e < 2 && /&(?:amp|lt|gt|quot|#\d+|#x[0-9a-f]+);/i.test(t);
e++
) {
let e =
new DOMParser().parseFromString(t, `text/html`).documentElement
.textContent ?? t;
if (e === t) break;
t = e;
}
return t;
}
export { r as n, i as t };
+253
View File
@@ -0,0 +1,253 @@
var e = new Set([3997, 5174, 5226, 5227, 5631, 5914, 6243]);
function t(t) {
return t.module === `idcsmart_common` && e.has(Number(t.product_id));
}
function n(e, n, r) {
if (r !== void 0 && (!Number.isSafeInteger(r) || r <= 0))
throw Error(`服务器导航参数无效`);
let i = (e) => e.replace(/^re(?=mf_|whmcs_)/, ``),
a = new Set(n.map(i)),
o =
r !== void 0 ||
a.has(`mf_finance`) ||
a.has(`mf_finance_dcim`) ||
a.has(`idcsmart_common`),
s = [...new Set([...n, `idcsmart_common`])].join(`,`),
c = new Map(),
l = new Map(),
u = new Map(),
d = 0,
f,
p,
m = new Map();
function h(t) {
let i =
r === void 0
? {
...t,
module: s,
display_modules: n.join(`,`),
server_page: `classified-v1`,
}
: {
...t,
m: r,
},
a = JSON.stringify(i),
o = m.get(a);
if (!o) {
((o =
r === void 0
? e.get(`/host`, i)
: e.get(`/home/host`, i).then((e) => ({
...e,
server_page: `classified-v1`,
}))),
m.set(a, o));
let t = o,
n = () => {
m.get(a) === t && m.delete(a);
};
o.then(n, n);
}
return o;
}
async function g(t, n) {
let a = t.product_id || -t.id;
if (c.has(a)) return c.get(a);
if (l.has(a)) return l.get(a);
let o = e.get(`/host/${t.id}/view`).then((e) => {
if (!e.module) throw Error(`服务器分类信息加载失败,请重试`);
let t = r === void 0 ? i(e.module) : e.module;
return (n === d && c.set(a, t), t);
});
l.set(a, o);
try {
return await o;
} finally {
l.get(a) === o && l.delete(a);
}
}
async function _(n, o, c) {
let l = [],
u = {},
p = new Set(),
m = new Set();
for (let t = 1; ; t++) {
let r =
t === 1 && c
? c
: f === !1
? await e.get(`/host`, {
...n,
module: s,
page: t,
limit: 100,
})
: await h({
...n,
orderby: `id`,
page: t,
limit: 100,
}),
i = r.server_page === `classified-v1`;
(t === 1 &&
(u = {
select_field: r.select_field,
self_defined_field: r.self_defined_field,
}),
o === d && (f = i));
let a = Array.isArray(r.list) ? r.list : [],
g = 0;
for (let e of a)
(i && m.add(Number(e.id)),
p.has(Number(e.id)) ||
(p.add(Number(e.id)),
l.push({
...e,
}),
g++));
if (l.length >= Number(r.count ?? l.length)) break;
if (!a.length || !g) throw Error(`服务器列表分页未返回完整数据,请重试`);
}
let _ = [
...new Map(
l
.filter(
(e) => e.module === `idcsmart_common` && !m.has(Number(e.id)),
)
.map((e) => [e.product_id || -e.id, e]),
).values(),
],
v = 0,
y = new Map();
await Promise.all(
Array.from(
{
length: Math.min(4, _.length),
},
async () => {
for (; v < _.length;) {
let e = _[v++];
y.set(e.product_id || -e.id, await g(e, o));
}
},
),
);
for (let e of l)
e.module === `idcsmart_common` &&
!m.has(Number(e.id)) &&
(e.module = y.get(e.product_id || -e.id));
let b =
r === void 0
? l.filter((e) => (t(e) ? a.has(`mf_dcim`) : a.has(i(e.module || ``))))
: l;
if (n.orderby === `dedicate_ip` || n.orderby === `name`) {
let e = n.orderby;
b.sort(
(t, r) =>
String(t[e] || ``).localeCompare(String(r[e] || ``), `zh-CN`, {
numeric: !0,
}) * (n.sort === `asc` ? 1 : -1),
);
}
return {
...u,
list: b,
};
}
async function v(t) {
if (!o) return e.get(`/host`, t);
let n = Object.fromEntries(
Object.entries(t)
.filter(([e]) => ![`page`, `limit`, `module`].includes(e))
.sort(([e], [t]) => e.localeCompare(t)),
),
r = JSON.stringify(n),
i = d,
a;
if (f !== !1 && ![`name`, `dedicate_ip`].includes(String(t.orderby))) {
let e = {
...n,
page: Math.max(1, Number(t.page) || 1),
limit: Math.max(1, Number(t.limit) || 10),
},
o = JSON.stringify(e),
s,
c = !0;
if (f === !0) s = await h(e);
else {
(!p || p.version !== i) &&
(p = {
key: r,
pageKey: o,
version: i,
promise: h(e),
});
let t = p;
try {
s = await t.promise;
} catch (e) {
throw (p === t && (p = void 0), e);
}
((c = t.key === r),
s.server_page === `classified-v1` &&
t.pageKey !== o &&
(s = await h(e)),
p === t && (p = void 0));
}
if (s.server_page === `classified-v1`)
return (
i === d && (f = !0),
{
...s,
list: s.list.map((e) => ({
...e,
})),
}
);
(i === d && (f = !1),
c &&
Array.isArray(s.list) &&
Number(s.count) === s.list.length &&
(a = s));
}
let s = Date.now();
for (let [e, t] of u) t.expires <= s && u.delete(e);
let c = u.get(r);
if (!c) {
(u.size >= 4 && u.delete(u.keys().next().value),
(c = {
expires: 1 / 0,
promise: _(n, i, a),
}));
let e = c;
(i === d && u.set(r, e),
e.promise.then(
() => {
e.expires = Date.now() + 3e4;
},
() => {
u.get(r) === e && u.delete(r);
},
));
}
let l = await c.promise,
m = l.list,
g = Math.max(1, Number(t.limit) || 10),
v = (Math.max(1, Number(t.page) || 1) - 1) * g;
return {
...l,
list: m.slice(v, v + g).map((e) => ({
...e,
})),
count: m.length,
};
}
return Object.assign(v, {
invalidate(e = !1) {
(d++, u.clear(), m.clear(), (p = void 0), e && (c.clear(), l.clear()));
},
});
}
export { t as n, n as t };
+466
View File
@@ -0,0 +1,466 @@
import { n as product_fields_n } from "~/lib/product-fields.js";
import { t as bandwidth_display_t } from "~/lib/bandwidth-display.js";
var n = new Set([4, 7, 9, 11, 14, 15, 16, 17, 18, 19]),
r = new Set([1, 2, 6, 8, 10, 13, 20]);
function i(e) {
return typeof e == `object` && e && !Array.isArray(e) ? e : null;
}
function a(e) {
return typeof e == `string` ? e : typeof e == `number` ? String(e) : ``;
}
function o(e) {
return e === !0 || e === 1 || e === `1`;
}
function s(e) {
throw Error(`${e},请刷新重试或联系客服`);
}
function c(e, t, n = 0) {
((typeof e != `number` && typeof e != `string`) || String(e).trim() === ``) &&
s(t);
let r = Number(e);
return ((!Number.isFinite(r) || r < n) && s(t), r);
}
function l(e) {
let t = c(e, `商品配置标识无效`, 1);
return (Number.isSafeInteger(t) || s(`商品配置标识无效`), t);
}
function u(e, t = `商品配置数据不完整`) {
return (Array.isArray(e) || s(t), e);
}
function d(e) {
return (
(!e.length || new Set(e.map((e) => e.value)).size !== e.length) &&
s(`商品配置选项不完整`),
e
);
}
function f(e) {
let t = `(?:第\\s*)?(?:[一二三四五六七八九十百零〇两]+|[0-90-9]+)\\s*区`;
return e
.replace(RegExp(`[((]\\s*${t}\\s*[))]`, `g`), ``)
.replace(RegExp(t, `g`), ``)
.replace(/\s{2,}/g, ` `)
.replace(/^[\s\-—_/·]+|[\s\-—_/·]+$/g, ``)
.trim();
}
function p(e, n) {
if (n === 5) {
let t = i(e.sub);
return (
t || s(`操作系统配置不完整`),
d(
Object.entries(t).flatMap(([e, t]) =>
u(i(t)?.child).map((t) => {
let n = i(t);
return (
n || s(`操作系统配置不完整`),
{
value: l(n.id),
label: a(n.version || n.option_name).trim() || e,
group: e,
}
);
}),
),
)
);
}
return d(
n === 12
? u(e.sub).flatMap((e) => {
let t = i(e);
return (
t || s(`区域配置不完整`),
u(t.area).map((e) => {
let n = i(e);
n || s(`区域配置不完整`);
let r = [f(a(t.option_name)), f(a(n.area_zh || n.area))].filter(
Boolean,
);
return {
value: l(n.id),
label: [...new Set(r)].join(` / `) || `默认区域`,
};
})
);
})
: u(e.sub).map((e) => {
let n = i(e);
n || s(`商品配置选项不完整`);
let r = l(n.id);
return {
value: r,
label: bandwidth_display_t(a(n.option_name).trim()) || String(r),
};
}),
);
}
function m(e) {
let t = i(e);
t || s(`商品配置数据不完整`);
let o = c(t.option_type, `商品配置类型无效`);
!r.has(o) &&
!n.has(o) &&
![3, 5, 12].includes(o) &&
s(`该商品配置类型暂不支持`);
let d = {
id: String(l(t.id)),
label: a(t.option_name).trim() || `配置选项`,
kind:
o === 20
? `cascade`
: o === 3
? `boolean`
: o === 5
? `os`
: n.has(o)
? `quantity`
: `choice`,
choices: [],
min: 0,
max: 0,
step: 1,
unit: a(t.unit) || (o === 14 ? `GB` : ``),
description: a(t.notes),
};
if (d.kind === `boolean`)
return (
(d.max = 1),
(d.choices = [
{
value: 0,
label: `否`,
},
{
value: 1,
label: `是`,
},
]),
d
);
if (d.kind !== `quantity`) return ((d.choices = p(t, o)), d);
if (
((d.min = c(t.qty_minimum, `商品数量配置无效`)),
(d.max = c(t.qty_maximum, `商品数量配置无效`, d.min)),
d.max === 0)
)
return null;
d.step =
t.qty_stage === void 0 || t.qty_stage === null || t.qty_stage === ``
? 1
: c(t.qty_stage, `商品数量步长配置无效`, Number.MIN_VALUE);
let f = u(t.sub)
.map((e) => {
let t = i(e);
t || s(`商品数量范围配置无效`);
let n = Math.max(d.min, c(t.qty_minimum, `商品数量范围配置无效`)),
r = Math.min(d.max, c(t.qty_maximum, `商品数量范围配置无效`));
return r < n
? null
: {
min: n,
max: r,
step: d.step,
};
})
.filter((e) => e !== null);
return (
(!f.length || !f.some((e) => e.min === d.min)) &&
s(`商品数量范围配置不完整`),
(d.ranges = f),
d
);
}
function h(e, t) {
let n = i(e);
return {
show: o(n?.show),
editable: o(n?.modify),
value: a(n?.[t]),
};
}
function g(t) {
if (t == null) return [];
let n = u(t, `自定义字段配置不完整`).map((t) => {
let n = i(t);
n || s(`自定义字段配置不完整`);
let r = {
text: `text`,
password: `password`,
textarea: `textarea`,
dropdown: `select`,
tickbox: `boolean`,
checkbox: `boolean`,
link: `link`,
explain: `explain`,
}[a(n.field_type)];
r || s(`该商品自定义字段类型暂不支持`);
let c = product_fields_n(n.regexpr),
u = [];
if (r === `select`) {
let e =
typeof n.field_option == `string`
? n.field_option.split(`,`)
: Array.isArray(n.field_option) &&
n.field_option.every((e) => typeof e == `string`)
? n.field_option
: [];
((u = [...new Set(e.map((e) => e.trim()).filter(Boolean))].map((e) => ({
value: e,
label: e,
}))),
u.length || s(`自定义字段选项不完整`));
}
return {
id: String(l(n.id)),
label: a(n.field_name).trim() || `自定义字段`,
kind: r,
required: o(n.is_required),
...c,
explain: a(n.explain_content),
options: u,
description: a(n.description),
};
});
return (
new Set(n.map((e) => e.id)).size !== n.length && s(`自定义字段标识重复`),
n
);
}
function _(e) {
let t = i(e),
n = i(t?.product) ? t : i(t?.data),
r = i(n?.product);
((!n || !r || (n.status !== void 0 && Number(n.status) !== 200)) &&
s(`商品配置数据不完整`),
n.links !== void 0 &&
n.links !== null &&
!Array.isArray(n.links) &&
s(`商品联动配置数据不完整`));
let l = u(n.option)
.map(m)
.filter((e) => e !== null);
new Set(l.map((e) => e.id)).size !== l.length && s(`商品配置标识重复`);
let d = u(r.cycle, `商品周期配置不完整`).map((e) => {
let t = i(e),
n = a(t?.billingcycle).trim();
return (
n || s(`商品周期配置不完整`),
{
value: n,
label: a(t?.billingcycle_zh).trim() || n,
}
);
});
(!d.length || new Set(d.map((e) => e.value)).size !== d.length) &&
s(`商品周期配置不完整`);
let f = o(r.stock_control) ? c(r.qty, `商品库存配置无效`) : null;
return (
f !== null && !Number.isSafeInteger(f) && s(`商品库存配置无效`),
{
options: l,
cycles: d,
allowQty: o(n.allow_qty ?? r.allow_qty),
stock: f,
hostname: h(r.host, `host`),
password: h(r.password, `password`),
customFields: g(n.custom_fields),
links: v(n.links ?? [], l),
linkDefinitions: JSON.parse(JSON.stringify(n.links ?? [])),
}
);
}
function v(e, t) {
let n = new Map(t.map((e) => [e.id, e]));
function r(e) {
let t = i(e),
r = String(l(t?.config_id)),
o = n.get(r);
(!o || ![`seq`, `sneq`].includes(a(t?.relation))) &&
s(`商品联动配置数据不完整`);
let u = i(t?.sub_id);
(!u || !Object.keys(u).length) && s(`商品联动选项不完整`);
let d =
o.kind === `quantity`
? Object.values(u).map((e) => {
let t = i(e),
n = c(t?.qty_minimum, `商品联动数量范围无效`);
return {
min: n,
max: c(t?.qty_maximum, `商品联动数量范围无效`, n),
};
})
: [],
f = [];
if (o.kind !== `quantity`)
for (let e of Object.keys(u)) {
if (!/^\d+$/.test(e)) return null;
let t = Number(e);
if (
!Number.isSafeInteger(t) ||
(o.kind === `cascade` && t <= 0) ||
!o.choices.some((e) => e.value === t)
)
return null;
f.push(t);
}
return {
optionId: r,
relation: t.relation,
values: f,
ranges: d,
};
}
return u(e).flatMap((e) => {
let t = i(e);
if ((t || s(`商品联动配置数据不完整`), !n.has(String(t.config_id))))
return [];
let a = r(t);
if (!a) return [];
let o = u(t.result, `商品联动结果不完整`);
o.length || s(`商品联动结果不完整`);
let c = o.filter((e) => n.has(String(i(e)?.config_id)));
if (!c.length) return [];
let l = c.map(r);
return l.some((e) => e === null)
? []
: [
{
...a,
results: l,
},
];
});
}
function y(e, t) {
let n =
e.values.includes(t) ||
e.ranges.some((e) => t !== void 0 && t >= e.min && t <= e.max);
return e.relation === `seq` ? n : !n;
}
function b(e, t, n) {
let r = t.filter((e) => y(e, n[e.optionId])).flatMap((e) => e.results);
return e.map((e) => {
let t = r.filter((t) => t.optionId === e.id);
if (!t.length) return e;
if (e.kind !== `quantity`)
return {
...e,
choices: e.choices.filter((e) => t.every((t) => y(t, e.value))),
};
let n = e.ranges ?? [
{
min: e.min,
max: e.max,
step: e.step,
},
];
for (let e of t) {
let t = [];
for (let r of n) {
let n = [
...new Set([
0,
Math.floor((r.max - r.min) / r.step + 1e-7) + 1,
...e.ranges.flatMap((e) => [
Math.max(0, Math.ceil((e.min - r.min) / r.step - 1e-7)),
Math.floor((e.max - r.min) / r.step + 1e-7) + 1,
]),
]),
]
.filter(
(e) =>
e >= 0 && e <= Math.floor((r.max - r.min) / r.step + 1e-7) + 1,
)
.sort((e, t) => e - t);
for (let i = 0; i < n.length - 1; i++) {
let a = Number((r.min + n[i] * r.step).toFixed(8)),
o = Number((r.min + (n[i + 1] - 1) * r.step).toFixed(8));
o >= a &&
y(e, a) &&
t.push({
min: a,
max: o,
step: r.step,
});
}
}
n = t;
}
return {
...e,
ranges: n,
min: n[0]?.min ?? 0,
max: n.at(-1)?.max ?? -1,
};
});
}
function x(e, t) {
let n = u(
i(u(e, `商品级联配置数据不完整`)[0])?.son,
`商品级联配置数据不完整`,
),
r = {};
return {
options: n.map((e) => {
let n = i(e);
n || s(`商品级联配置数据不完整`);
let a = m({
...n,
option_type: 20,
});
(a.id === t || r[a.id] !== void 0) && s(`商品级联配置标识重复`);
let o = l(n.checkSubId);
return (
a.choices.some((e) => e.value === o) || s(`商品级联默认配置无效`),
(r[a.id] = o),
{
...a,
cascadeRoot: t,
}
);
}),
values: r,
};
}
function S(e) {
let t = /^([kmgtpe])(?:i?b)?$|^(b)$/i.exec(e.trim());
return t
? t[2]
? `B`
: `${t[1].toUpperCase()}${/ib$/i.test(e.trim()) ? `iB` : `B`}`
: ``;
}
function C(e, t = ``) {
let n = e.normalize(`NFKC`).trim();
if (!n || /[×*¥¥$€]|(?:^|[\s([{])[-+]\s*\d/.test(n)) return null;
let r = [...n.matchAll(/\d+(?:\.\d+)?\s*(?:[kmgtpe](?:i?b)?|b)(?![a-z])/gi)],
i = r[0],
a = ``;
if (r.length === 1) a = S(/[a-z]+$/i.exec(i[0])?.[0] ?? ``);
else if (r.length === 0 && S(t)) {
let e = [...n.matchAll(/\d+(?:\.\d+)?/g)];
if (e.length !== 1) return null;
((i = e[0]), (a = S(t)));
} else return null;
if (!i || !a) return null;
let o = Number(/^\d+(?:\.\d+)?/.exec(i[0])?.[0]);
if (!Number.isFinite(o)) return null;
let s = n.slice(0, i.index) + n.slice(i.index + i[0].length),
c = [...s.matchAll(/NVMe|SSD|HDD|SAS|SATA/gi)].map((e) =>
e[0].toUpperCase() === `NVME` ? `NVMe` : e[0].toUpperCase(),
);
return s
.replace(
/NVMe|SSD|HDD|SAS|SATA|免费赠送|免费|赠送|系统盘|数据盘|云硬盘|云磁盘|云盘|硬盘|磁盘|存储|容量|高性能|高效|普通|标准|通用型|性能型|弹性|本地/gi,
``,
)
.replace(/[\s()[\]{}::·]/g, ``)
? null
: {
size: o,
unit: a,
type: [...new Set(c)].join(` `),
};
}
export { _ as a, v as i, b as n, x as r, C as t };
+86
View File
@@ -0,0 +1,86 @@
function e(e) {
if (
!/^(?:https?:\/\/|\/(?!\/)|\.\.?\/)/i.test(e) ||
/[\u0000-\u001f\u007f\\]/.test(e)
)
return !1;
try {
let t = new URL(e, `https://attachment.invalid/`);
return t.protocol === `http:` || t.protocol === `https:`;
} catch {
return !1;
}
}
function t(t) {
return (
!!t.href &&
e(t.href) &&
/\.(?:avif|bmp|gif|ico|jpe?g|png|webp)$/i.test(t.name)
);
}
function n(e, t) {
let n =
e
.split(`/`)
.at(-1)
?.split(/\^|%5e/i)
.at(-1) || t;
try {
n = decodeURIComponent(n);
} catch {}
return n.split(`^`).at(-1) || t;
}
function r(t) {
return Array.isArray(t)
? t.map((t, r) => {
let i = `附件 ${r + 1}`,
a = t && typeof t == `object` && !Array.isArray(t) ? t : null;
if (
typeof t != `string` &&
(!a ||
![`url`, `name`, `save_name`].some((e) => typeof a[e] == `string`))
)
return {
name: `${i}(格式暂不支持)`,
href: null,
};
let o = typeof t == `string` ? t : a?.url,
s = typeof o == `string` ? o.trim() : ``,
c = typeof a?.name == `string` ? a.name.trim() : ``,
l = typeof a?.save_name == `string` ? a.save_name.trim() : ``,
u = c || (l ? n(l, i) : ``),
d =
l ||
(typeof o == `string` && !e(o) && !/[\\/:\u0000-\u001f]/.test(o)
? o
: ``),
f = {
name: u || (d ? n(d, i) : `${i}(地址不可用)`),
href: null,
...(d
? {
storageName: d,
}
: {}),
};
if (!e(s)) return f;
try {
let e = new URL(s, `https://attachment.invalid/`);
return e.protocol !== `http:` && e.protocol !== `https:`
? f
: {
name: u || n(e.pathname, i),
href: s,
...(d
? {
storageName: d,
}
: {}),
};
} catch {
return f;
}
})
: [];
}
export { r as n, t };
+202
View File
@@ -0,0 +1,202 @@
import { onMounted } from "vue";
import { watch } from "vue";
import { onScopeDispose } from "vue";
import { ref } from "vue";
import { ApiError } from "~/lib/auth.js";
import { useApi } from "~/lib/auth.js";
import { t as useSiteConfig_t } from "~/lib/useSiteConfig.js";
var s = (e) => e === !0 || e === 1 || e === `1`;
function c(e, t) {
return s(e?.[`captcha_client_${t}`])
? !0
: t === `login` &&
s(e?.captcha_client_login_error) &&
s(e?.captcha_client_login_error_3_times);
}
function l(e) {
if (typeof e != `string` || e.length > 262144) throw Error(`验证码响应无效`);
let t = new DOMParser().parseFromString(e, `text/html`),
n = t.querySelector(`[data-captcha-provider]`);
if (n) {
let e = n.getAttribute(`data-captcha-id`) ?? ``;
if (
n.getAttribute(`data-captcha-provider`) !== `geetest` ||
!/^[a-f0-9]{32}$/i.test(e)
)
throw Error(`验证码服务尚未配置完成,请联系管理员`);
return {
provider: `geetest`,
captchaId: e,
};
}
if (
e.includes(`/captcha/tp_captcha/index/refresh`) &&
t.querySelector(`#captcha-img`)
)
return {
provider: `image`,
captchaId: ``,
};
throw Error(`当前验证码插件暂不受支持,请联系管理员`);
}
function u(e) {
if (!e || typeof e != `object`) return !1;
let t = e;
return [`lot_number`, `captcha_output`, `pass_token`, `gen_time`].every(
(e) =>
typeof t[e] == `string` && t[e].trim().length > 0 && t[e].length <= 8192,
);
}
function d(d) {
let f = useSiteConfig_t(),
p = useApi(),
m = ref(!1),
h = ref(`image`),
g = ref(``),
_ = ref(``),
v = ref(``),
y = ref(``),
b = ref(!1),
x = ref(``),
S = ref(!(!d || f.config.value)),
C = !1,
w = 0,
T = null,
E = !1;
function D() {
((y.value = ``), (v.value = ``));
}
async function O() {
if (C || b.value) return;
let e = ++w;
((b.value = !0),
(x.value = ``),
D(),
(_.value = ``),
(g.value = ``),
(T = new AbortController()));
let t = T,
n = setTimeout(() => t.abort(), 1e4);
try {
let n = await p.get(`/captcha`, void 0, !1, {
timeoutMs: 1e4,
});
if (C || e !== w) return;
let r = l(n.html);
if (
((h.value = r.provider),
(g.value = r.captchaId),
r.provider === `geetest`)
)
return;
let i = await fetch(`/captcha/tp_captcha/index/refresh`, {
headers: {
Accept: `application/json`,
},
signal: t.signal,
cache: `no-store`,
}),
a = await i.json();
if (C || e !== w) return;
if (
!i.ok ||
typeof a?.base64 != `string` ||
!/^data:image\/(?:png|jpeg|gif|webp);base64,/.test(a.base64) ||
typeof a?.token != `string` ||
!a.token
)
throw Error(`验证码加载失败`);
((_.value = a.base64), (v.value = a.token));
} catch (t) {
if (C || e !== w) return;
x.value =
t instanceof Error && /验证码.*(?:配置|支持)/.test(t.message)
? t.message
: `验证码加载失败,请点击重新加载`;
} finally {
(clearTimeout(n), !C && e === w && (b.value = !1));
}
}
function k(e) {
(D(),
!C &&
m.value &&
h.value === `geetest` &&
!b.value &&
u(e) &&
((y.value = JSON.stringify({
lot_number: e.lot_number,
captcha_output: e.captcha_output,
pass_token: e.pass_token,
gen_time: e.gen_time,
})),
(v.value = e.lot_number)));
}
function A() {
return S.value
? `验证码设置正在加载,请稍候`
: d && !f.config.value
? `验证码设置加载失败,请刷新页面重试`
: m.value
? b.value
? `验证码正在加载,请稍候`
: x.value
? x.value
: h.value === `geetest`
? v.value && y.value
? ``
: `请先完成人机验证`
: v.value
? y.value.trim()
? ``
: `请输入图形验证码`
: `请先重新加载图形验证码`
: ``;
}
async function j(e) {
let t = e instanceof ApiError && s(e.data?.captcha);
return (t && ((E = !0), (m.value = !0)), m.value && (await O()), t);
}
return (
d &&
(watch(
() => c(f.config.value, d),
(e) => {
((m.value = E || e),
m.value
? O()
: ((w += 1), T?.abort(), (b.value = !1), (x.value = ``), D()));
},
{
immediate: !0,
},
),
onMounted(async () => {
(await f.load(),
!C &&
((S.value = !1),
f.config.value ||
(x.value = `验证码设置加载失败,请刷新页面重试`)));
})),
onScopeDispose(() => {
((C = !0), (w += 1), T?.abort(), D());
}),
{
needed: m,
provider: h,
captchaId: g,
img: _,
token: v,
value: y,
loading: b,
error: x,
configLoading: S,
load: O,
complete: k,
invalidate: D,
validationError: A,
handleError: j,
}
);
}
export { d as t };
+176
View File
@@ -0,0 +1,176 @@
import { onMounted } from "vue";
import { watch } from "vue";
import { onScopeDispose } from "vue";
import { ref } from "vue";
import { apiCacheKey } from "~/lib/auth.js";
import { apiCacheVersion } from "~/lib/auth.js";
import { useApi } from "~/lib/auth.js";
import { writeApiCache } from "~/lib/auth.js";
import { readApiCache } from "~/lib/auth.js";
import { clearApiCache } from "~/lib/auth.js";
function u(u, d = {}) {
let f = useApi(),
p =
d.identity ??
(typeof f.identity == `function` ? () => f.identity() : void 0),
m = d.retainOnRefreshError !== !1,
h = ref([]),
g = ref(0),
_ = ref(!1),
v = ref(``),
y = ref(!1),
b = ref(1),
x = ref(d.limit ?? 10),
S = 0,
C = ``,
w = !0,
T = !1,
E = null;
function D() {
(S++,
(h.value = []),
(g.value = 0),
(_.value = !1),
(v.value = ``),
(y.value = !1),
(C = ``),
(E = null),
(w = !1));
}
(p &&
watch(
p,
() => {
(clearApiCache(), D());
},
{
flush: `sync`,
},
),
onScopeDispose(() => {
((T = !0), S++, (E = null));
}));
function O(e) {
if (d.rowKey) return d.rowKey(e);
if (
e &&
typeof e == `object` &&
`id` in e &&
(typeof e.id == `string` || typeof e.id == `number`)
)
return e.id;
}
function k() {
if (T) return Promise.resolve();
let e,
t,
n = p?.();
try {
((e = {
page: b.value,
limit: x.value,
...(d.params?.() ?? {}),
}),
(t = apiCacheKey(
u,
e,
typeof d.snapshotKey == `function` ? d.snapshotKey() : d.snapshotKey,
)));
} catch (e) {
return (
D(),
(v.value = e instanceof Error ? e.message : `查询条件无效`),
Promise.resolve()
);
}
if (E?.query === t && E.identity === n) return E.promise;
let r = ++S,
o = () => !T && r === S && (!p || p() === n);
((_.value = !0), (v.value = ``));
let l = y.value && t === C,
k = p ? readApiCache(n, t) : void 0,
A = apiCacheVersion();
(l || ((h.value = []), (g.value = 0), (y.value = !1)),
w &&
k &&
((h.value = k.list),
(g.value = k.count),
(y.value = !0),
(C = t),
(l = !0)),
(w = !1));
let j = (async () => {
try {
let r = d.loader ? await d.loader(e) : await f.get(u, e);
if (!o()) return;
let i = new Map(
h.value.flatMap((e) => {
let t = O(e);
return t === void 0 ? [] : [[t, e]];
}),
);
((h.value = (r.list ?? []).map((e) => {
let t = O(e),
n = t === void 0 ? void 0 : i.get(t);
if (!n || typeof n != `object` || typeof e != `object` || !e)
return e;
let r = n;
for (let t of Object.keys(r))
Object.prototype.hasOwnProperty.call(e, t) || delete r[t];
return (Object.assign(r, e), n);
})),
(g.value = r.count ?? 0),
(y.value = !0),
(C = t),
p &&
writeApiCache(
n,
t,
{
list: h.value,
count: g.value,
},
A,
));
} catch (e) {
if (!o()) return;
((v.value = e instanceof Error ? e.message : `加载失败`),
(!m || !l) && ((h.value = []), (g.value = 0), (y.value = !1)));
} finally {
(o() && (_.value = !1), r === S && (E = null));
}
})();
return (
o() &&
_.value &&
(E = {
query: t,
identity: n,
promise: j,
}),
j
);
}
function A(e) {
((b.value = e.page + 1), (x.value = e.rows), k());
}
function j() {
((b.value = 1), k());
}
return (
d.immediate !== !1 && onMounted(k),
{
list: h,
total: g,
loading: _,
error: v,
hasResult: y,
page: b,
limit: x,
load: k,
onPage: A,
reload: j,
}
);
}
export { u as t };
+48
View File
@@ -0,0 +1,48 @@
import { watch } from "vue";
import { useState } from "#app";
import { useApi } from "~/lib/auth.js";
import { useAuth } from "~/lib/auth.js";
function i() {
let i = useState(`mail-unread-count`, () => 0),
a = useState(`mail-recent`, () => []),
o = useState(`mail-types`, () => []),
s = useState(`mail-session`, () => null),
c = useState(`mail-request-id`, () => 0),
l = useAuth(),
u = useApi();
watch(
() => l.token,
(e) => {
s.value !== e &&
((s.value = e),
(c.value += 1),
(i.value = 0),
(a.value = []),
(o.value = []));
},
{
immediate: !0,
flush: `sync`,
},
);
async function d() {
if (!l.token) return;
let e = l.token,
t = ++c.value;
try {
let n = await u.get(`/client_care/mail`);
if (e !== l.token || t !== c.value) return;
let r = n?.credit_limit;
((i.value = Number(r?.count ?? 0)),
(a.value = r?.list ?? []),
(o.value = r?.type ?? []));
} catch {}
}
return {
count: i,
recent: a,
types: o,
refresh: d,
};
}
export { i as t };
+42
View File
@@ -0,0 +1,42 @@
import { onBeforeUnmount } from "vue";
import { ref } from "vue";
import { useApi } from "~/lib/auth.js";
import { r as oauth_r } from "~/lib/oauth.js";
function i() {
let i = useApi(),
a = ref(!1),
o = ref(``),
s = !0;
onBeforeUnmount(() => {
s = !1;
});
async function c(e) {
if (s && !a.value) {
if (((o.value = ``), !/^[a-z][a-z0-9_]*$/i.test(e))) {
o.value = `授权方式无效`;
return;
}
a.value = !0;
try {
let t = await i.get(`/oauth/${encodeURIComponent(e)}`);
if (!s) return;
let n = oauth_r(t?.url, window.location.origin);
if (!n) throw Error(`授权地址无效,请联系支持`);
try {
sessionStorage.setItem(`console-oauth-pending`, `1`);
} catch {}
window.location.assign(n);
} catch (e) {
s && (o.value = e instanceof Error ? e.message : `授权失败`);
} finally {
s && (a.value = !1);
}
}
}
return {
busy: a,
error: o,
start: c,
};
}
export { i as t };
+417
View File
@@ -0,0 +1,417 @@
import { useState } from "#app";
import { useApi } from "~/lib/auth.js";
var n = {
meta: {
title: `破碎工坊网络 - 云计算与基础设施服务`,
description: `为开发者与企业提供云服务器、物理服务器、机柜托管与网络资源。`,
},
theme: {
primary: `#0052d9`,
accent: `#eff6ff`,
},
brand: {
name: `破碎工坊网络`,
tagline: `云计算与基础设施服务`,
logoUrl: ``,
},
header: {
navigation: [
{
label: `产品服务`,
href: `#products`,
is_show: !0,
},
{
label: `订购产品`,
href: `/cart`,
is_show: !0,
},
{
label: `基础设施`,
href: `#infrastructure`,
is_show: !0,
},
{
label: `客户评价`,
href: `#reviews`,
is_show: !0,
},
{
label: `联系我们`,
href: `#contact`,
is_show: !0,
},
],
buttonLabel: `进入客户中心`,
buttonHref: `/login`,
},
hero: {
tag: `面向开发者与企业用户`,
title: `让每一份算力,
都稳定生长。`,
subtitle: `灵活的云基础设施服务`,
description: `从云服务器到专属物理资源,按业务阶段灵活选择,让部署、扩展与日常管理更简单。`,
features: [
{
text: `按需配置`,
is_show: !0,
},
{
text: `弹性扩展`,
is_show: !0,
},
{
text: `统一管理`,
is_show: !0,
},
],
buttonLabel: `浏览产品服务`,
buttonHref: `/login?redirect=%2Fproducts`,
secondaryLabel: `了解基础设施`,
secondaryHref: `#infrastructure`,
metric: {
value: `云 · 物 · 柜`,
unit: ``,
title: `多类型资源`,
label: `从轻量部署到专属算力`,
description: `云服务器、物理服务器与机柜托管,可按需选择。`,
},
floatingText: `灵活部署 · 简单管理`,
artCaption: `为业务构建可靠的运行基础`,
},
sectionOrder: [`products`, `infrastructure`, `reviews`, `contact`],
products: {
is_show: !0,
eyebrow: `产品与服务`,
title: `为不同阶段准备合适的资源`,
description: `从快速上线到专属部署,选择适合当前业务的产品方案。`,
badges: [
{
label: `配置清晰`,
is_show: !0,
},
{
label: `按需选择`,
is_show: !0,
},
{
label: `统一管理`,
is_show: !0,
},
],
items: [
{
title: `云服务器`,
subtitle: `CLOUD SERVER`,
icon: `lucide:cloud`,
price: `按需选配`,
period: `查看方案`,
description: `灵活部署,随业务变化扩展计算资源。`,
features: [
{
label: `多种配置可选`,
is_show: !0,
},
{
label: `支持弹性升级`,
is_show: !0,
},
{
label: `控制台统一管理`,
is_show: !0,
},
],
buttonLabel: `查看云服务器`,
href: `/login?redirect=%2Fcloud-servers`,
is_show: !0,
},
{
title: `物理服务器`,
subtitle: `DEDICATED SERVER`,
icon: `lucide:server`,
price: `专属算力`,
period: `查看方案`,
description: `独享硬件资源,适合稳定运行的核心业务。`,
features: [
{
label: `独享物理资源`,
is_show: !0,
},
{
label: `可选多种规格`,
is_show: !0,
},
{
label: `实例状态可视`,
is_show: !0,
},
],
buttonLabel: `查看物理服务器`,
href: `/login?redirect=%2Fdedicated-servers`,
is_show: !0,
},
{
title: `机柜托管`,
subtitle: `CABINET COLOCATION`,
icon: `lucide:network`,
price: `按需咨询`,
period: `了解服务`,
description: `为自有设备提供机房空间与网络接入方案。`,
features: [
{
label: `机房资源托管`,
is_show: !0,
},
{
label: `网络接入可选`,
is_show: !0,
},
{
label: `服务信息可查询`,
is_show: !0,
},
],
buttonLabel: `了解机柜托管`,
href: `/login?redirect=%2Fcolocations`,
is_show: !0,
},
],
},
infrastructure: {
is_show: !0,
eyebrow: `基础设施`,
title: `让资源状态一目了然`,
description: `通过统一的客户中心管理实例、订单与服务信息,减少日常运维中的重复操作。`,
visualLabel: `RESOURCE OVERVIEW`,
visualCaption: `基础设施服务概览`,
stats: [
{
value: `多类型`,
unit: ``,
label: `资源形态`,
is_show: !0,
},
{
value: `按需`,
unit: ``,
label: `配置选择`,
is_show: !0,
},
{
value: `统一`,
unit: ``,
label: `控制入口`,
is_show: !0,
},
],
nodeTitle: `服务资源`,
nodeSubtitle: `按业务需要灵活组合`,
nodes: [
{
label: `云服务器`,
value: `弹性计算`,
progress: 78,
is_show: !0,
},
{
label: `物理服务器`,
value: `专属资源`,
progress: 64,
is_show: !0,
},
{
label: `机柜托管`,
value: `设备接入`,
progress: 52,
is_show: !0,
},
],
},
reviews: {
is_show: !1,
eyebrow: `客户声音`,
title: `真实体验,值得持续打磨`,
description: `在这里展示经授权发布的客户评价。`,
items: [
{
quote: `请填写获得客户授权的真实评价。`,
author: `客户姓名`,
company: `公司或项目名称`,
avatar: ``,
rating: 5,
is_show: !1,
},
],
},
contact: {
is_show: !0,
eyebrow: `开始使用`,
title: `为你的下一个项目选好基础设施`,
description: `浏览可用产品方案,或进入客户中心配置服务、管理实例与订单。`,
buttonLabel: `前往产品目录`,
buttonHref: `/login?redirect=%2Fproducts`,
secondaryLabel: `登录客户中心`,
secondaryHref: `/login`,
},
footer: {
linkGroups: [
{
title: `产品服务`,
is_show: !0,
links: [
{
label: `云服务器`,
href: `/login?redirect=%2Fcloud-servers`,
is_show: !0,
},
{
label: `物理服务器`,
href: `/login?redirect=%2Fdedicated-servers`,
is_show: !0,
},
{
label: `机柜托管`,
href: `/login?redirect=%2Fcolocations`,
is_show: !0,
},
],
},
{
title: `服务支持`,
is_show: !0,
links: [
{
label: `帮助中心`,
href: `/login?redirect=%2Fhelp`,
is_show: !0,
},
{
label: `服务公告`,
href: `/login?redirect=%2Fnotices`,
is_show: !0,
},
{
label: `新闻资讯`,
href: `/login?redirect=%2Fnews`,
is_show: !0,
},
],
},
],
contactTitle: `联系我们`,
phone: ``,
email: ``,
address: ``,
qrImage: ``,
qrCaption: `扫码关注`,
copyright: `© 破碎工坊网络`,
registrations: [
{
label: `ICP备案`,
number: ``,
href: ``,
is_show: !0,
},
{
label: `网安备案`,
number: ``,
href: ``,
is_show: !0,
},
{
label: `增值电信业务经营许可证`,
number: ``,
href: ``,
is_show: !0,
},
],
legalLinks: [
{
label: `服务条款`,
href: ``,
is_show: !1,
},
{
label: `隐私政策`,
href: ``,
is_show: !1,
},
],
},
};
function r(e) {
return typeof e == `object` && !!e && !Array.isArray(e);
}
function i(e, t) {
if (Array.isArray(e)) return Array.isArray(t) ? t : e;
if (!r(e)) return t === void 0 ? e : t;
let n = r(t) ? t : {},
a = {
...e,
};
for (let [t, r] of Object.entries(n)) a[t] = t in e ? i(e[t], r) : r;
return a;
}
function a() {
return JSON.parse(JSON.stringify(n));
}
function o(e) {
return i(n, e);
}
function s(e) {
if (typeof e != `string`) return `#`;
let t = e.trim();
return !t || /[\u0000-\u001f\\]/.test(t)
? `#`
: /^(https?:\/\/|mailto:|tel:|#|\/(?!\/))/i.test(t)
? t
: `#`;
}
function c(e) {
if (typeof e != `string`) return ``;
let t = e.trim();
return !t || /[\u0000-\u001f\\]/.test(t)
? ``
: /^(https?:\/\/|\/(?!\/))/i.test(t)
? t
: ``;
}
function l(e, t) {
return typeof e == `string` && /^#[0-9a-fA-F]{6}$/.test(e) ? e : t;
}
var u = null;
function d() {
let n = useState(`official-site-content`, a),
r = useState(`official-site-content-loaded`, () => !1),
i = useState(`official-site-content-error`, () => ``);
async function s(e = !1) {
return r.value && !e
? n.value
: ((!u || e) &&
((i.value = ``),
(u = useApi()
.get(`/official_site_cms/content`, void 0, !1, {
timeoutMs: 8e3,
})
.then((e) => {
(e?.content && (n.value = o(e.content)), (r.value = !0));
})
.catch((e) => {
((r.value = !0),
(i.value =
e instanceof Error ? e.message : `官网内容暂时无法同步`));
})
.finally(() => {
u = null;
}))),
await u,
n.value);
}
return {
content: n,
loaded: r,
error: i,
load: s,
};
}
export { c as i, l as n, s as r, d as t };
+47
View File
@@ -0,0 +1,47 @@
import { ref } from "vue";
import { computed } from "vue";
import { useState } from "#app";
import { useApi } from "~/lib/auth.js";
var i = null;
function a() {
let a = useState(`site-config`, () => null),
o = ref(``);
async function s() {
if (((o.value = ``), a.value)) return a.value;
i ||= useApi()
.get(`/common`, void 0, !1, {
timeoutMs: 1e4,
})
.then((e) => ((a.value = e), e))
.catch((e) => {
throw ((i = null), e);
});
try {
return await i;
} catch (e) {
return (
(o.value = e instanceof Error ? e.message : `加载站点配置失败`),
null
);
}
}
let c = (e) => e === 1 || e === `1` || e === !0;
return {
config: a,
error: o,
load: s,
on: c,
maintenance: computed(() => c(a.value?.maintenance_mode)),
rechargeClosed: computed(
() => a.value != null && !c(a.value.recharge_open),
),
lockedFields: computed(
() => a.value?.prohibit_user_information_changes ?? [],
),
siteName: computed(() => a.value?.website_name || `破碎工坊云`),
scanLoginEnabled: computed(() =>
c(a.value?.plugin_configuration?.mp_weixin_notice?.scan_login),
),
};
}
export { a as t };
+73
View File
@@ -0,0 +1,73 @@
import { computed } from "vue";
import { useState } from "#app";
function n(e) {
try {
let t = (e ?? globalThis.localStorage)?.getItem(`theme`);
if (t === `light` || t === `dark`) return t;
} catch {}
return `auto`;
}
var r = [`light`, `dark`, `auto`],
i = {
light: `浅色`,
dark: `深色`,
auto: `跟随系统`,
},
a = {
light: `pi pi-sun`,
dark: `pi pi-moon`,
auto: `pi pi-desktop`,
},
o = `theme`;
function s() {
let s = useState(`theme-mode`, () => n()),
c = useState(
`theme-dark`,
() =>
typeof document < `u` &&
document.documentElement.classList.contains(`app-dark`),
),
l = () => window.matchMedia(`(prefers-color-scheme: dark)`);
function u() {
c.value = s.value === `dark` || (s.value === `auto` && l().matches);
}
function d() {
let e = document.documentElement;
(e.classList.toggle(`app-dark`, c.value),
(e.style.colorScheme = c.value ? `dark` : `light`));
}
function f() {
(u(), d());
}
let p = null,
m = () => {
s.value === `auto` && f();
};
function h() {
(p?.removeEventListener(`change`, m), (p = null));
}
function g() {
(h(), (s.value = n()), f(), (p = l()), p.addEventListener(`change`, m));
}
function _(e) {
s.value = e;
try {
localStorage.setItem(o, e);
} catch {}
f();
}
function v() {
_(r[(r.indexOf(s.value) + 1) % r.length]);
}
return {
mode: s,
isDark: c,
init: g,
dispose: h,
set: _,
cycle: v,
label: computed(() => i[s.value]),
icon: computed(() => a[s.value]),
};
}
export { s as t };
+83
View File
@@ -0,0 +1,83 @@
import { onScopeDispose } from "vue";
import { ref } from "vue";
import { useApi } from "~/lib/auth.js";
import { t as interval_t } from "~/lib/interval.js";
function i(i) {
let a = useApi(),
o = ref(!1),
s = ref(0),
c = null,
l = !1;
function u() {
c &&= (clearInterval(c), null);
}
function d() {
l ||
(u(),
(s.value = i.seconds ?? 60),
(c = interval_t(() => {
(--s.value, s.value <= 0 && u());
}, 1e3)));
}
onScopeDispose(() => {
((l = !0), u());
});
async function f(e, t, n) {
if (l || o.value || s.value > 0) return;
if (((i.error.value = ``), !t)) {
i.error.value = n;
return;
}
let r = i.captcha.validationError();
if (r) {
i.error.value = r;
return;
}
o.value = !0;
try {
let n = {
action: i.action,
captcha: i.captcha.value.value.trim(),
token: i.captcha.token.value,
};
if (e === `email`)
await a.post(`/email/code`, {
...n,
email: t,
});
else {
let e = String(
typeof i.phoneCode == `function`
? i.phoneCode()
: (i.phoneCode ?? 86),
).trim();
if (!/^[1-9]\d{0,3}$/.test(e)) throw Error(`请输入有效的国际电话区号`);
await a.post(`/phone/code`, {
...n,
phone_code: Number(e),
phone: t,
});
}
(d(),
!l &&
i.captcha.needed.value &&
(i.captcha.provider.value === `geetest`
? i.captcha.invalidate()
: i.captcha.load()));
} catch (e) {
if (l) return;
((i.error.value = e instanceof Error ? e.message : `验证码发送失败`),
await i.captcha.handleError(e));
} finally {
o.value = !1;
}
}
return {
sending: o,
countdown: s,
send: f,
start: d,
stop: u,
};
}
export { i as t };
+50
View File
@@ -0,0 +1,50 @@
import { computed } from "vue";
import { useState } from "#app";
import { useApi } from "~/lib/auth.js";
import { n as WithdrawDialog_n } from "~/components/WithdrawDialog.vue";
function i(i = ``) {
let a = useState(
`withdraw-availability:${i ? `recommend` : `credit`}`,
() => ({
rule: null,
loading: !1,
loaded: !1,
error: ``,
}),
),
o = computed(() => WithdrawDialog_n(a.value.rule, i ? `recommend` : ``)),
s = computed(() => a.value.loading),
c = computed(() => a.value.loaded),
l = computed(() => a.value.error);
async function u(e = !1) {
if (!(a.value.loading || (a.value.loaded && !e))) {
((a.value.loading = !0), (a.value.error = ``));
try {
let e = await useApi().get(
`/withdraw/rule/credit`,
i
? {
scene: `recommend`,
}
: void 0,
);
((a.value.rule = e ?? null), (a.value.loaded = !0));
} catch (e) {
((a.value.rule = null),
(a.value.loaded = !1),
(a.value.error =
e instanceof Error ? e.message : `加载提现设置失败`));
} finally {
a.value.loading = !1;
}
}
}
return {
enabled: o,
loading: s,
loaded: c,
error: l,
load: u,
};
}
export { i as t };
+35
View File
@@ -0,0 +1,35 @@
var e = `console.wechat-binding`;
function t(t, n, r = Date.now()) {
if (!t.ticket || !t.token) throw Error(`扫码会话无效,请重新扫码`);
let i = Math.min(r + 3e5, t.expire_time ? t.expire_time * 1e3 : r + 3e5);
if (i <= r) throw Error(`二维码已过期,请重新扫码`);
n.setItem(
e,
JSON.stringify({
ticket: t.ticket,
token: t.token,
expires: i,
}),
);
}
function n(t, n = Date.now()) {
try {
let r = JSON.parse(t.getItem(e) || `null`);
if (
r &&
typeof r.ticket == `string` &&
r.ticket &&
typeof r.token == `string` &&
r.token &&
typeof r.expires == `number` &&
r.expires > n &&
r.expires <= n + 3e5
)
return r;
} catch {}
return (t.removeItem(e), null);
}
function r(t) {
t.removeItem(e);
}
export { n, t as r, r as t };