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

@@ -0,0 +1,172 @@
<script>
import "~/assets/styles/CloudAccessExtras.CnBJlFAZ.css";
import { toDisplayString } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
var y = {
key: 0,
class: `cloud-extras`,
},
b = {
class: `info-table`,
},
x = {
key: 0,
class: `kv`,
},
S = {
class: `action-cell`,
},
C = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `CloudAccessExtras`,
props: {
hostId: {},
module: {},
imageName: {},
config: {},
},
emits: [`refresh`],
setup(f) {
let _ = f,
C = useApi(),
w = computed(() => [`mf_cloud`, `remf_cloud`].includes(_.module)),
T = computed(() => /windows/i.test(_.imageName)),
E = ref(!1),
D = ref(``),
O = 0,
k = !1;
async function A() {
if (!w.value || !T.value || E.value || k) return;
let e = O;
((E.value = !0), (D.value = ``));
try {
let t = await C.get(`/${_.module}/${_.hostId}/download_rdp`);
if (k || e !== O) return;
if (typeof t.content != `string` || !t.content.trim())
throw Error(`远程桌面文件内容为空`);
let n = URL.createObjectURL(
new Blob([t.content], {
type: `application/x-rdp`,
}),
),
r = document.createElement(`a`);
((r.href = n),
(r.download = String(
t.name || `instance-${_.hostId}.rdp`,
).replace(/[\\/\0]/g, `_`)),
r.click(),
setTimeout(() => URL.revokeObjectURL(n), 1e3));
} catch (t) {
!k &&
e === O &&
(D.value = t instanceof Error ? t.message : `RDP 文件下载失败`);
} finally {
e === O && (E.value = !1);
}
}
return (
watch([() => _.hostId, () => _.module, () => _.imageName], () => {
(O++, (E.value = !1), (D.value = ``));
}),
onBeforeUnmount(() => {
((k = !0), O++);
}),
(t, n) => {
let i = button,
s = message;
return unref(w) && unref(T)
? (openBlock(),
createElementBlock(`section`, y, [
(n[2] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`远程桌面连接`,
-1,
)),
createElementVNode(`div`, b, [
unref(T)
? (openBlock(),
createElementBlock(`div`, x, [
(n[1] ||= createElementVNode(
`span`,
null,
`远程桌面`,
-1,
)),
createElementVNode(`div`, S, [
createVNode(
i,
{
label: `下载远程桌面连接文件`,
icon: `pi pi-download`,
loading: unref(E),
onClick: A,
},
null,
8,
[`loading`],
),
(n[0] ||= createElementVNode(
`p`,
{
class: `action-desc`,
},
`下载连接文件后,使用远程桌面客户端连接您的实例。`,
-1,
)),
]),
]))
: createCommentVNode(``, !0),
]),
unref(D)
? (openBlock(),
createBlock(
s,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(D)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]))
: createCommentVNode(``, !0);
}
);
},
}),
[[`__scopeId`, `data-v-94e7f654`]],
),
{
__name: `CloudAccessExtras`,
},
);
export {};
export default C;
</script>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+838
View File
@@ -0,0 +1,838 @@
<script>
import "~/assets/styles/GeetestField.DiieTibK.css";
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
import "~/assets/styles/InstanceSmsCode.CsITfIEU.css";
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
import "~/assets/styles/DcimActions.Da2op5wy.css";
import { toDisplayString } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import inputtext from "primevue/inputtext";
import { n as product_name_n } from "~/lib/product-name.js";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import checkbox from "primevue/checkbox";
import OperationNotice from "~/components/OperationNotice.vue";
import OperatePasswordGate from "~/components/OperatePasswordGate.vue";
import { t as os_name_t } from "~/lib/os-name.js";
import ImagePurchaseDialog from "~/components/instance/ImagePurchaseDialog.vue";
import InstanceSmsCode from "~/components/instance/InstanceSmsCode.vue";
import { t as remote_console_t } from "~/lib/remote-console.js";
var fe = {
class: `action-form`,
},
pe = {
class: `target`,
},
me = [`id`],
he = {
key: 1,
class: `muted`,
},
ge = {
class: `form-grid`,
},
_e = [`for`],
ve = [`id`],
ye = [`for`],
be = [`id`],
xe = [`for`],
Se = {
key: 6,
class: `ack`,
},
Ce = [`for`],
S = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimActions`,
props: {
hostId: {},
productId: {},
host: {},
module: {},
detail: {},
},
emits: [`refresh`],
setup(h, { expose: y, emit: S }) {
let C = h,
w = S,
T = useApi(),
E = useId(),
D = ref(null),
O = ref(``),
k = ref(!1),
A = ref(``),
j = ref(!1),
M = ref(``),
N = ref(``),
P = ref(``),
F = ref(!1),
I = ref(2),
L = ref(null),
R = ref([]),
we = (e) => os_name_t(e.name),
z = ref(!1),
B = ref(``),
V = ref(22),
H = ref(1),
U = ref(``),
W = ref(null),
G = 0,
K = !1,
q = {
on: `开机`,
off: `关机`,
reboot: `重启`,
vnc: `打开 VNC 控制台`,
"vnc/restart": `重启 VNC`,
"vnc/start": `启动 VNC`,
reset_password: `重置密码`,
reinstall: `重装系统`,
rescue: `进入救援模式`,
"rescue/exit": `退出救援模式`,
},
J = computed(() => D.value === `reinstall`),
Y = computed(
() => D.value === `reinstall` || D.value === `reset_password`,
),
X = computed(() =>
D.value === `reinstall`
? Number(C.detail.info.value?.config?.reinstall_sms_verify) ===
1
: D.value === `reset_password` &&
Number(
C.detail.info.value?.config?.reset_password_sms_verify,
) === 1,
),
Z = computed(
() => C.host.status === `Active` && C.detail.canControl.value,
),
Te = computed(() =>
D.value === `reinstall`
? `重装会覆盖所选分区并删除其中的数据。请先完成备份,再确认继续。`
: D.value === `off`
? `关机后,该实例上的服务将停止运行。`
: [`reboot`, `rescue`, `rescue/exit`].includes(D.value || ``)
? `此操作会中断当前连接,实例上的服务可能暂时不可用。`
: D.value === `reset_password`
? `密码修改后,请使用新密码连接服务器。部分系统可能需要重启后生效。`
: `请确认目标实例后继续。`,
);
function Ee(e) {
return e === `rescue` || e === `rescue/exit`
? !!C.detail.remote?.value && !C.detail.remoteLoading?.value
: !0;
}
function Q() {
return (
!K &&
Z.value &&
O.value === `${C.module}:${C.hostId}` &&
String(C.host.id) === C.hostId
);
}
function De() {
k.value ||
(G++,
(D.value = null),
(N.value = ``),
(P.value = ``),
(A.value = ``),
(W.value = null));
}
async function $(e) {
if (!Z.value || k.value || K || !(e in q) || !Ee(e)) return;
if (e === `vnc`) {
remote_console_t(C.hostId, C.module);
return;
}
let t = ++G;
if (
((O.value = `${C.module}:${C.hostId}`),
(D.value = e),
(A.value = ``),
(M.value = ``),
(N.value = ``),
(P.value = ``),
(F.value = !1),
(U.value = ``),
(L.value = null),
(R.value = []),
(B.value = ``),
(z.value = !1),
e === `reinstall`)
) {
z.value = !0;
try {
let e = await T.get(
`/product/${C.productId}/${C.module}/image`,
);
if (t !== G || !Q()) return;
R.value = (e.list || []).flatMap((e) => e.image || []);
} catch (e) {
t === G &&
Q() &&
(B.value =
e instanceof Error ? e.message : `系统镜像加载失败`);
} finally {
t === G && (z.value = !1);
}
}
}
async function Oe() {
if (!D.value || k.value || !Q() || !Ee(D.value)) return;
let e = D.value,
t = G,
n = C.hostId,
r = C.module;
if (((A.value = ``), (j.value = !1), X.value && !U.value.trim())) {
A.value = `请输入账户手机验证码`;
return;
}
if (Y.value && N.value.length < 8) {
A.value = `请设置至少 8 位的新密码`;
return;
}
if (
e === `reinstall` &&
(!L.value || !R.value.some((e) => e.id === L.value))
) {
A.value = `请选择操作系统`;
return;
}
if (
e === `reinstall` &&
(!Number.isInteger(V.value) || V.value < 1 || V.value > 65535)
) {
A.value = `请输入 1 到 65535 之间的端口`;
return;
}
if (J.value && !F.value) {
A.value = `请确认已备份数据并了解重装影响`;
return;
}
let i = () => t === G && Q(),
a = {};
([`mf_dcim`, `remf_dcim`].includes(r) &&
P.value &&
(a.client_operate_password = P.value),
Y.value && (a.password = N.value),
X.value && (a.code = U.value.trim()),
e === `rescue` && (a.type = I.value),
e === `reinstall` &&
Object.assign(a, {
image_id: L.value,
port: V.value,
part_type: H.value,
}),
(k.value = !0));
try {
if (e === `reinstall`) {
let e = L.value,
t = await T.get(`/${r}/${n}/image/check`, {
image_id: e,
});
if (!i()) return;
if (
t.price === null ||
t.price === void 0 ||
String(t.price).trim() === `` ||
!Number.isFinite(Number(t.price)) ||
Number(t.price) < 0
)
throw Error(`镜像费用信息无效,请重试`);
if (Number(t.price) > 0) {
((W.value = {
module: r,
hostId: n,
imageId: Number(e),
price: Number(t.price).toFixed(2),
description: t.description,
}),
(F.value = !1));
return;
}
}
if ((await T.post(`/${r}/${n}/${e}`, a), !i())) return;
((M.value = `${q[e]}指令已提交,请等待实例状态更新。`),
(D.value = null),
(N.value = ``),
(P.value = ``),
w(`refresh`));
} catch (t) {
i() &&
((j.value = !0),
(A.value = t instanceof Error ? t.message : `${q[e]}失败`));
} finally {
t === G && (k.value = !1);
}
}
return (
watch(
[() => C.hostId, () => C.module, () => C.host.status],
() => {
(G++,
(D.value = null),
(k.value = !1),
(N.value = ``),
(P.value = ``),
(W.value = null));
},
{
flush: `sync`,
},
),
watch(
L,
() => {
W.value = null;
},
{
flush: `sync`,
},
),
onBeforeUnmount(() => {
((K = !0), G++);
}),
y({
request: $,
busy: k,
}),
(t, n) => {
let r = ImagePurchaseDialog,
a = OperationNotice,
c = message,
v = InstanceSmsCode,
y = select,
b = button,
x = inputnumber,
S = inputtext,
C = OperatePasswordGate,
w = checkbox,
T = dialog;
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createVNode(
r,
{
modelValue: unref(W),
"onUpdate:modelValue": (n[0] ||= (e) =>
isRef(W) ? (W.value = e) : null),
onAuthorized: (n[1] ||= (e) =>
(M.value = `镜像已授权,请确认备份后重新提交重装`)),
},
null,
8,
[`modelValue`],
),
unref(M)
? (openBlock(),
createBlock(
a,
{
key: 0,
message: unref(M),
},
null,
8,
[`message`],
))
: createCommentVNode(``, !0),
unref(A) && unref(j)
? (openBlock(),
createBlock(
a,
{
key: 1,
severity: `error`,
message: unref(A),
},
null,
8,
[`message`],
))
: createCommentVNode(``, !0),
createVNode(
T,
{
visible: !!unref(D),
header: unref(D) ? q[unref(D)] : ``,
modal: ``,
style: {
width: `520px`,
},
draggable: !1,
closable: !unref(k),
"close-on-escape": !unref(k),
"onUpdate:visible": (n[11] ||= (e) => {
e || De();
}),
},
{
footer: withCtx(() => [
createVNode(
b,
{
label: `取消`,
outlined: ``,
severity: `secondary`,
disabled: unref(k),
onClick: De,
},
null,
8,
[`disabled`],
),
createVNode(
b,
{
label: `确认${unref(D) ? q[unref(D)] : ``}`,
severity:
unref(D) === `vnc` || unref(D) === `on`
? `primary`
: `danger`,
loading: unref(k),
disabled: unref(k) || unref(z) || !unref(Z),
onClick: Oe,
},
null,
8,
[`label`, `severity`, `loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, fe, [
createElementVNode(`p`, pe, [
(n[12] ||= createTextVNode(`目标实例:`, -1)),
createElementVNode(
`strong`,
null,
toDisplayString(
h.host.name ||
unref(product_name_n)(h.host.product_name),
),
1,
),
createTextVNode(
`(#` + toDisplayString(h.hostId) + `)`,
1,
),
]),
createVNode(
c,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(Te)),
1,
),
]),
_: 1,
},
),
unref(A) && !unref(j)
? (openBlock(),
createBlock(
c,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(A)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(X)
? (openBlock(),
createBlock(
v,
{
key: 1,
modelValue: unref(U),
"onUpdate:modelValue": (n[2] ||= (e) =>
isRef(U) ? (U.value = e) : null),
disabled: unref(k),
},
null,
8,
[`modelValue`, `disabled`],
))
: createCommentVNode(``, !0),
unref(D) === `reinstall`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createElementVNode(
`span`,
{
id: `${unref(E)}-image-label`,
},
`操作系统`,
8,
me,
),
createVNode(
y,
{
modelValue: unref(L),
"onUpdate:modelValue": (n[3] ||= (e) =>
isRef(L) ? (L.value = e) : null),
"input-id": `${unref(E)}-image`,
"aria-labelledby": `${unref(E)}-image-label`,
options: unref(R),
"option-label": we,
"option-value": `id`,
placeholder: `请选择操作系统`,
loading: unref(z),
disabled: unref(k) || unref(z),
fluid: ``,
},
null,
8,
[
`modelValue`,
`input-id`,
`aria-labelledby`,
`options`,
`loading`,
`disabled`,
],
),
unref(B)
? (openBlock(),
createBlock(
c,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(B)),
1,
),
createVNode(b, {
label: `重试`,
text: ``,
onClick: (n[4] ||= (e) =>
$(`reinstall`)),
}),
]),
_: 1,
},
))
: !unref(z) && !unref(R).length
? (openBlock(),
createElementBlock(
`p`,
he,
`此商品暂无可用系统镜像。`,
))
: createCommentVNode(``, !0),
createElementVNode(`div`, ge, [
createElementVNode(`div`, null, [
createElementVNode(
`label`,
{
for: `${unref(E)}-port`,
},
`连接端口`,
8,
_e,
),
createVNode(
x,
{
modelValue: unref(V),
"onUpdate:modelValue": (n[5] ||= (
e,
) =>
isRef(V) ? (V.value = e) : null),
"input-id": `${unref(E)}-port`,
min: 1,
max: 65535,
"use-grouping": !1,
disabled: unref(k),
fluid: ``,
},
null,
8,
[
`modelValue`,
`input-id`,
`disabled`,
],
),
]),
createElementVNode(`div`, null, [
createElementVNode(
`span`,
{
id: `${unref(E)}-partition-label`,
},
`分区方式`,
8,
ve,
),
createVNode(
y,
{
modelValue: unref(H),
"onUpdate:modelValue": (n[6] ||= (
e,
) =>
isRef(H) ? (H.value = e) : null),
"aria-labelledby": `${unref(E)}-partition-label`,
options: [
{
label: `仅格式化第一分区`,
value: 1,
},
{
label: `格式化全盘`,
value: 0,
},
],
"option-label": `label`,
"option-value": `value`,
disabled: unref(k),
fluid: ``,
},
null,
8,
[
`modelValue`,
`aria-labelledby`,
`disabled`,
],
),
]),
]),
],
64,
))
: createCommentVNode(``, !0),
unref(Y)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 3,
},
[
createElementVNode(
`label`,
{
for: `${unref(E)}-password`,
},
`新密码`,
8,
ye,
),
createVNode(
S,
{
id: `${unref(E)}-password`,
modelValue: unref(N),
"onUpdate:modelValue": (n[7] ||= (e) =>
isRef(N) ? (N.value = e) : null),
type: `password`,
autocomplete: `new-password`,
disabled: unref(k),
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
],
64,
))
: createCommentVNode(``, !0),
unref(D) === `rescue`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 4,
},
[
createElementVNode(
`span`,
{
id: `${unref(E)}-rescue-label`,
},
`救援系统`,
8,
be,
),
createVNode(
y,
{
modelValue: unref(I),
"onUpdate:modelValue": (n[8] ||= (e) =>
isRef(I) ? (I.value = e) : null),
"aria-labelledby": `${unref(E)}-rescue-label`,
options: [
{
label: `Linux`,
value: 2,
},
{
label: `Windows`,
value: 1,
},
],
"option-label": `label`,
"option-value": `value`,
disabled: unref(k),
fluid: ``,
},
null,
8,
[
`modelValue`,
`aria-labelledby`,
`disabled`,
],
),
],
64,
))
: createCommentVNode(``, !0),
[`mf_dcim`, `remf_dcim`].includes(h.module)
? (openBlock(),
createBlock(
C,
{
key: 5,
},
{
default: withCtx(() => [
createElementVNode(
`label`,
{
for: `${unref(E)}-operate`,
},
`操作密码(如已设置)`,
8,
xe,
),
createVNode(
S,
{
id: `${unref(E)}-operate`,
modelValue: unref(P),
"onUpdate:modelValue": (n[9] ||= (
e,
) =>
isRef(P) ? (P.value = e) : null),
type: `password`,
autocomplete: `off`,
disabled: unref(k),
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(J)
? (openBlock(),
createElementBlock(`div`, Se, [
createVNode(
w,
{
modelValue: unref(F),
"onUpdate:modelValue": (n[10] ||= (e) =>
isRef(F) ? (F.value = e) : null),
"input-id": `${unref(E)}-ack`,
binary: ``,
disabled: unref(k),
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
createElementVNode(
`label`,
{
for: `${unref(E)}-ack`,
},
`我已备份数据,了解所选分区的数据将被清除`,
8,
Ce,
),
]))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`, `header`, `closable`, `close-on-escape`],
),
],
64,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-a1044895`]],
),
{
__name: `DcimActions`,
},
);
export {};
export default S;
</script>
+989
View File
@@ -0,0 +1,989 @@
<script>
import "~/assets/styles/InstanceRenewDialog.BHDAL6d3.css";
import "~/assets/styles/GeetestField.DiieTibK.css";
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
import "~/assets/styles/SecurityVerificationDialog.skYFo4v7.css";
import "~/assets/styles/DcimBilling.QV7PUjnH.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { navigateTo } from "#app";
import { NuxtLink } from "#components";
import { sanitizeMessage } from "~/lib/auth.js";
import { useApi } from "~/lib/auth.js";
import { assertSecurityComplete } from "~/lib/auth.js";
import { securityChallenge } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { c as dict_c } from "~/lib/dict.js";
import { l as dict_l } from "~/lib/dict.js";
import { r as dict_r } from "~/lib/dict.js";
import select from "primevue/select";
import OperationNotice from "~/components/OperationNotice.vue";
import textarea from "primevue/textarea";
import tag from "primevue/tag";
import SecurityVerificationDialog from "~/components/SecurityVerificationDialog.vue";
import InstanceRenewDialog from "~/components/instance/InstanceRenewDialog.vue";
var he = {
class: `billing`,
},
ge = {
class: `rows`,
},
_e = {
key: 1,
},
ve = {
key: 0,
},
ye = {
key: 0,
},
be = {
key: 1,
},
xe = {
class: `order-row`,
},
Se = {
key: 1,
},
Ce = {
class: `muted`,
},
we = {
class: `form`,
},
Te = {
key: 1,
},
Ee = [`id`],
De = [`for`],
Oe = [`id`],
ke = {
key: 3,
},
C = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimBilling`,
props: {
hostId: {},
host: {},
},
emits: [`refresh`],
setup(g, { emit: S }) {
let C = g,
w = S,
T = useApi(),
E = ref(``),
D = useId(),
O = ref(!1),
k = ref(null),
A = ref(``),
j = ref(``),
M = ref(``),
N = ref(``),
P = ref(!1),
F = ref(!1),
I = ref(null),
L = ref(`Expire`),
R = ref(null),
z = ref(``),
B = ref(!1),
V = ref({}),
H = ref(null),
U = ref(null),
W = ref(null),
Ae = {
Pending: `待审核`,
Suspending: `待停用`,
Suspend: `停用中`,
Suspended: `已停用`,
Refund: `已退款`,
Reject: `已驳回`,
Cancelled: `已取消`,
},
je = computed(
() =>
!C.host.renew_forbidden &&
![`Deleted`, `Unpaid`, `Cancelled`, `Failed`].includes(
C.host.status,
),
),
G = computed(
() =>
!F.value &&
!j.value &&
Number(U.value?.allow_refund) === 1 &&
(!W.value || [`Reject`, `Cancelled`].includes(W.value.status)),
),
K = computed(
() =>
!F.value &&
!j.value &&
[`Pending`, `Suspending`, `Suspend`].includes(
W.value?.status || ``,
),
),
q = 0,
J = 0,
Y = !1,
X = (e, t) =>
!Y && e === C.hostId && String(C.host.id) === e && t === J;
async function Z() {
let e = ++q,
t = C.hostId;
((F.value = !0),
(k.value = null),
(U.value = null),
(W.value = null),
(A.value = ``),
(j.value = ``));
let n = await Promise.allSettled([
T.get(`/host/${t}/renew/auto`),
T.get(`/refund`, {
host_id: t,
}),
T.get(`/refund/host/${t}/refund`),
]);
if (Y || e !== q || t !== C.hostId) return;
let [r, i, a] = n;
(r.status === `fulfilled` &&
[0, 1].includes(Number(r.value?.status))
? (k.value = Number(r.value.status))
: (A.value =
r.status === `rejected` && r.reason instanceof Error
? r.reason.message
: `自动续费状态不可用`),
i.status === `fulfilled`
? (U.value = i.value)
: (j.value =
i.reason instanceof Error
? i.reason.message
: `停用信息暂不可用`),
a.status === `fulfilled` && a.value && `refund` in a.value
? (W.value = a.value.refund)
: (j.value =
a.status === `rejected` && a.reason instanceof Error
? a.reason.message
: `停用记录暂不可用`),
(F.value = !1));
}
function Q(e) {
P.value ||
F.value ||
B.value ||
String(C.host.id) !== C.hostId ||
(e === `auto` && k.value === null) ||
(e === `refund` && !G.value) ||
(e === `cancel` && !K.value) ||
((I.value = e),
(M.value = ``),
(E.value = ``),
(N.value = ``),
(L.value = `Expire`),
(z.value = ``),
(R.value = null),
(H.value = null));
}
function $() {
!P.value &&
!B.value &&
((I.value = null), (M.value = ``), (H.value = null));
}
async function Me() {
if (
P.value ||
B.value ||
!I.value ||
Y ||
String(C.host.id) !== C.hostId
)
return;
let e = I.value,
t = C.hostId,
n = J,
r = () => X(t, n);
if (
((M.value = ``),
(E.value = ``),
(e === `auto` && k.value === null) ||
(e === `refund` && !G.value) ||
(e === `cancel` && !K.value))
)
return;
if (
e === `refund` &&
(U.value?.reason_custom ? !z.value.trim() : !R.value)
) {
M.value = `请填写或选择停用原因`;
return;
}
let i = {
host_id: Number(t),
type: L.value,
suspend_reason: U.value?.reason_custom
? z.value.trim()
: [R.value],
};
P.value = !0;
try {
if (e === `auto`) {
let e = k.value === 1 ? 0 : 1;
(await T.put(`/host/${t}/renew/auto`, {
status: e,
}),
r() && (k.value = e));
} else if (e === `cancel`)
await T.put(`/refund/${W.value.id}/cancel`);
else {
let e = await T.post(`/refund`, i);
if (!r()) return;
assertSecurityComplete(e);
}
if (!r()) return;
((I.value = null),
(N.value =
e === `auto`
? `自动续费设置已更新`
: e === `cancel`
? `停用申请已取消`
: `停用申请已提交`),
e !== `auto` && (await Z()));
} catch (t) {
if (!r()) return;
let n = e === `refund` ? securityChallenge(t) : null;
n
? ((H.value = i), (V.value = n), (B.value = !0))
: (E.value =
t instanceof Error ? t.message : `操作失败,请重试`);
} finally {
r() && (P.value = !1);
}
}
async function Ne(e) {
let t = H.value,
n = C.hostId,
r = J;
if (
t &&
!P.value &&
B.value &&
Number(n) === t.host_id &&
X(n, r)
) {
((P.value = !0), (E.value = ``));
try {
let i = await T.post(`/refund`, {
...t,
...e,
});
if (!X(n, r)) return;
(assertSecurityComplete(i),
(H.value = null),
(B.value = !1),
(I.value = null),
(N.value = `停用申请已提交`),
await Z(),
X(n, r) && w(`refresh`));
} catch (e) {
if (!X(n, r)) return;
let t = securityChallenge(e);
t
? ((V.value = t), (E.value = `安全验证尚未完成,请重试`))
: (E.value =
e instanceof Error ? e.message : `操作失败,请重试`);
} finally {
X(n, r) && (P.value = !1);
}
}
}
return (
watch(
() => C.hostId,
() => {
(J++,
(I.value = null),
(P.value = !1),
(O.value = !1),
(H.value = null),
(B.value = !1),
(V.value = {}),
(E.value = ``),
(N.value = ``),
Z());
},
{
flush: `sync`,
},
),
onMounted(Z),
onBeforeUnmount(() => {
((Y = !0), q++, J++, (H.value = null), (B.value = !1));
}),
(t, n) => {
let r = OperationNotice,
i = tag,
o = button,
l = NuxtLink,
y = InstanceRenewDialog,
b = message,
x = select,
S = textarea,
C = dialog,
T = SecurityVerificationDialog;
return (
openBlock(),
createElementBlock(`div`, he, [
createVNode(
r,
{
message: unref(E),
severity: `error`,
},
null,
8,
[`message`],
),
createVNode(
r,
{
message: unref(N),
severity: `success`,
},
null,
8,
[`message`],
),
(n[24] ||= createElementVNode(`h3`, null, `计费信息`, -1)),
createElementVNode(`dl`, ge, [
createElementVNode(`div`, null, [
(n[12] ||= createElementVNode(
`dt`,
null,
`计费方式`,
-1,
)),
createElementVNode(
`dd`,
null,
toDisplayString(
g.host.billing_cycle_name ||
g.host.billing_cycle ||
`—`,
),
1,
),
]),
createElementVNode(`div`, null, [
(n[13] ||= createElementVNode(`dt`, null, `状态`, -1)),
createElementVNode(`dd`, null, [
createVNode(
i,
{
value: (`statusLabel` in t
? t.statusLabel
: unref(dict_c))(g.host.status),
severity: (`statusSeverity` in t
? t.statusSeverity
: unref(dict_l))(g.host.status),
},
null,
8,
[`value`, `severity`],
),
]),
]),
createElementVNode(`div`, null, [
(n[14] ||= createElementVNode(
`dt`,
null,
`自动续费`,
-1,
)),
createElementVNode(`dd`, null, [
createElementVNode(
`span`,
null,
toDisplayString(
unref(F)
? `加载中…`
: unref(k) === null
? `状态不可用`
: unref(k)
? `已开启`
: `已关闭`,
),
1,
),
unref(k) === null
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
o,
{
key: 0,
label: unref(k) ? `关闭` : `开启`,
text: ``,
size: `small`,
disabled: unref(P) || unref(F),
onClick: (n[0] ||= (e) => Q(`auto`)),
},
null,
8,
[`label`, `disabled`],
)),
unref(A)
? (openBlock(),
createElementBlock(
`small`,
_e,
toDisplayString(unref(A)),
1,
))
: createCommentVNode(``, !0),
]),
]),
createElementVNode(`div`, null, [
(n[15] ||= createElementVNode(
`dt`,
null,
`续费金额`,
-1,
)),
createElementVNode(`dd`, null, [
createTextVNode(
`¥` + toDisplayString(g.host.renew_amount),
1,
),
createVNode(
o,
{
label: `续费`,
size: `small`,
text: ``,
disabled: !unref(je),
onClick: (n[1] ||= (e) => (O.value = !0)),
},
null,
8,
[`disabled`],
),
]),
]),
createElementVNode(`div`, null, [
(n[16] ||= createElementVNode(
`dt`,
null,
`开通时间`,
-1,
)),
createElementVNode(
`dd`,
null,
toDisplayString(
(`formatTime` in t ? t.formatTime : unref(dict_r))(
g.host.active_time,
),
),
1,
),
]),
createElementVNode(`div`, null, [
(n[17] ||= createElementVNode(
`dt`,
null,
`到期时间`,
-1,
)),
createElementVNode(
`dd`,
null,
toDisplayString(
(`formatTime` in t ? t.formatTime : unref(dict_r))(
g.host.due_time,
),
),
1,
),
]),
createElementVNode(`div`, null, [
(n[18] ||= createElementVNode(
`dt`,
null,
`停用 / 退款`,
-1,
)),
createElementVNode(`dd`, null, [
unref(F)
? (openBlock(),
createElementBlock(`span`, ve, `加载中…`))
: unref(j)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`span`,
null,
toDisplayString(unref(j)),
1,
),
createVNode(o, {
label: `重试`,
text: ``,
size: `small`,
onClick: Z,
}),
],
64,
))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
unref(W)
? (openBlock(),
createElementBlock(`span`, ye, [
createTextVNode(
toDisplayString(
Ae[unref(W).status] ||
unref(W).status,
),
1,
),
unref(W).reject_reason
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
` · ` +
toDisplayString(
unref(sanitizeMessage)(
unref(W).reject_reason,
),
),
1,
),
],
64,
))
: createCommentVNode(``, !0),
]))
: unref(G)
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`span`,
be,
`当前实例不支持申请停用 / 退款`,
)),
unref(G)
? (openBlock(),
createBlock(o, {
key: 2,
label: `申请停用`,
text: ``,
severity: `danger`,
size: `small`,
onClick: (n[2] ||= (e) => Q(`refund`)),
}))
: createCommentVNode(``, !0),
unref(K)
? (openBlock(),
createBlock(o, {
key: 3,
label: `取消申请`,
text: ``,
size: `small`,
onClick: (n[3] ||= (e) => Q(`cancel`)),
}))
: createCommentVNode(``, !0),
],
64,
)),
]),
]),
]),
(n[25] ||= createElementVNode(`h3`, null, `关联订单`, -1)),
createElementVNode(`div`, xe, [
(n[19] ||= createElementVNode(
`span`,
null,
`开通订单`,
-1,
)),
g.host.order_id
? (openBlock(),
createBlock(
l,
{
key: 0,
to: `/orders/${g.host.order_id}`,
},
{
default: withCtx(() => [
createTextVNode(
`#` + toDisplayString(g.host.order_id),
1,
),
]),
_: 1,
},
8,
[`to`],
))
: (openBlock(),
createElementBlock(`span`, Se, `暂无关联订单`)),
]),
createElementVNode(`p`, Ce, [
(n[21] ||= createTextVNode(`续费及变更订单可前往`, -1)),
createVNode(
l,
{
to: `/orders`,
},
{
default: withCtx(() => [
...(n[20] ||= [createTextVNode(`订单管理`, -1)]),
]),
_: 1,
},
),
(n[22] ||= createTextVNode(`查看。`, -1)),
]),
createVNode(
y,
{
modelValue: unref(O),
"onUpdate:modelValue": (n[4] ||= (e) =>
isRef(O) ? (O.value = e) : null),
"host-id": g.hostId,
onPaid: (n[5] ||= (e) => {
(w(`refresh`),
(`navigateTo` in t
? t.navigateTo
: unref(navigateTo))(`/orders`));
}),
},
null,
8,
[`modelValue`, `host-id`],
),
createVNode(
C,
{
visible: !!unref(I),
header:
unref(I) === `auto`
? `确认自动续费设置`
: unref(I) === `refund`
? `确认申请停用`
: `确认取消申请`,
modal: ``,
style: {
width: `500px`,
},
closable: !unref(P) && !unref(B),
"close-on-escape": !unref(P) && !unref(B),
"onUpdate:visible": (n[9] ||= (e) => {
e || $();
}),
},
{
footer: withCtx(() => [
createVNode(
o,
{
label: `取消`,
outlined: ``,
severity: `secondary`,
disabled: unref(P) || unref(B),
onClick: $,
},
null,
8,
[`disabled`],
),
createVNode(
o,
{
label: `确认`,
severity:
unref(I) === `refund` ? `danger` : `primary`,
loading: unref(P),
disabled: unref(P) || unref(B),
onClick: Me,
},
null,
8,
[`severity`, `loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, we, [
createElementVNode(
`p`,
null,
`实例「` +
toDisplayString(g.host.name) +
`」(#` +
toDisplayString(g.hostId) +
`)`,
1,
),
unref(M)
? (openBlock(),
createBlock(
b,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(M)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(I) === `auto`
? (openBlock(),
createElementBlock(
`p`,
Te,
`确认` +
toDisplayString(unref(k) ? `关闭` : `开启`) +
`自动续费?开启后将按平台规则扣取余额续费。`,
1,
))
: unref(I) === `refund`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createVNode(
b,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
...(n[23] ||= [
createTextVNode(
`停用后服务将不可用,请提前备份数据。退款金额以审核结果为准。`,
-1,
),
]),
]),
_: 1,
},
),
createElementVNode(
`span`,
{
id: `${unref(D)}-type-label`,
},
`停用时间`,
8,
Ee,
),
createVNode(
x,
{
modelValue: unref(L),
"onUpdate:modelValue": (n[6] ||= (e) =>
isRef(L) ? (L.value = e) : null),
"aria-labelledby": `${unref(D)}-type-label`,
options: [
{
label: `到期停用`,
value: `Expire`,
},
{
label: `立即停用`,
value: `Immediate`,
},
],
"option-label": `label`,
"option-value": `value`,
disabled: unref(P) || unref(B),
},
null,
8,
[
`modelValue`,
`aria-labelledby`,
`disabled`,
],
),
unref(U)?.reason_custom
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createElementVNode(
`label`,
{
for: `${unref(D)}-reason`,
},
`停用原因`,
8,
De,
),
createVNode(
S,
{
id: `${unref(D)}-reason`,
modelValue: unref(z),
"onUpdate:modelValue": (n[7] ||=
(e) =>
isRef(z)
? (z.value = e)
: null),
disabled: unref(P) || unref(B),
rows: `3`,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
],
64,
))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`span`,
{
id: `${unref(D)}-reason-label`,
},
`停用原因`,
8,
Oe,
),
createVNode(
x,
{
modelValue: unref(R),
"onUpdate:modelValue": (n[8] ||=
(e) =>
isRef(R)
? (R.value = e)
: null),
"aria-labelledby": `${unref(D)}-reason-label`,
options:
unref(U)?.reasons || [],
"option-label": `content`,
"option-value": `id`,
disabled: unref(P) || unref(B),
},
null,
8,
[
`modelValue`,
`aria-labelledby`,
`options`,
`disabled`,
],
),
],
64,
)),
],
64,
))
: (openBlock(),
createElementBlock(
`p`,
ke,
`确认取消尚未处理的停用申请?`,
)),
]),
]),
_: 1,
},
8,
[`visible`, `header`, `closable`, `close-on-escape`],
),
createVNode(
T,
{
visible: unref(B),
"onUpdate:visible": (n[10] ||= (e) =>
isRef(B) ? (B.value = e) : null),
challenge: unref(V),
busy: unref(P),
"request-error": unref(E),
context: {
scene: `account`,
action: `host_refund`,
},
onVerified: Ne,
onCancel: (n[11] ||= (e) => (H.value = null)),
},
null,
8,
[`visible`, `challenge`, `busy`, `request-error`],
),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-9a8e05c2`]],
),
{
__name: `DcimBilling`,
},
);
export {};
export default C;
</script>
+636
View File
@@ -0,0 +1,636 @@
<script>
import "~/assets/styles/DcimDefence.BYaQccXZ.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { navigateTo } from "#app";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import select from "primevue/select";
import OperationNotice from "~/components/OperationNotice.vue";
import skeleton from "primevue/skeleton";
var T = {
class: `defence`,
},
E = {
class: `head`,
},
D = [`id`],
O = {
class: `rows`,
},
k = {
key: 0,
class: `config-error`,
},
A = {
key: 1,
class: `muted`,
},
j = {
class: `form`,
},
re = [`id`],
ie = {
key: 0,
},
ae = {
key: 1,
class: `muted`,
},
M = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimDefence`,
props: {
hostId: {},
module: {},
ip: {},
additionalIp: {},
peak: {},
active: {
type: Boolean,
},
upgradeAllowed: {
type: Boolean,
default: !0,
},
},
setup(g) {
let x = g,
M = useApi(),
N = ref(``),
P = useId(),
F = ref(x.ip),
I = computed(() => [
...new Set(
[x.ip, ...(x.additionalIp || ``).split(/[,;]/)]
.map((e) => e.trim())
.filter(Boolean),
),
]),
L = ref([]),
R = ref(``),
z = ref(!1),
B = ref(``),
V = ref(!1),
H = ref(!1),
U = ref(``),
W = ref(!1),
G = ref(``),
K = ref(null),
q = 0,
J = 0,
Y = !1,
X = computed(() =>
L.value.filter((e) => String(e.value) !== String(R.value)),
);
async function Z() {
let e = ++q,
t = F.value,
n = x.hostId;
if (
((L.value = []),
(R.value = ``),
(B.value = ``),
(z.value = !0),
!t || x.upgradeAllowed === !1)
) {
z.value = !1;
return;
}
try {
let r = await M.get(`/${x.module}/${n}/upgrade_defence_config`, {
ip: t,
});
if (Y || e !== q || t !== F.value || n !== x.hostId) return;
((L.value = Array.isArray(r.defence) ? r.defence : []),
(R.value = r.current_defence ?? ``));
} catch (t) {
!Y &&
e === q &&
(B.value = t instanceof Error ? t.message : `防御配置暂不可用`);
} finally {
!Y && e === q && (z.value = !1);
}
}
function oe() {
x.upgradeAllowed !== !1 &&
x.active &&
!H.value &&
!z.value &&
X.value.length &&
(J++,
(U.value = ``),
(K.value = null),
(G.value = ``),
(V.value = !0));
}
function Q() {
H.value || ((V.value = !1), J++, (W.value = !1), (K.value = null));
}
async function $() {
if (x.upgradeAllowed === !1) return;
let e = ++J,
t = U.value,
n = F.value,
r = x.hostId;
if (((K.value = null), (G.value = ``), (W.value = !0), !t)) {
W.value = !1;
return;
}
try {
let i = await M.get(`/${x.module}/${r}/upgrade_defence/price`, {
ip: n,
peak_defence: t,
});
if (
Y ||
e !== J ||
t !== U.value ||
n !== F.value ||
r !== x.hostId
)
return;
if (
i.price == null ||
!Number.isFinite(Number(i.price)) ||
Number(i.price) < 0
)
throw Error(`防御报价无效,请重试`);
K.value = i;
} catch (t) {
!Y &&
e === J &&
(G.value = t instanceof Error ? t.message : `获取防御报价失败`);
} finally {
!Y && e === J && (W.value = !1);
}
}
async function se() {
if (
x.upgradeAllowed === !1 ||
H.value ||
!x.active ||
!V.value ||
!K.value ||
W.value ||
!X.value.some((e) => String(e.value) === String(U.value))
)
return;
let e = J,
t = x.hostId,
n = F.value;
((H.value = !0), (G.value = ``), (N.value = ``));
try {
let r = await M.post(`/${x.module}/${t}/upgrade_defence/order`, {
ip: n,
peak_defence: U.value,
});
if (Y || e !== J || t !== x.hostId || n !== F.value) return;
if (!r.id)
throw Error(`订单编号未返回,请在订单管理中检查后再试`);
((V.value = !1), await navigateTo(`/orders/${r.id}`));
} catch (t) {
!Y &&
e === J &&
(N.value = t instanceof Error ? t.message : `创建防御订单失败`);
} finally {
!Y && e === J && (H.value = !1);
}
}
return (
watch(F, () => {
(Q(), Z());
}),
watch([() => x.hostId, () => x.module], () => {
(q++, J++, (H.value = !1), (V.value = !1), (F.value = x.ip), Z());
}),
onMounted(Z),
onBeforeUnmount(() => {
((Y = !0), q++, J++);
}),
(t, n) => {
let r = OperationNotice,
i = message,
o = select,
l = button,
y = skeleton,
b = dialog;
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createVNode(
r,
{
message: unref(N),
severity: `error`,
},
null,
8,
[`message`],
),
createElementVNode(`div`, T, [
createVNode(
i,
{
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
(n[3] ||= createTextVNode(`当前实例可查看`, -1)),
g.upgradeAllowed === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[createTextVNode(`和调整`)],
64,
)),
(n[4] ||= createTextVNode(
`平台提供的防御配置,暂未提供攻击事件与黑洞记录查询。`,
-1,
)),
]),
_: 1,
},
),
createElementVNode(`div`, E, [
(n[5] ||= createElementVNode(
`h3`,
null,
`DDoS 防护`,
-1,
)),
createElementVNode(
`span`,
{
id: `${unref(P)}-ip-label`,
},
`IP 地址`,
8,
D,
),
createVNode(
o,
{
modelValue: unref(F),
"onUpdate:modelValue": (n[0] ||= (e) =>
isRef(F) ? (F.value = e) : null),
options: unref(I),
"aria-labelledby": `${unref(P)}-ip-label`,
disabled: unref(H),
},
null,
8,
[
`modelValue`,
`options`,
`aria-labelledby`,
`disabled`,
],
),
createVNode(
l,
{
label: `刷新`,
text: ``,
icon: `pi pi-refresh`,
loading: unref(z),
onClick: Z,
},
null,
8,
[`loading`],
),
]),
createElementVNode(`dl`, O, [
createElementVNode(`div`, null, [
(n[6] ||= createElementVNode(
`dt`,
null,
`防御峰值`,
-1,
)),
createElementVNode(`dd`, null, [
createTextVNode(
toDisplayString(
unref(R) || g.peak != null
? `${unref(R) || g.peak} Gbps`
: `未提供`,
),
1,
),
g.upgradeAllowed !== !1 && unref(X).length
? (openBlock(),
createBlock(
l,
{
key: 0,
label: `调整防御`,
text: ``,
size: `small`,
disabled: !g.active || unref(H),
onClick: oe,
},
null,
8,
[`disabled`],
))
: createCommentVNode(``, !0),
]),
]),
]),
unref(B)
? (openBlock(),
createElementBlock(`div`, k, [
createElementVNode(
`span`,
null,
toDisplayString(unref(B)),
1,
),
createVNode(l, {
label: `重试`,
text: ``,
size: `small`,
onClick: Z,
}),
]))
: g.upgradeAllowed !== !1 &&
!unref(z) &&
!unref(X).length
? (openBlock(),
createElementBlock(
`p`,
A,
`此 IP 暂无可选的防御调整配置。`,
))
: createCommentVNode(``, !0),
(n[7] ||= createElementVNode(`h3`, null, `攻击记录`, -1)),
(n[8] ||= createElementVNode(
`p`,
{
class: `unavailable`,
},
`攻击记录暂不可用`,
-1,
)),
(n[9] ||= createElementVNode(`h3`, null, `黑洞记录`, -1)),
(n[10] ||= createElementVNode(
`p`,
{
class: `unavailable`,
},
`黑洞记录暂不可用`,
-1,
)),
]),
g.upgradeAllowed === !1
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
b,
{
key: 0,
visible: unref(V),
header: `确认调整防御`,
modal: ``,
style: {
width: `480px`,
},
closable: !unref(H),
"close-on-escape": !unref(H),
"onUpdate:visible": (n[2] ||= (e) => {
e || Q();
}),
},
{
footer: withCtx(() => [
createVNode(
l,
{
label: `取消`,
severity: `secondary`,
outlined: ``,
disabled: unref(H),
onClick: Q,
},
null,
8,
[`disabled`],
),
createVNode(
l,
{
label: `确认并创建订单`,
loading: unref(H),
disabled:
unref(H) ||
!unref(K) ||
unref(W) ||
!g.active,
onClick: se,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, j, [
createElementVNode(
`p`,
null,
`实例 #` +
toDisplayString(g.hostId) +
` · ` +
toDisplayString(unref(F)),
1,
),
createElementVNode(
`span`,
{
id: `${unref(P)}-peak-label`,
},
`防御配置`,
8,
re,
),
createVNode(
o,
{
modelValue: unref(U),
"onUpdate:modelValue": (n[1] ||= (e) =>
isRef(U) ? (U.value = e) : null),
options: unref(X),
"option-label": `desc`,
"option-value": `value`,
"aria-labelledby": `${unref(P)}-peak-label`,
disabled: unref(H),
placeholder: `选择防御配置`,
onChange: $,
},
null,
8,
[
`modelValue`,
`options`,
`aria-labelledby`,
`disabled`,
],
),
unref(W)
? (openBlock(),
createBlock(y, {
key: 0,
height: `60px`,
}))
: unref(K)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(`p`, null, [
(n[11] ||= createTextVNode(
`本次费用:`,
-1,
)),
createElementVNode(
`strong`,
null,
`¥` +
toDisplayString(unref(K).price),
1,
),
]),
unref(K).renew_price_difference ==
null
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
ie,
`续费差价:¥` +
toDisplayString(
unref(K)
.renew_price_difference,
),
1,
)),
unref(K).description
? (openBlock(),
createElementBlock(
`p`,
ae,
toDisplayString(
unref(K).description,
),
1,
))
: createCommentVNode(``, !0),
],
64,
))
: createCommentVNode(``, !0),
unref(G)
? (openBlock(),
createBlock(
i,
{
key: 2,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(G)),
1,
),
!unref(H) && !unref(K)
? (openBlock(),
createBlock(l, {
key: 0,
label: `重试报价`,
text: ``,
size: `small`,
onClick: $,
}))
: createCommentVNode(``, !0),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
i,
{
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(n[12] ||= [
createTextVNode(
`确认后将创建调整订单,请核对费用后完成付款。`,
-1,
),
]),
]),
_: 1,
},
),
]),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
)),
],
64,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-2f38c55b`]],
),
{
__name: `DcimDefence`,
},
);
export {};
export default M;
</script>
+356
View File
@@ -0,0 +1,356 @@
<script>
import "~/assets/styles/DcimDomains.BT2s5hGW.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { NuxtLink } from "#components";
import { sanitizeMessage } from "~/lib/auth.js";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { r as dict_r } from "~/lib/dict.js";
import datatable from "primevue/datatable";
import paginator from "primevue/paginator";
import column from "primevue/column";
import tag from "primevue/tag";
var E = {
class: `domains`,
},
D = {
class: `toolbar`,
},
O = {
class: `empty`,
},
k = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimDomains`,
props: {
hostId: {},
},
setup(f) {
let y = f,
k = useApi(),
A = ref(null),
j = ref(``),
M = ref(!1),
N = ref([]),
P = ref(0),
F = ref(0),
I = 0,
L = !1;
async function R() {
let e = ++I,
t = y.hostId;
((M.value = !0), (j.value = ``), (N.value = []));
try {
let n = await k.get(`/domain_whitelist/host`);
if (L || e !== I || t !== y.hostId) return;
A.value = (n.list || []).some((e) => String(e.id) === t);
let r = await k.get(`/domain_whitelist/record`, {
host_id: t,
page: P.value + 1,
limit: 10,
});
if (L || e !== I || t !== y.hostId) return;
((N.value = r.list || []), (F.value = Number(r.count || 0)));
} catch (t) {
!L &&
e === I &&
(j.value =
t instanceof Error ? t.message : `域名白名单加载失败`);
} finally {
!L && e === I && (M.value = !1);
}
}
return (
watch(
() => y.hostId,
() => {
((A.value = null), (P.value = 0), R());
},
),
onMounted(R),
onBeforeUnmount(() => {
((L = !0), I++);
}),
(t, n) => {
let r = message,
a = NuxtLink,
_ = button,
y = column,
k = tag,
I = datatable,
L = paginator;
return (
openBlock(),
createElementBlock(`div`, E, [
createVNode(
r,
{
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(n[1] ||= [
createTextVNode(
`域名白名单用于为当前实例提交域名访问申请,审核结果以平台记录为准。`,
-1,
),
]),
]),
_: 1,
},
),
createElementVNode(`div`, D, [
(n[3] ||= createElementVNode(`h3`, null, `域名白名单`, -1)),
unref(A)
? (openBlock(),
createBlock(
a,
{
key: 0,
class: `p-button p-button-sm`,
to: {
path: `/security/domain-whitelist`,
query: {
host_id: f.hostId,
},
},
},
{
default: withCtx(() => [
...(n[2] ||= [
createElementVNode(
`i`,
{
class: `pi pi-plus`,
"aria-hidden": `true`,
},
null,
-1,
),
createTextVNode(`管理 / 添加域名`, -1),
]),
]),
_: 1,
},
8,
[`to`],
))
: createCommentVNode(``, !0),
createVNode(
_,
{
label: `刷新`,
icon: `pi pi-refresh`,
severity: `secondary`,
text: ``,
size: `small`,
loading: unref(M),
onClick: R,
},
null,
8,
[`loading`],
),
]),
unref(j)
? (openBlock(),
createBlock(
r,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(j)), 1),
]),
_: 1,
},
))
: unref(A) === !1
? (openBlock(),
createBlock(
r,
{
key: 1,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(n[4] ||= [
createTextVNode(
`此实例尚未配置可用的域名白名单入口,暂不能提交新域名。`,
-1,
),
]),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
I,
{
value: unref(N),
loading: unref(M),
"data-key": `id`,
scrollable: ``,
},
{
empty: withCtx(() => [
createElementVNode(
`div`,
O,
toDisplayString(
unref(j) ? `记录暂不可用` : `暂无域名记录`,
),
1,
),
]),
default: withCtx(() => [
createVNode(
y,
{
header: `域名`,
},
{
body: withCtx(({ data: t }) => [
createTextVNode(
toDisplayString(t.domains?.join(`、`) || `—`),
1,
),
]),
_: 1,
},
),
createVNode(
y,
{
header: `状态`,
},
{
body: withCtx(({ data: e }) => [
createVNode(
k,
{
value:
e.status === 1
? `已通过`
: e.status === -1
? `已驳回`
: `处理中`,
severity:
e.status === 1
? `success`
: e.status === -1
? `danger`
: `warn`,
},
null,
8,
[`value`, `severity`],
),
]),
_: 1,
},
),
createVNode(
y,
{
header: `驳回原因`,
},
{
body: withCtx(({ data: t }) => [
createTextVNode(
toDisplayString(
unref(sanitizeMessage)(t.reject_reason) ||
`—`,
),
1,
),
]),
_: 1,
},
),
createVNode(y, {
field: `remark`,
header: `备注`,
}),
createVNode(
y,
{
header: `创建时间`,
},
{
body: withCtx(({ data: n }) => [
createTextVNode(
toDisplayString(
(`formatTime` in t
? t.formatTime
: unref(dict_r))(n.create_time),
),
1,
),
]),
_: 1,
},
),
]),
_: 1,
},
8,
[`value`, `loading`],
),
unref(F) > 10
? (openBlock(),
createBlock(
L,
{
key: 2,
rows: 10,
first: unref(P) * 10,
"total-records": unref(F),
onPage: (n[0] ||= (e) => {
((P.value = e.page), R());
}),
},
null,
8,
[`first`, `total-records`],
))
: createCommentVNode(``, !0),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-6c2c5ee1`]],
),
{
__name: `DcimDomains`,
},
);
export {};
export default k;
</script>
File diff suppressed because it is too large. Load diff
+343
View File
@@ -0,0 +1,343 @@
<script>
import "~/assets/styles/DcimMonitor.CiStTCbZ.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { normalizeClass } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { defineAsyncComponent } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { normalizeStyle } from "vue";
import { loadModule } from "~/utils/load-module.js";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import skeleton from "primevue/skeleton";
import selectbutton from "primevue/selectbutton";
var T = defineAsyncComponent(() =>
loadModule(
() => import("~/components/ChartBox.vue").then((e) => e.default || e),
[],
import.meta.url,
),
),
E = {
class: `monitor-panel`,
},
D = {
key: 0,
class: `monitor-head`,
},
O = {
class: `legend`,
},
k = [`aria-busy`],
A = {
key: 1,
role: `alert`,
class: `monitor-error`,
},
j = {
key: 3,
class: `empty`,
},
M = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimMonitor`,
props: {
hostId: {},
module: {},
compact: {
type: Boolean,
default: !1,
},
},
setup(a) {
let h = a,
y = useApi(),
S = ref(3600),
M = [
{
label: `1 小时`,
value: 3600,
},
{
label: `24 小时`,
value: 86400,
},
{
label: `7 天`,
value: 604800,
},
{
label: `1 个月`,
value: 2592e3,
},
{
label: `1 年`,
value: 31536e3,
},
],
N = ref(!1),
P = ref(``),
F = ref([]),
I = ref(``),
L = 0,
R = !1,
z = ``;
async function B() {
let e = ++L,
t = h.hostId,
n = h.module,
r = `${n}:${t}:${S.value}`;
(r !== z && ((F.value = []), (I.value = ``)),
(z = r),
(N.value = !0),
(P.value = ``));
try {
let r = await y.get(`/${n}/${t}/chart`, {
start_time: Math.floor(Date.now() / 1e3) - S.value,
});
if (R || e !== L || t !== h.hostId || n !== h.module) return;
((F.value = (Array.isArray(r.list) ? r.list : []).filter((e) =>
Number.isFinite(Number(e.time)),
)),
(I.value = typeof r.unit == `string` ? r.unit : ``));
} catch (t) {
!R &&
e === L &&
(P.value = t instanceof Error ? t.message : `带宽监控加载失败`);
} finally {
!R && e === L && (N.value = !1);
}
}
function V(e) {
return e != null && e !== `` && Number.isFinite(Number(e))
? Number(e)
: null;
}
let H = computed(() =>
F.value.some((e) => V(e.in_bw) !== null || V(e.out_bw) !== null),
),
U = computed(() => ({
color: [`#1687d9`, `#29b6d8`],
tooltip: {
trigger: `axis`,
},
grid: {
left: 8,
right: 8,
top: h.compact ? 10 : 30,
bottom: 8,
outerBoundsMode: `same`,
outerBoundsContain: `axisLabel`,
},
xAxis: {
type: `category`,
boundaryGap: !1,
data: F.value.map((e) =>
new Date(Number(e.time) * 1e3).toLocaleTimeString(`zh-CN`, {
hour: `2-digit`,
minute: `2-digit`,
}),
),
},
yAxis: {
type: `value`,
name: I.value,
min: 0,
splitNumber: h.compact ? 2 : 5,
},
series: [`in_bw`, `out_bw`].map((e, t) => ({
name: t ? `出站` : `入站`,
type: `line`,
showSymbol: !0,
symbol: `circle`,
symbolSize: h.compact ? 3 : 4,
smooth: 0.25,
lineStyle: {
width: 1.5,
},
areaStyle: {
opacity: 0.14,
},
connectNulls: !1,
data: F.value.map((t) => V(t[e])),
})),
}));
return (
watch([() => h.hostId, () => h.module, S], B),
onMounted(B),
onBeforeUnmount(() => {
((R = !0), L++);
}),
(t, r) => {
let i = selectbutton,
s = skeleton,
l = button,
h = T;
return (
openBlock(),
createElementBlock(
`section`,
{
class: normalizeClass([
`monitor`,
{
compact: a.compact,
},
]),
},
[
a.compact
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
i,
{
key: 0,
modelValue: unref(S),
"onUpdate:modelValue": (r[0] ||= (e) =>
isRef(S) ? (S.value = e) : null),
class: `range`,
options: M,
"option-label": `label`,
"option-value": `value`,
"allow-empty": !1,
"aria-label": `监控时间范围`,
},
null,
8,
[`modelValue`],
)),
createElementVNode(`div`, E, [
a.compact
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, D, [
...(r[1] ||= [
createElementVNode(`h3`, null, `网络带宽`, -1),
]),
])),
createElementVNode(`div`, O, [
(r[2] ||= createElementVNode(
`span`,
null,
[
createElementVNode(`i`, {
class: `incoming`,
}),
createTextVNode(`入站`),
],
-1,
)),
(r[3] ||= createElementVNode(
`span`,
null,
[
createElementVNode(`i`, {
class: `outgoing`,
}),
createTextVNode(`出站`),
],
-1,
)),
createElementVNode(
`small`,
null,
toDisplayString(unref(I) || `单位未返回`),
1,
),
]),
createElementVNode(
`div`,
{
class: `chart-viewport`,
style: normalizeStyle({
"--chart-height": a.compact ? `126px` : `320px`,
}),
"aria-busy": unref(N),
},
[
unref(N) && !unref(H)
? (openBlock(),
createBlock(
s,
{
key: 0,
height: a.compact ? `126px` : `320px`,
},
null,
8,
[`height`],
))
: unref(P)
? (openBlock(),
createElementBlock(`div`, A, [
createElementVNode(
`span`,
null,
toDisplayString(unref(P)),
1,
),
createVNode(l, {
label: `重试`,
text: ``,
size: `small`,
onClick: B,
}),
]))
: unref(H)
? (openBlock(),
createBlock(
h,
{
key: 2,
option: unref(U),
height: a.compact ? 126 : 320,
loading: unref(N),
},
null,
8,
[`option`, `height`, `loading`],
))
: (openBlock(),
createElementBlock(
`p`,
j,
`所选时段暂无带宽采样`,
)),
],
12,
k,
),
]),
],
2,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-eb47944f`]],
),
{
__name: `DcimMonitor`,
},
);
export {};
export default M;
</script>
@@ -0,0 +1,163 @@
<script>
import "~/assets/styles/DcimReinstallStatus.CuXeXmZ3.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { ref } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
var m = {
class: `task-status`,
},
h = {
key: 0,
role: `status`,
},
g = [`aria-label`, `title`],
_ = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimReinstallStatus`,
props: {
hostId: {},
module: {},
refreshVersion: {},
},
setup(c) {
let p = c,
_ = useApi(),
v = ref(!1),
y = ref(``),
b = ref(!1),
x = ref(!1),
S = 0,
C = !1,
w = 0,
T;
function E() {
T = setTimeout(() => {
if (!C) {
if (
document.visibilityState !== `visible` ||
document.querySelector(`.p-dialog-mask`)
) {
E();
return;
}
D(!1);
}
}, 1e4);
}
async function D(e = !0) {
if (v.value || C) return;
(clearTimeout(T), e && (w = 0));
let t = ++S;
((v.value = !0), (y.value = ``));
try {
let e = await _.get(`/${p.module}/${p.hostId}/reinstall_status`);
if (C || t !== S) return;
if (
!Array.isArray(e) ||
e.some(
(e) =>
!e ||
e.task_type === null ||
e.task_type === void 0 ||
!Number.isInteger(Number(e.task_type)),
)
)
throw Error(`重装任务状态响应无效`);
((x.value = e.some((e) => Number(e.task_type) === 0)),
(b.value = !0),
x.value && ++w < 60 && E());
} catch (e) {
!C &&
t === S &&
(y.value =
e instanceof Error ? e.message : `重装任务状态加载失败`);
} finally {
t === S && (v.value = !1);
}
}
return (
watch(
[() => p.hostId, () => p.module, () => p.refreshVersion],
() => {
(S++, clearTimeout(T), (v.value = !1), (b.value = !1), D());
},
),
onMounted(D),
onBeforeUnmount(() => {
((C = !0), S++, clearTimeout(T));
}),
(t, n) => {
let r = button;
return (
openBlock(),
createElementBlock(`div`, m, [
unref(b) && !unref(y)
? (openBlock(),
createElementBlock(
`span`,
h,
toDisplayString(
unref(x)
? `系统正在重装,请等待任务结束`
: `当前未检测到进行中的重装任务`,
),
1,
))
: createCommentVNode(``, !0),
unref(y)
? (openBlock(),
createElementBlock(
`span`,
{
key: 1,
class: `task-error`,
role: `alert`,
"aria-label": `重装任务状态加载失败:${unref(y)}`,
title: unref(y),
},
`重装状态加载失败,可点刷新重试`,
8,
g,
))
: createCommentVNode(``, !0),
createVNode(
r,
{
label: `刷新重装状态`,
icon: `pi pi-refresh`,
text: ``,
size: `small`,
loading: unref(v),
onClick: (n[0] ||= (e) => D()),
},
null,
8,
[`loading`],
),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-d99d9473`]],
),
{
__name: `DcimReinstallStatus`,
},
);
export {};
export default _;
</script>
+613
View File
@@ -0,0 +1,613 @@
<script>
import "~/assets/styles/ConfigBandwidth.CWSH1WJZ.css";
import "~/assets/styles/DcimUpgrade.DaLApYFa.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { reactive } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import ConfigBandwidth from "~/components/config/ConfigBandwidth.vue";
var T = {
key: 0,
class: `dcim-upgrade`,
},
E = {
key: 1,
},
te = {
key: 2,
},
D = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `DcimUpgrade`,
props: {
hostId: {},
productId: {},
module: {},
current: {},
upgradeAllowed: {
type: Boolean,
},
},
emits: [`pay`],
setup(h, { expose: b, emit: D }) {
let O = h,
k = D,
A = useApi(),
j = ref(null),
M = computed(() => O.current.model_config ?? {}),
N = [`memory`, `disk`, `gpu`],
P = {
memory: `内存`,
disk: `硬盘`,
gpu: `显卡`,
},
F = reactive({
bw: 0,
flow: 0,
ip_num: 0,
peak_defence: 0,
optional_memory: {},
optional_disk: {},
optional_gpu: {},
}),
I = ref(!1),
L = ref(!1),
R = ref(!1),
z = ref(``),
B = ref(``),
V = ref(``),
H = 0,
U = 0,
W = !1,
G = ``,
K = ``,
q = computed(() => JSON.stringify([O.hostId, O.module, F])),
J = computed(() => q.value !== K),
ne = (e = []) =>
e
.filter(
(e) => e.value !== `` && Number.isFinite(Number(e.value)),
)
.map((e) => ({
value: Number(e.value),
label: String(e.value_show || e.desc || e.value),
})),
re = (e = []) =>
e.some((e) => e.min_value !== void 0 && e.max_value !== void 0),
Y = computed(() =>
[
...(j.value?.bill_type === `flow`
? [
{
key: `flow`,
label: `流量配额`,
options: j.value.flow ?? [],
},
]
: []),
{
key: `ip_num`,
label: `IPv4 数量`,
options: j.value?.ip ?? [],
},
{
key: `peak_defence`,
label: `防御峰值`,
options: j.value?.defence ?? [],
},
].filter((e) => e.options.length),
);
function ie(e, t) {
return (
Number.isFinite(e) &&
t.some((t) => {
if (
t.min_value === void 0 ||
t.max_value === void 0 ||
t.type === `radio`
)
return Number(t.value) === e;
let n = Number(t.step ?? 1);
return (
n > 0 &&
e >= Number(t.min_value) &&
e <= Number(t.max_value) &&
Math.abs(
(e - Number(t.min_value)) / n -
Math.round((e - Number(t.min_value)) / n),
) < 1e-7
);
})
);
}
let X = (e) => M.value[`optional_${e}`] ?? [];
function Z() {
(H++, (B.value = ``), (V.value = ``), (G = ``), (L.value = !1));
}
function ae() {
for (let e of [`bw`, `flow`, `ip_num`, `peak_defence`])
F[e] = Number(O.current[e] ?? 0);
for (let e of N) {
let t = O.current[`optional_${e}`];
F[`optional_${e}`] =
t && typeof t == `object` && !Array.isArray(t)
? Object.fromEntries(
Object.entries(t).map(([e, t]) => [e, Number(t)]),
)
: {};
}
((K = q.value), Z());
}
async function Q() {
if (O.upgradeAllowed === !1 || W) return;
let e = ++U;
(ae(), (I.value = !0), (z.value = ``), (j.value = null));
try {
let t = Number(O.current.line?.id);
if (!Number.isSafeInteger(t) || t <= 0)
throw Error(`实例线路信息无效,请刷新后重试`);
let n = await A.get(
`/product/${O.productId}/${O.module}/line/${t}`,
);
!W && e === U && (j.value = n);
} catch (t) {
!W &&
e === U &&
(z.value = t instanceof Error ? t.message : `升级配置加载失败`);
} finally {
e === U && (I.value = !1);
}
}
function oe() {
for (let e of N) {
let t = F[`optional_${e}`],
n = O.current[`optional_${e}`] ?? {},
r = new Set([
...X(e).map((e) => String(e.id)),
...Object.keys(n),
]);
if (
Object.entries(t).some(
([e, t]) => !r.has(e) || !Number.isSafeInteger(t) || t < 0,
)
)
throw Error(`${P[e]}数量无效`);
let i =
Object.values(t).reduce((e, t) => e + t, 0) -
Object.values(n).reduce((e, t) => e + Number(t), 0),
a = M.value[`max_${e}_num`];
if (a !== void 0 && i > Number(a))
throw Error(`${P[e]}数量超过剩余槽位`);
}
if (!j.value) throw Error(`请先加载有效的升级配置`);
let e = [
...Y.value,
...(j.value.bill_type === `bw`
? [
{
key: `bw`,
label: `带宽`,
options: j.value.bw ?? [],
},
]
: []),
];
for (let t of e)
if (
F[t.key] !== Number(O.current[t.key] ?? 0) &&
!ie(F[t.key], t.options)
)
throw Error(`请选择有效的${t.label}档位`);
}
async function $() {
if (O.upgradeAllowed === !1 || R.value || W || !J.value) return;
((z.value = ``), Z());
try {
oe();
} catch (e) {
z.value = e.message;
return;
}
let e = ++H,
t = q.value,
n = JSON.parse(JSON.stringify(F)),
r = {
bw: n.bw,
flow: n.flow,
ip_num: n.ip_num,
peak_defence: n.peak_defence,
};
for (let e of N)
for (let [t, i] of Object.entries(n[`optional_${e}`]))
r[`optional_${e}[${t}]`] = i;
L.value = !0;
try {
let n = await A.get(`/${O.module}/${O.hostId}/common_config`, r);
if (W || e !== H || t !== q.value) return;
if (
n.price === null ||
n.price === void 0 ||
String(n.price).trim() === `` ||
!Number.isFinite(Number(n.price))
)
throw Error(`升级报价无效,请重试`);
((B.value = String(n.price)),
(V.value = n.description ?? ``),
(G = t));
} catch (t) {
!W &&
e === H &&
(z.value = t instanceof Error ? t.message : `升级询价失败`);
} finally {
e === H && (L.value = !1);
}
}
async function se() {
if (
O.upgradeAllowed === !1 ||
R.value ||
L.value ||
!J.value ||
!B.value ||
G !== q.value ||
W
)
return;
let e = q.value,
t = B.value,
n = JSON.parse(JSON.stringify(F));
((R.value = !0), (z.value = ``));
try {
let r = await A.post(
`/${O.module}/${O.hostId}/common_config/order`,
n,
);
if (W || e !== q.value) return;
if (!/^[1-9]\d*$/.test(String(r.id)))
throw Error(`升级订单无效,请重试`);
(Z(),
k(`pay`, {
order_id: r.id,
amount: t,
}));
} catch (t) {
!W &&
e === q.value &&
(z.value = t instanceof Error ? t.message : `升级订单创建失败`);
} finally {
W || (R.value = !1);
}
}
return (
watch(F, Z, {
deep: !0,
flush: `sync`,
}),
watch(
[
() => O.hostId,
() => O.module,
() => O.current,
() => O.upgradeAllowed,
],
() => {
(U++, Z(), Q());
},
{
flush: `sync`,
},
),
onMounted(Q),
onBeforeUnmount(() => {
((W = !0), H++, U++);
}),
b({
busy: R,
}),
(n, r) => {
let i = message,
o = button,
l = ConfigBandwidth,
u = inputnumber,
v = select;
return h.upgradeAllowed === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, T, [
unref(z)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(z)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(j)
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
o,
{
key: 1,
label: `加载升级配置`,
text: ``,
loading: unref(I),
onClick: Q,
},
null,
8,
[`loading`],
)),
unref(j)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
unref(j).bill_type === `bw` && unref(j).bw?.length
? (openBlock(),
createBlock(
l,
{
key: 0,
modelValue: unref(F).bw,
"onUpdate:modelValue": (r[0] ||= (e) =>
(unref(F).bw = e)),
options: unref(j).bw,
disabled: unref(R),
onChange: $,
},
null,
8,
[`modelValue`, `options`, `disabled`],
))
: createCommentVNode(``, !0),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(Y),
(t) => (
openBlock(),
createElementBlock(
`label`,
{
key: t.key,
},
[
createTextVNode(
toDisplayString(t.label),
1,
),
re(t.options)
? (openBlock(),
createBlock(
u,
{
key: 0,
modelValue: unref(F)[t.key],
"onUpdate:modelValue": (e) =>
(unref(F)[t.key] = e),
min: 0,
disabled: unref(R),
"use-grouping": !1,
},
null,
8,
[
`modelValue`,
`onUpdate:modelValue`,
`disabled`,
],
))
: (openBlock(),
createBlock(
v,
{
key: 1,
modelValue: unref(F)[t.key],
"onUpdate:modelValue": (e) =>
(unref(F)[t.key] = e),
options: ne(t.options),
"option-label": `label`,
"option-value": `value`,
disabled: unref(R),
},
null,
8,
[
`modelValue`,
`onUpdate:modelValue`,
`options`,
`disabled`,
],
)),
],
)
),
),
128,
)),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
N.filter((e) => X(e).length),
(n) => (
openBlock(),
createElementBlock(
`fieldset`,
{
key: n,
},
[
createElementVNode(
`legend`,
null,
toDisplayString(P[n]) + `配置`,
1,
),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
X(n),
(t) => (
openBlock(),
createElementBlock(
`label`,
{
key: t.id,
},
[
createTextVNode(
toDisplayString(t.value),
1,
),
createVNode(
u,
{
modelValue:
unref(F)[`optional_${n}`][
String(t.id)
],
"onUpdate:modelValue": (
e,
) =>
(unref(F)[
`optional_${n}`
][String(t.id)] = e),
min: 0,
max:
Number(
unref(M)[
`max_${n}_num`
] ?? 99,
) +
Number(
h.current[
`optional_${n}`
]?.[String(t.id)] ?? 0,
),
disabled: unref(R),
"use-grouping": !1,
},
null,
8,
[
`modelValue`,
`onUpdate:modelValue`,
`max`,
`disabled`,
],
),
],
)
),
),
128,
)),
],
)
),
),
128,
)),
createVNode(
o,
{
label: `计算变更费用`,
outlined: ``,
loading: unref(L),
disabled: unref(R) || !unref(J),
onClick: $,
},
null,
8,
[`loading`, `disabled`],
),
unref(B) === ``
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
E,
`变更费用:¥` + toDisplayString(unref(B)),
1,
)),
unref(V)
? (openBlock(),
createElementBlock(
`p`,
te,
toDisplayString(unref(V)),
1,
))
: createCommentVNode(``, !0),
createVNode(
o,
{
label: `确认生成升级订单`,
loading: unref(R),
disabled:
unref(B) === `` || unref(L) || !unref(J),
onClick: se,
},
null,
8,
[`loading`, `disabled`],
),
],
64,
))
: createCommentVNode(``, !0),
]));
}
);
},
}),
[[`__scopeId`, `data-v-790898bc`]],
),
{
__name: `DcimUpgrade`,
},
);
export {};
export default D;
</script>
+681
View File
@@ -0,0 +1,681 @@
<script>
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { normalizeClass } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { r as dict_r } from "~/lib/dict.js";
import OperationNotice from "~/components/OperationNotice.vue";
import tag from "primevue/tag";
import { n as complete_list_n } from "~/lib/complete-list.js";
var oe = {
key: 1,
class: `block`,
},
se = {
class: `info-table`,
},
C = {
key: 0,
class: `kv`,
},
w = {
class: `kv`,
},
T = {
class: `action-cell`,
},
E = {
key: 0,
class: `pk-empty`,
role: `status`,
},
ce = {
key: 2,
class: `pk-empty`,
},
le = {
key: 1,
class: `kv`,
},
ue = {
class: `pk-list`,
},
de = {
class: `pk-name`,
},
fe = {
class: `col-mono`,
},
D = {
class: `pk-expire`,
},
O = {
key: 0,
class: `pk-empty`,
role: `status`,
},
k = {
key: 2,
class: `pk-empty`,
},
A = {
key: 3,
class: `pk-grid`,
},
j = {
class: `pk-card-name`,
},
M = {
class: `pk-card-cap`,
},
N = {
class: `pk-card-price`,
},
P = {
class: `pk-card-tags`,
},
F = {
key: 1,
class: `pk-card-note`,
},
I = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `FlowPacketPanel`,
props: {
hostId: {},
flow: {},
module: {
default: `mf_cloud`,
},
mode: {
default: `panel`,
},
},
emits: [`pay`],
setup(_, { emit: S }) {
let I = _,
L = S,
R = useApi(),
z = ref([]),
B = ref([]),
V = ref(!1),
H = ref(``),
U = ref(``),
W = computed(() => {
let e = I.flow?.flow_packet?.leave_size;
if (![`mf_cloud`, `remf_cloud`].includes(I.module) || e == null)
return null;
let t = Number(e);
return Number.isFinite(t) && t >= 0 ? t : null;
});
function G(e) {
let t = Number(e ?? 0);
return t
? t >= 1024
? `${(t / 1024).toFixed(2)} TB`
: `${t} GB`
: `0`;
}
let K = 0,
q = 0,
J = !1;
async function Y() {
if (J || !I.hostId) return;
let e = ++K,
t = I.hostId,
n = I.module,
r = () => !J && e === K && t === I.hostId && n === I.module;
((V.value = !0),
(H.value = ``),
(U.value = ``),
(z.value = []),
(B.value = []));
try {
await Promise.all([
(async () => {
try {
let e = await R.get(`/host/${t}/flow_packet`, {
page: 1,
limit: 100,
});
r() && (z.value = e.list ?? []);
} catch (e) {
r() &&
(H.value =
e instanceof Error
? e.message
: `流量包加载失败,请重试`);
}
})(),
[`mf_cloud`, `remf_cloud`].includes(n) && I.mode === `panel`
? (async () => {
try {
let e = await complete_list_n(
(e, r) =>
R.get(`/${n}/${t}/traffic_package`, {
page: e,
limit: r,
}),
r,
);
r() && (B.value = e);
} catch (e) {
r() &&
(U.value =
e instanceof Error
? e.message
: `已购流量包加载失败,请重试`);
}
})()
: Promise.resolve(),
]);
} finally {
r() && (V.value = !1);
}
}
let X = ref(!1),
Z = ref(null),
Q = ref(``);
async function $() {
((Q.value = ``), (X.value = !0), await Y());
}
async function pe(e) {
if (
J ||
Z.value !== null ||
V.value ||
H.value ||
!I.hostId ||
!z.value.some((t) => t.id === e.id) ||
e.billing_mode !== 0 ||
e.monthly_purchase_limit_reached === 1
)
return;
let t = ++q,
n = I.hostId,
r = I.module,
i = () => !J && t === q && n === I.hostId && r === I.module;
((Q.value = ``), (Z.value = e.id));
try {
let t = await R.post(`/host/${n}/flow_packet_order`, {
id: n,
flow_packet_id: e.id,
});
if (!i()) return;
if (!/^[1-9]\d*$/.test(String(t.id)))
throw Error(`流量包订单无效,请重试`);
((X.value = !1),
L(`pay`, {
order_id: t.id,
amount: e.price,
}));
} catch (e) {
i() &&
(Q.value =
e instanceof Error ? e.message : `下单失败,请稍后重试`);
} finally {
i() && (Z.value = null);
}
}
return (
onMounted(() => {
if (I.mode === `panel`) return Y();
}),
watch(
() => [I.hostId, I.module],
() => {
if (
(K++,
q++,
(z.value = []),
(B.value = []),
(H.value = ``),
(U.value = ``),
(Q.value = ``),
(V.value = !1),
(Z.value = null),
(X.value = !1),
I.mode === `panel`)
)
return Y();
},
),
onBeforeUnmount(() => {
((J = !0), K++, q++);
}),
(n, i) => {
let a = OperationNotice,
s = button,
u = message,
b = tag,
S = dialog;
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createVNode(
a,
{
message: unref(Q),
severity: `error`,
},
null,
8,
[`message`],
),
_.mode === `button`
? (openBlock(),
createBlock(s, {
key: 0,
label: `购买流量包`,
icon: `pi pi-plus`,
fluid: ``,
onClick: $,
}))
: (openBlock(),
createElementBlock(`section`, oe, [
(i[4] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`流量包`,
-1,
)),
(i[5] ||= createElementVNode(
`p`,
{
class: `block-desc`,
},
` 购买流量包可补充当前实例的可用流量,容量和有效期以套餐为准。 `,
-1,
)),
createElementVNode(`div`, se, [
unref(W) === null
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, C, [
(i[1] ||= createElementVNode(
`span`,
null,
`流量包剩余`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(G(unref(W))),
1,
),
])),
createElementVNode(`div`, w, [
(i[2] ||= createElementVNode(
`span`,
null,
`流量包购买`,
-1,
)),
createElementVNode(`div`, T, [
unref(V)
? (openBlock(),
createElementBlock(`p`, E, `流量包加载中…`))
: unref(H)
? (openBlock(),
createBlock(
u,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(H)) + ` `,
1,
),
createVNode(s, {
label: `重试`,
size: `small`,
severity: `secondary`,
text: ``,
onClick: Y,
}),
]),
_: 1,
},
))
: unref(z).length
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
ce,
`该实例暂无可购流量包`,
)),
unref(z).length
? (openBlock(),
createBlock(s, {
key: 3,
label: `购买流量包`,
icon: `pi pi-plus`,
size: `small`,
severity: `secondary`,
outlined: ``,
onClick: $,
}))
: createCommentVNode(``, !0),
]),
]),
unref(B).length || unref(U)
? (openBlock(),
createElementBlock(`div`, le, [
(i[3] ||= createElementVNode(
`span`,
null,
`已购流量包`,
-1,
)),
createElementVNode(`div`, ue, [
unref(U)
? (openBlock(),
createBlock(
u,
{
key: 0,
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(U)) + ` `,
1,
),
createVNode(s, {
label: `重试`,
size: `small`,
severity: `secondary`,
text: ``,
onClick: Y,
}),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(B),
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t.id,
class: `pk-row`,
},
[
createElementVNode(
`span`,
de,
toDisplayString(t.name),
1,
),
createElementVNode(`span`, fe, [
createTextVNode(
toDisplayString(G(t.size)),
1,
),
t.used
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`(已用 ` +
toDisplayString(
G(t.used),
) +
`)`,
1,
),
],
64,
))
: createCommentVNode(``, !0),
]),
createElementVNode(
`span`,
D,
toDisplayString(
t.expire_time
? `${(`formatTime` in n ? n.formatTime : unref(dict_r))(t.expire_time)} 到期`
: `不限时`,
),
1,
),
],
)
),
),
128,
)),
]),
]))
: createCommentVNode(``, !0),
]),
])),
createVNode(
S,
{
visible: unref(X),
"onUpdate:visible": (i[0] ||= (e) =>
isRef(X) ? (X.value = e) : null),
header: `购买流量包`,
modal: ``,
style: {
width: `600px`,
maxWidth: `calc(100vw - 32px)`,
},
closable: unref(Z) === null,
"close-on-escape": unref(Z) === null,
},
{
default: withCtx(() => [
unref(V)
? (openBlock(),
createElementBlock(`div`, O, `流量包加载中…`))
: unref(H)
? (openBlock(),
createBlock(
u,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(H)) + ` `,
1,
),
createVNode(s, {
label: `重试`,
size: `small`,
severity: `secondary`,
text: ``,
onClick: Y,
}),
]),
_: 1,
},
))
: unref(z).length
? (openBlock(),
createElementBlock(`div`, A, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(z),
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t.id,
class: normalizeClass([
`pk-card`,
{
"pk-card-disabled":
t.billing_mode !== 0 ||
t.monthly_purchase_limit_reached ===
1,
},
]),
},
[
createElementVNode(
`div`,
j,
toDisplayString(t.name),
1,
),
createElementVNode(
`div`,
M,
toDisplayString(t.capacity) +
` GB`,
1,
),
createElementVNode(
`div`,
N,
`¥` + toDisplayString(t.price),
1,
),
createElementVNode(`div`, P, [
t.long_term_valid === 1
? (openBlock(),
createBlock(b, {
key: 0,
value: `长期有效`,
severity: `success`,
}))
: createCommentVNode(``, !0),
t.monthly_purchase_limit
? (openBlock(),
createBlock(
b,
{
key: 1,
value: `本月还可购 ${t.monthly_purchase_left ?? 0} 份`,
severity: `secondary`,
},
null,
8,
[`value`],
))
: createCommentVNode(``, !0),
]),
t.billing_mode === 0
? (openBlock(),
createBlock(
s,
{
key: 0,
label: `购买`,
size: `small`,
loading:
unref(Z) === t.id,
disabled:
unref(Z) !== null ||
t.monthly_purchase_limit_reached ===
1,
onClick: (e) => pe(t),
},
null,
8,
[
`loading`,
`disabled`,
`onClick`,
],
))
: (openBlock(),
createElementBlock(
`span`,
F,
`按 GB 计费,请联系客服购买`,
)),
],
2,
)
),
),
128,
)),
]))
: (openBlock(),
createElementBlock(
`div`,
k,
`该实例暂无可购流量包`,
)),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
],
64,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-ca0029df`]],
),
{
__name: `FlowPacketPanel`,
},
);
export {};
export default I;
</script>
@@ -0,0 +1,275 @@
<script>
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
import { toDisplayString } from "vue";
import { onBeforeUnmount } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import message from "primevue/message";
import PaymentDialog from "~/components/PaymentDialog.vue";
var C = {
key: 0,
},
w = Object.assign(
defineComponent({
__name: `ImagePurchaseDialog`,
props: {
modelValue: {
default: null,
},
modelModifiers: {},
},
emits: mergeModels([`authorized`], [`update:modelValue`]),
setup(n, { emit: h }) {
let w = useModel(n, `modelValue`),
T = h,
E = useApi(),
D = ref(!1),
O = ref(``),
k = ref(!1),
A = ref(null),
j = new Map(),
M = 0,
N = !1,
P = (e) => `${e.module}:${e.hostId}:${e.imageId}`;
function F(e) {
if (
(typeof e != `string` && typeof e != `number`) ||
String(e).trim() === `` ||
!Number.isFinite(Number(e)) ||
Number(e) < 0
)
throw Error(`镜像费用信息无效,请重试`);
return Number(e).toFixed(2);
}
async function I() {
let e = w.value;
if (!e || D.value || N) return;
let t = M,
n = () => !N && M === t && w.value === e;
((D.value = !0), (O.value = ``));
try {
let t = await E.get(`/${e.module}/${e.hostId}/image/check`, {
image_id: e.imageId,
});
if (!n()) return;
let r = F(t.price);
if (Number(r) === 0) {
((w.value = null), T(`authorized`));
return;
}
if (r !== F(e.price)) {
((w.value = {
...e,
price: r,
}),
(O.value = `镜像费用已更新,请确认最新金额`));
return;
}
let i = j.get(P(e));
if (!i) {
let t = await E.post(`/${e.module}/${e.hostId}/image/order`, {
image_id: e.imageId,
});
if (!/^[1-9]\d*$/.test(String(t.id)))
throw Error(`镜像购买订单无效,请重试`);
((i = t.id), j.set(P(e), i));
}
if (!n()) return;
((A.value = i), (k.value = !0));
} catch (e) {
n() &&
(O.value = e instanceof Error ? e.message : `创建镜像订单失败`);
} finally {
t === M && (D.value = !1);
}
}
async function L() {
let e = w.value;
if (!e || N) return;
let t = M;
((D.value = !0), (O.value = ``), (k.value = !1));
try {
let n = await E.get(`/${e.module}/${e.hostId}/image/check`, {
image_id: e.imageId,
});
if (t !== M || N) return;
if (Number(F(n.price)) !== 0)
throw Error(`镜像授权尚未生效,请稍后重新检查`);
(j.delete(P(e)), (w.value = null), T(`authorized`));
} catch (e) {
t === M &&
(O.value = e instanceof Error ? e.message : `镜像授权校验失败`);
} finally {
t === M && (D.value = !1);
}
}
return (
watch(
w,
() => {
(M++,
(D.value = !1),
(k.value = !1),
(O.value = ``),
(A.value = null));
},
{
flush: `sync`,
},
),
onBeforeUnmount(() => {
((N = !0), M++);
}),
(t, n) => {
let r = message,
i = button,
o = dialog,
h = PaymentDialog;
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createVNode(
o,
{
visible: !!w.value && !unref(k),
header: `购买系统镜像`,
modal: ``,
closable: !unref(D),
"close-on-escape": !unref(D),
style: {
width: `480px`,
},
"onUpdate:visible": (n[1] ||= (e) => {
!e && !unref(D) && (w.value = null);
}),
},
{
footer: withCtx(() => [
createVNode(
i,
{
label: `取消`,
outlined: ``,
severity: `secondary`,
disabled: unref(D),
onClick: (n[0] ||= (e) => (w.value = null)),
},
null,
8,
[`disabled`],
),
createVNode(
i,
{
label: `确认购买 / 继续支付`,
loading: unref(D),
onClick: I,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(`p`, null, [
createTextVNode(
`实例 #` +
toDisplayString(w.value?.hostId) +
` 所选镜像需要购买,费用为 `,
1,
),
createElementVNode(
`strong`,
null,
`¥` + toDisplayString(w.value?.price),
1,
),
(n[3] ||= createTextVNode(`。`, -1)),
]),
w.value?.description
? (openBlock(),
createElementBlock(
`p`,
C,
toDisplayString(w.value.description),
1,
))
: createCommentVNode(``, !0),
(n[4] ||= createElementVNode(
`p`,
null,
`支付并确认授权后,请再次确认重装。支付不会自动清除服务器数据。`,
-1,
)),
unref(O)
? (openBlock(),
createBlock(
r,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(O)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
createVNode(
h,
{
modelValue: unref(k),
"onUpdate:modelValue": (n[2] ||= (e) =>
isRef(k) ? (k.value = e) : null),
"order-id": unref(A),
amount: w.value?.price ?? ``,
onSuccess: L,
},
null,
8,
[`modelValue`, `order-id`, `amount`],
),
],
64,
)
);
}
);
},
}),
{
__name: `ImagePurchaseDialog`,
},
);
export {};
export default w;
</script>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,166 @@
<script>
import "~/assets/styles/InstanceLoadingShell.CwfiUwdU.css";
import { renderList } from "vue";
import { normalizeClass } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import skeleton from "primevue/skeleton";
var u = {
class: `shell-tabs`,
"aria-hidden": `true`,
},
d = {
class: `shell-grid`,
"aria-hidden": `true`,
},
f = {
class: `shell-card`,
},
p = {
class: `shell-card shell-secondary`,
},
m = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceLoadingShell`,
props: {
dcim: {
type: Boolean,
default: !1,
},
},
setup(a) {
return (c, m) => {
let h = skeleton;
return (
openBlock(),
createElementBlock(
`div`,
{
class: normalizeClass([
`instance-loading-shell`,
{
dcim: a.dcim,
},
]),
role: `status`,
"aria-label": `正在加载实例管理信息`,
"aria-busy": `true`,
},
[
createElementVNode(`div`, u, [
(openBlock(),
createElementBlock(
Fragment,
null,
renderList([32, 32, 64, 32, 80, 80, 32], (e, t) =>
createElementVNode(
`span`,
{
key: t,
},
[
createVNode(
h,
{
width: `${e}px`,
height: `24px`,
},
null,
8,
[`width`],
),
],
),
),
64,
)),
]),
createElementVNode(`div`, d, [
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(3, (t) =>
createElementVNode(
`div`,
{
key: t,
class: `shell-column`,
},
[
createElementVNode(`div`, f, [
createVNode(h, {
width: `64px`,
height: `24px`,
}),
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(5, (e) =>
createElementVNode(
`div`,
{
key: e,
class: `shell-row`,
},
[
createVNode(h, {
width: `28%`,
height: `24px`,
}),
createVNode(h, {
width: `45%`,
height: `24px`,
}),
],
),
),
64,
)),
createVNode(h, {
height: `40px`,
class: `shell-button`,
}),
]),
createElementVNode(`div`, p, [
createVNode(h, {
width: `64px`,
height: `24px`,
}),
createVNode(h, {
height: `126px`,
}),
createVNode(h, {
width: `70%`,
height: `24px`,
}),
]),
],
),
),
64,
)),
]),
],
2,
)
);
};
},
}),
[[`__scopeId`, `data-v-f12d9300`]],
),
{
__name: `InstanceLoadingShell`,
},
);
export {};
export default m;
</script>
+882
View File
@@ -0,0 +1,882 @@
<script>
import "~/assets/styles/InstanceTraffic.CyyEAXl3.css";
import "~/assets/styles/RingProgress.CVwR7il5.css";
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
import "~/assets/styles/InstanceOverview.C9ExpxMB.css";
import "~/assets/styles/InstanceMonitorSkeleton.C0FT51jJ.css";
import "~/assets/styles/InstanceLoadingShell.CwfiUwdU.css";
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
import "~/assets/styles/InstanceServiceInfo.BftSVIeW.css";
import "~/assets/styles/InstanceManage.apzbBV1c.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { watch } from "vue";
import { Suspense } from "vue";
import { defineAsyncComponent } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { loadModule } from "~/utils/load-module.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import InstanceServiceInfo from "~/components/instance/InstanceServiceInfo.vue";
import InstanceLoadingShell from "~/components/instance/InstanceLoadingShell.vue";
import InstanceMonitorSkeleton from "~/components/instance/InstanceMonitorSkeleton.vue";
import tabs from "primevue/tabs";
import tabpanels from "primevue/tabpanels";
import tabpanel from "primevue/tabpanel";
import tablist from "primevue/tablist";
import tab from "primevue/tab";
import InstanceOverview from "~/components/instance/InstanceOverview.vue";
var oe = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceMonitor.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
D = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceAccess.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
O = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceDisks.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
k = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceNetwork.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
A = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/MfCloudBackupPanel.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
j = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceBilling.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
M = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/mfcloud/MfCloudLogs.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
N = {
class: `instance-manage`,
},
P = {
key: 1,
class: `bs-wrap`,
},
F = {
class: `bs-block`,
},
I = {
class: `bs-block`,
},
L = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceManage`,
props: mergeModels(
{
hostId: {},
productId: {},
productState: {},
host: {},
module: {},
detail: {},
},
{
tab: {
default: `overview`,
},
tabModifiers: {},
},
),
emits: mergeModels([`refresh`, `pay`], [`update:tab`]),
setup(n, { emit: o }) {
let _ = n,
b = o,
S = ref(null),
L = 0,
{
info: R,
powerDesc: z,
loading: B,
error: V,
caps: H,
disksLoading: U,
disksError: W,
disksLoaded: G,
refreshDisks: K,
} = _.detail,
q = computed(() => _.host.status === `Active`),
J = useModel(n, `tab`),
Y = computed(() => [
{
value: `overview`,
label: `概要`,
},
{
value: `monitor`,
label: `监控`,
},
{
value: `access`,
label: `访问控制`,
},
...(H.value.disk === !1
? []
: [
{
value: `disk`,
label: `硬盘`,
},
]),
{
value: `network`,
label: `网络与安全`,
},
...(H.value.snapshot
? [
{
value: `backup`,
label: `备份与快照`,
},
]
: []),
{
value: `billing`,
label: `计费`,
},
...(H.value.log
? [
{
value: `log`,
label: `日志`,
},
]
: []),
]);
function se(e) {
J.value = Y.value.some((t) => t.value === e) ? e : `overview`;
}
function ce(e) {
q.value &&
(e !== `rescue` || H.value.rescue) &&
(e !== `reinstall` || H.value.reinstall) &&
((J.value = `access`),
(S.value = {
kind: e,
id: ++L,
}));
}
function le() {
S.value = null;
}
watch(
[Y, J],
([e, t]) => {
e.some((e) => e.value === t) || (J.value = `overview`);
},
{
immediate: !0,
},
);
let X = (e) => `实例尚未开通,${e}`;
return (r, i) => {
let o = button,
c = message,
d = InstanceServiceInfo,
_ = InstanceLoadingShell,
L = tab,
ue = tablist,
de = InstanceOverview,
Z = tabpanel,
fe = oe,
pe = InstanceMonitorSkeleton,
me = D,
he = O,
ge = k,
Q = A,
$ = j,
_e = M,
ve = tabpanels,
ye = tabs;
return (
openBlock(),
createElementBlock(`div`, N, [
unref(V) && unref(R)
? (openBlock(),
createBlock(
c,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(V)), 1),
createVNode(
o,
{
label: `重试`,
text: ``,
size: `small`,
loading: unref(B),
onClick: (i[0] ||= (e) => n.detail.load()),
},
null,
8,
[`loading`],
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
!unref(q) || (!unref(R) && unref(V))
? (openBlock(),
createBlock(
d,
{
key: 1,
host: n.host,
module: n.module,
info: unref(R),
onPay: (i[1] ||= (e) => b(`pay`, e)),
},
null,
8,
[`host`, `module`, `info`],
))
: !unref(R) && !unref(V)
? (openBlock(),
createBlock(_, {
key: 2,
}))
: createCommentVNode(``, !0),
unref(V) && !unref(R) && unref(q)
? (openBlock(),
createBlock(
c,
{
key: 3,
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(V)), 1),
createVNode(o, {
label: `重试`,
text: ``,
onClick: (i[2] ||= (e) => n.detail.load()),
}),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(q) && unref(R)
? (openBlock(),
createBlock(
ye,
{
key: 4,
value: J.value,
"onUpdate:value": (i[11] ||= (e) => (J.value = e)),
lazy: ``,
},
{
default: withCtx(() => [
createVNode(ue, null, {
default: withCtx(() => [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(Y),
(t) => (
openBlock(),
createBlock(
L,
{
key: t.value,
value: t.value,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(t.label),
1,
),
]),
_: 2,
},
1032,
[`value`],
)
),
),
128,
)),
]),
_: 1,
}),
createVNode(ve, null, {
default: withCtx(() => [
createVNode(
Z,
{
value: `overview`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createBlock(
de,
{
key: 1,
"product-state": n.productState,
info: unref(R),
host: n.host,
"host-id": n.hostId,
module: n.module,
caps: unref(H),
"power-desc": unref(z),
"disks-loading": unref(U),
"disks-error": unref(W),
"disks-loaded": unref(G),
onPay: (i[3] ||= (e) =>
b(`pay`, e)),
onGoTab: se,
onAccessAction: ce,
onRefreshDisks: unref(K),
},
null,
8,
[
`product-state`,
`info`,
`host`,
`host-id`,
`module`,
`caps`,
`power-desc`,
`disks-loading`,
`disks-error`,
`disks-loaded`,
`onRefreshDisks`,
],
))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
X(`以下数据将在开通后可用。`),
),
1,
),
]),
_: 1,
},
)),
]),
_: 1,
},
),
createVNode(
Z,
{
value: `monitor`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createBlock(
Suspense,
{
key: 1,
},
{
fallback: withCtx(() => [
createVNode(pe),
]),
default: withCtx(() => [
createVNode(
fe,
{
"host-id": n.hostId,
module: n.module,
},
null,
8,
[`host-id`, `module`],
),
]),
_: 1,
},
))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
X(`暂无监控数据。`),
),
1,
),
]),
_: 1,
},
)),
]),
_: 1,
},
),
createVNode(
Z,
{
value: `access`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createBlock(
me,
{
key: 1,
info: unref(R),
"host-id": n.hostId,
"product-id": n.productId,
module: n.module,
caps: unref(H),
detail: n.detail,
"pending-action": unref(S),
onRefresh: (i[4] ||= (e) =>
b(`refresh`)),
onActionConsumed: le,
},
null,
8,
[
`info`,
`host-id`,
`product-id`,
`module`,
`caps`,
`detail`,
`pending-action`,
],
))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
X(`暂不能进行访问相关操作。`),
),
1,
),
]),
_: 1,
},
)),
]),
_: 1,
},
),
unref(H).disk === !1
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
Z,
{
key: 0,
value: `disk`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createBlock(
he,
{
key: 1,
disks: unref(R).disks,
"host-id": n.hostId,
"product-id": n.productId,
module: n.module,
"upgrade-allowed":
unref(H).upgrade,
loading: unref(U),
error: unref(W),
loaded: unref(G),
onPay: (i[5] ||= (e) =>
b(`pay`, e)),
onRefresh: unref(K),
},
null,
8,
[
`disks`,
`host-id`,
`product-id`,
`module`,
`upgrade-allowed`,
`loading`,
`error`,
`loaded`,
`onRefresh`,
],
))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
X(`暂不能管理硬盘。`),
),
1,
),
]),
_: 1,
},
)),
]),
_: 1,
},
)),
createVNode(
Z,
{
value: `network`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createBlock(
ge,
{
key: 1,
info: unref(R),
"host-id": n.hostId,
"product-id": n.productId,
module: n.module,
caps: unref(H),
onPay: (i[6] ||= (e) =>
b(`pay`, e)),
onRefresh: (i[7] ||= (e) =>
b(`refresh`)),
},
null,
8,
[
`info`,
`host-id`,
`product-id`,
`module`,
`caps`,
],
))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
X(`暂无网络信息。`),
),
1,
),
]),
_: 1,
},
)),
]),
_: 1,
},
),
unref(H).snapshot
? (openBlock(),
createBlock(
Z,
{
key: 1,
value: `backup`,
},
{
default: withCtx(() => [
unref(q)
? (openBlock(),
createElementBlock(`div`, P, [
createElementVNode(`section`, F, [
createVNode(
Q,
{
"product-id": n.productId,
"upgrade-allowed":
unref(H).upgrade,
module: n.module,
"host-id": n.hostId,
kind: `snapshot`,
limit: Number(
unref(R).raw.snap_num ??
0,
),
onPay: (i[8] ||= (e) =>
b(`pay`, e)),
},
null,
8,
[
`product-id`,
`upgrade-allowed`,
`module`,
`host-id`,
`limit`,
],
),
]),
createElementVNode(`section`, I, [
createVNode(
Q,
{
"product-id": n.productId,
"upgrade-allowed":
unref(H).upgrade,
module: n.module,
"host-id": n.hostId,
kind: `backup`,
limit: Number(
unref(R).raw.backup_num ??
0,
),
"backup-mode": String(
unref(R).raw
.backup_mode ?? ``,
),
onPay: (i[9] ||= (e) =>
b(`pay`, e)),
},
null,
8,
[
`product-id`,
`upgrade-allowed`,
`module`,
`host-id`,
`limit`,
`backup-mode`,
],
),
]),
]))
: (openBlock(),
createBlock(
c,
{
key: 0,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(i[12] ||= [
createTextVNode(
`实例尚未开通,暂不能管理备份与快照。`,
-1,
),
]),
]),
_: 1,
},
)),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
Z,
{
value: `billing`,
},
{
default: withCtx(() => [
createVNode(
$,
{
"product-state": n.productState,
"upgrade-allowed": unref(H).upgrade,
host: n.host,
info: unref(R),
"host-id": n.hostId,
module: n.module,
disks: unref(R).disks,
provisioned: unref(q),
onPay: (i[10] ||= (e) => b(`pay`, e)),
},
null,
8,
[
`product-state`,
`upgrade-allowed`,
`host`,
`info`,
`host-id`,
`module`,
`disks`,
`provisioned`,
],
),
]),
_: 1,
},
),
unref(H).log
? (openBlock(),
createBlock(
Z,
{
key: 2,
value: `log`,
},
{
default: withCtx(() => [
J.value === `log`
? (openBlock(),
createBlock(
_e,
{
key: 0,
"host-id": n.hostId,
module: n.module,
},
null,
8,
[`host-id`, `module`],
))
: createCommentVNode(``, !0),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
}),
]),
_: 1,
},
8,
[`value`],
))
: createCommentVNode(``, !0),
])
);
};
},
}),
[[`__scopeId`, `data-v-627058ac`]],
),
{
__name: `InstanceManage`,
},
);
export {};
export default L;
</script>
+757
View File
@@ -0,0 +1,757 @@
<script>
import "~/assets/styles/InstanceMonitor.B0X15iQt.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { defineAsyncComponent } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { loadModule } from "~/utils/load-module.js";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import { t as useTheme_t } from "~/lib/useTheme.js";
import message from "primevue/message";
import ListSegments from "~/components/ListSegments.vue";
import skeleton from "primevue/skeleton";
import { n as finance_resource_chart_n } from "~/lib/finance-resource-chart.js";
import { t as finance_resource_chart_t } from "~/lib/finance-resource-chart.js";
var O = defineAsyncComponent(() =>
loadModule(
() => import("~/components/ChartBox.vue").then((e) => e.default || e),
[],
import.meta.url,
),
),
k = {
class: `mon`,
},
A = {
class: `range-row`,
},
j = {
class: `hint`,
},
M = {
key: 1,
class: `charts`,
},
N = {
class: `chart-title`,
},
P = {
class: `chart-viewport`,
},
F = {
key: 2,
class: `charts`,
},
I = {
class: `chart-title`,
},
L = {
key: 0,
class: `chart-unit`,
},
R = {
class: `chart-viewport`,
},
z = {
key: 0,
class: `chart-error`,
},
B = {
key: 2,
class: `chart-empty`,
},
V = {
class: `refresh-row`,
},
H = `#f59e0b`,
U = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceMonitor`,
props: {
hostId: {},
module: {},
},
setup(a) {
let g = a,
y = useApi(),
S = useTheme_t(),
U = computed(() => (S.isDark.value ? `#38bdf8` : `#0ea5e9`)),
W = ref([]),
G = ref(!1),
K = ref(``),
q = 0,
J = !1,
Y = ``,
X = [
{
label: `1小时`,
value: 3600,
},
{
label: `24小时`,
value: 86400,
},
{
label: `7天`,
value: 604800,
},
{
label: `1个月`,
value: 2592e3,
},
{
label: `1年`,
value: 31536e3,
},
],
Z = ref(86400),
Q = (e) => {
let t = new Date(e * 1e3);
return `${String(t.getHours()).padStart(2, `0`)}:${String(t.getMinutes()).padStart(2, `0`)}`;
};
async function te(e, t, n = `mf_cloud`) {
let r = [
{
type: `cpu`,
title: `CPU 使用率`,
max: 100,
pick: [
{
name: `CPU`,
fn: (e) => e.value,
color: U.value,
unit: `%`,
},
],
},
{
type: `memory`,
title: `内存使用率`,
max: 100,
pick: [
{
name: `内存`,
fn: (e) =>
e.total
? (Number(e.used ?? 0) / Number(e.total)) * 100
: void 0,
color: U.value,
unit: `%`,
},
],
},
{
type: `bw`,
title: `带宽(入 / 出)`,
pick: [
{
name: `入`,
fn: (e) => e.in_bw,
color: U.value,
},
{
name: `出`,
fn: (e) => e.out_bw,
color: H,
},
],
scale: `bits`,
},
{
type: `disk_io`,
title: `硬盘 IO(读 / 写)`,
pick: [
{
name: `读`,
fn: (e) => e.read_bytes,
color: U.value,
unit: `B/s`,
},
{
name: `写`,
fn: (e) => e.write_bytes,
color: H,
unit: `B/s`,
},
],
},
];
function i(e) {
let t = e > 0 ? Math.max(0, Math.floor(Math.log2(e) / 10)) : 0,
n = [`bps`, `Kbps`, `Mbps`, `Gbps`, `Tbps`];
return {
divisor: 1024 ** t,
unit: n[Math.min(t, n.length - 1)],
};
}
let a = n === `jy_dcim` ? r.filter((e) => e.type === `bw`) : r,
o = await Promise.allSettled(
a.map((r) =>
y.get(`/${n}/${e}/chart`, {
type: r.type,
start_time: t,
}),
),
);
return a.map((e, t) => {
let n = o[t];
if (n.status === `rejected`)
return {
key: e.type,
title: e.title,
labels: [],
series: [],
error:
n.reason instanceof Error
? n.reason.message
: `监控数据加载失败,请重试`,
};
let r = n.value.list ?? [],
a = e.pick.map((e) =>
r.map((t) => {
let n = e.fn(t);
return n === void 0 || Number.isNaN(n) ? null : Number(n);
}),
),
s =
e.scale === `bits`
? i(Math.max(0, ...a.flat().filter((e) => e !== null)))
: null;
return {
key: e.type,
title: e.title,
max: e.max,
labels: r.map((e) => Q(e.time)),
series: e.pick.map((e, t) => ({
name: e.name,
unit: s ? s.unit : e.unit,
color: e.color,
data: a[t].map((e) =>
e === null
? null
: Number((e / (s?.divisor ?? 1)).toFixed(2)),
),
})),
};
});
}
async function ne(e, t, n) {
let r = [
{
type: `cpu`,
title: `CPU 使用率`,
max: 100,
},
{
type: `memory`,
title: `内存使用率`,
max: 100,
},
{
type: `flow`,
title: `带宽(进 / 出)`,
},
{
type: `disk`,
title: `硬盘 IO(读 / 写)`,
},
],
i = await Promise.allSettled(
r.map((r) =>
y.get(`/remf_finance/${e}/chart`, {
type: r.type,
start: t,
end: n,
}),
),
);
return r.map((e, t) => {
let n = i[t];
if (n.status === `rejected`)
return {
key: e.type,
title: e.title,
labels: [],
series: [],
error:
n.reason instanceof Error
? n.reason.message
: `监控数据加载失败,请重试`,
};
let r = n.value ?? {};
if (e.type === `cpu` || e.type === `memory`) {
let t = finance_resource_chart_n(r, e.type);
return {
key: e.type,
title: e.title,
max: 100,
labels: t.labels,
series: [
{
name: e.type === `cpu` ? `CPU` : `内存`,
unit: `%`,
color: U.value,
data: t.data,
},
],
};
}
let a = (r.list?.[0] ?? []).map((e) =>
String(e.time ?? ``).slice(11, 16),
),
o = (r.list ?? []).map((e, t) => ({
name: String(r.label?.[t] ?? `系列 ${t + 1}`).replace(
/\(.*\)$/,
``,
),
unit: r.unit,
color: t === 0 ? U.value : H,
data: e.map((e) => finance_resource_chart_t(e.value)),
}));
return {
key: e.type,
title: e.title,
max: e.max,
labels: a,
series: o,
};
});
}
async function re(e) {
let t = await y.get(`/kky_ecs/monitor/${e}`),
n = (t.sample_info ?? []).map((e) =>
String(e.timestamp ?? ``).slice(11, 16),
),
r = (e, t, r, i, a, o = 1) => ({
key: e,
title: t,
labels: n,
series: (r ?? []).map((e, t) => ({
name: e.title,
unit: a,
color: i[t % i.length],
data: (e.value ?? []).map((e) =>
typeof e == `number` ? Number((e / o).toFixed(2)) : null,
),
})),
});
return [
r(`cpu`, `CPU 使用率`, t.cpu, [U.value], `%`),
r(`memory`, `内存`, t.memory, [U.value, H], `KB`),
r(`bandwidth`, `带宽`, t.bandwidth, [U.value, H], `Mbps`, 1e3),
r(`disk`, `硬盘 IO`, t.disk, [U.value, H], `KB/s`),
];
}
async function $() {
if (J) return;
let e = ++q,
t = g.hostId,
n = g.module,
r = Z.value,
i = `${n}:${t}:${n === `kky_ecs` ? `` : r}`,
a = () =>
!J &&
e === q &&
t === g.hostId &&
n === g.module &&
(n === `kky_ecs` || r === Z.value);
((G.value = !0), (K.value = ``), Y !== i && (W.value = []));
try {
let e = Date.now(),
o =
n === `mf_cloud` ||
n === `remf_cloud` ||
n === `jy_cloud` ||
n === `jy_dcim`
? await te(t, Math.floor(e / 1e3) - r, n)
: n === `remf_finance`
? await ne(t, e - r * 1e3, e)
: await re(t);
a() && ((W.value = o), (Y = i));
} catch (e) {
if (!a()) return;
((K.value = e instanceof Error ? e.message : `加载监控数据失败`),
(W.value = []));
} finally {
a() && (G.value = !1);
}
}
function ie(e) {
if (g.module === `kky_ecs` || e === void 0) return;
let t = Number(e);
if (X.some((e) => e.value === t)) return ((Z.value = t), $());
}
let ae = (e) => e.series.some((e) => e.data.some((e) => e !== null));
function oe(e) {
let t = S.isDark.value ? `#a1a1aa` : `#94a3b8`,
n = S.isDark.value ? `rgba(255,255,255,.08)` : `rgba(0,0,0,.06)`;
return {
grid: {
left: 6,
right: 10,
top: 26,
bottom: 4,
outerBoundsMode: `same`,
outerBoundsContain: `axisLabel`,
},
tooltip: {
trigger: `axis`,
},
legend:
e.series.length > 1
? {
top: 0,
right: 0,
itemWidth: 10,
itemHeight: 2,
textStyle: {
fontSize: 11,
},
}
: void 0,
xAxis: {
type: `category`,
data: e.labels,
boundaryGap: !1,
axisTick: {
show: !1,
},
axisLine: {
lineStyle: {
color: n,
},
},
axisLabel: {
color: t,
fontSize: 11,
},
},
yAxis: {
type: `value`,
max: e.max,
axisLine: {
show: !1,
},
axisTick: {
show: !1,
},
axisLabel: {
color: t,
fontSize: 11,
formatter: e.series.every((e) => e.unit === `%`)
? (e) => `${e}%`
: void 0,
},
splitLine: {
lineStyle: {
color: n,
},
},
},
series: e.series.map((t) => ({
name: t.name,
type: `line`,
smooth: !0,
showSymbol: !1,
connectNulls: !1,
areaStyle:
e.series.length === 1
? {
opacity: 0.12,
}
: void 0,
lineStyle: {
width: 1.6,
color: t.color,
},
itemStyle: {
color: t.color,
},
data: t.data,
tooltip: {
valueFormatter: (e) =>
e == null
? `暂无数据`
: t.unit === `%`
? `${e}%`
: t.unit
? `${e} ${t.unit}`
: String(e),
},
})),
};
}
return (
onMounted($),
watch(() => [g.hostId, g.module], $),
onBeforeUnmount(() => {
((J = !0), (q += 1));
}),
(n, r) => {
let i = ListSegments,
s = button,
u = message,
g = skeleton,
y = O;
return (
openBlock(),
createElementBlock(`div`, k, [
createElementVNode(`div`, A, [
a.module === `kky_ecs`
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
i,
{
key: 0,
"aria-label": `监控时间范围`,
"model-value": unref(Z),
options: X,
"onUpdate:modelValue": ie,
},
null,
8,
[`model-value`],
)),
createElementVNode(`span`, j, [
a.module === `kky_ecs`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createTextVNode(
`数据由平台采集,可查询的时间范围固定。`,
),
],
64,
))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`数据由平台采集,实例未运行时可能为空。`,
),
],
64,
)),
]),
]),
unref(K)
? (openBlock(),
createBlock(
u,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(K)) + ` `, 1),
createVNode(
s,
{
label: `重试`,
size: `small`,
severity: `secondary`,
text: ``,
loading: unref(G),
onClick: $,
},
null,
8,
[`loading`],
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(G) && !unref(W).length
? (openBlock(),
createElementBlock(`div`, M, [
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(4, (e) =>
createElementVNode(
`div`,
{
key: e,
class: `chart-card`,
},
[
createElementVNode(`div`, N, [
createVNode(g, {
width: `35%`,
height: `24px`,
}),
]),
createElementVNode(`div`, P, [
createVNode(g, {
height: `280px`,
}),
]),
],
),
),
64,
)),
]))
: (openBlock(),
createElementBlock(`div`, F, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(W),
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t.key,
class: `chart-card`,
},
[
createElementVNode(`div`, I, [
createTextVNode(
toDisplayString(t.title),
1,
),
t.series[0]?.unit
? (openBlock(),
createElementBlock(
`span`,
L,
`(` +
toDisplayString(t.series[0].unit) +
`)`,
1,
))
: createCommentVNode(``, !0),
]),
createElementVNode(`div`, R, [
t.error
? (openBlock(),
createElementBlock(`div`, z, [
createVNode(
u,
{
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(t.error) +
` `,
1,
),
createVNode(
s,
{
label: `重试`,
size: `small`,
severity: `secondary`,
text: ``,
loading: unref(G),
onClick: $,
},
null,
8,
[`loading`],
),
]),
_: 2,
},
1024,
),
]))
: ae(t)
? (openBlock(),
createBlock(
y,
{
key: 1,
option: oe(t),
height: 280,
loading: unref(G),
},
null,
8,
[`option`, `loading`],
))
: (openBlock(),
createElementBlock(
`p`,
B,
`暂无监控数据`,
)),
]),
],
)
),
),
128,
)),
])),
createElementVNode(`div`, V, [
createVNode(
s,
{
label: `刷新`,
icon: `pi pi-refresh`,
size: `small`,
severity: `secondary`,
text: ``,
loading: unref(G),
onClick: $,
},
null,
8,
[`loading`],
),
]),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-6a900feb`]],
),
{
__name: `InstanceMonitor`,
},
);
export {};
export default U;
</script>
@@ -0,0 +1,147 @@
<script>
import "~/assets/styles/InstanceMonitorSkeleton.C0FT51jJ.css";
import { renderList } from "vue";
import { normalizeClass } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import skeleton from "primevue/skeleton";
var d = {
class: `range-placeholder`,
"aria-hidden": `true`,
},
f = {
key: 0,
class: `hint-placeholder`,
},
p = {
class: `title-placeholder`,
},
m = {
key: 0,
class: `legend-placeholder`,
},
h = {
key: 0,
class: `refresh-placeholder`,
"aria-hidden": `true`,
},
g = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceMonitorSkeleton`,
props: {
dcim: {
type: Boolean,
default: !1,
},
},
setup(o) {
return (l, g) => {
let _ = skeleton;
return (
openBlock(),
createElementBlock(
`div`,
{
class: normalizeClass([
`monitor-skeleton`,
{
dcim: o.dcim,
},
]),
role: `status`,
"aria-label": `正在加载监控`,
"aria-busy": `true`,
},
[
createElementVNode(`div`, d, [
createVNode(_, {
width: `340px`,
height: `40px`,
}),
o.dcim
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`span`,
f,
`数据由平台采集,实例未运行时可能为空。`,
)),
]),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
o.dcim ? 1 : 4,
(e) => (
openBlock(),
createElementBlock(
`div`,
{
key: e,
class: `chart-placeholder`,
"aria-hidden": `true`,
},
[
createElementVNode(`div`, p, [
createVNode(_, {
width: `120px`,
height: `24px`,
}),
]),
o.dcim
? (openBlock(),
createElementBlock(`div`, m, [
createVNode(_, {
width: `180px`,
height: `21px`,
}),
]))
: createCommentVNode(``, !0),
createVNode(
_,
{
height: o.dcim ? `320px` : `280px`,
},
null,
8,
[`height`],
),
],
)
),
),
128,
)),
o.dcim
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, h, [
createVNode(_, {
width: `70px`,
height: `35px`,
}),
])),
],
2,
)
);
};
},
}),
[[`__scopeId`, `data-v-5a1fd568`]],
),
{
__name: `InstanceMonitorSkeleton`,
},
);
export {};
export default g;
</script>
+926
View File
@@ -0,0 +1,926 @@
<script>
import "~/assets/styles/MfCloudDefence.B2vl5Yip.css";
import "~/assets/styles/MfCloudVpc.CpOEbuWs.css";
import "~/assets/styles/MfCloudIps.jhFnuvcs.css";
import "~/assets/styles/InstanceTraffic.CyyEAXl3.css";
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
import "~/assets/styles/InstanceNetwork.CyucZaZp.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { NuxtLink } from "#components";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import OperationNotice from "~/components/OperationNotice.vue";
import { n as configuration_display_n } from "~/lib/configuration-display.js";
import { i as cloud_instance_management_i } from "~/lib/cloud-instance-management.js";
import FlowPacketPanel from "~/components/instance/FlowPacketPanel.vue";
import InstanceTraffic from "~/components/instance/InstanceTraffic.vue";
import MfCloudIps from "~/components/mfcloud/MfCloudIps.vue";
import MfCloudVpc from "~/components/mfcloud/MfCloudVpc.vue";
import MfCloudDefence from "~/components/mfcloud/MfCloudDefence.vue";
var ce = {
class: `nw`,
},
le = {
class: `block`,
},
ue = {
class: `block-desc`,
},
de = {
class: `info-table`,
},
fe = {
class: `kv`,
},
pe = {
class: `kv`,
},
me = {
key: 0,
class: `kv`,
},
he = {
class: `kv`,
},
ge = {
class: `kv`,
},
_e = {
key: 0,
class: `block-desc`,
},
ve = {
class: `block`,
},
ye = {
key: 1,
class: `info-table`,
},
be = {
class: `col-mono`,
},
xe = {
key: 0,
class: `kv`,
},
Se = {
class: `col-mono`,
},
Ce = {
key: 1,
class: `kv`,
},
we = {
class: `action-cell`,
},
Te = {
key: 0,
class: `sub`,
},
Ee = {
key: 2,
class: `kv`,
},
De = {
key: 1,
class: `block`,
},
Oe = {
class: `block`,
},
ke = {
class: `info-table`,
},
Ae = {
key: 0,
class: `kv`,
},
S = {
class: `kv`,
},
C = {
class: `action-cell`,
},
je = {
key: 3,
class: `block`,
},
Me = {
class: `info-table`,
},
Ne = {
class: `kv`,
},
Pe = {
key: 0,
},
Fe = {
key: 1,
},
Ie = {
key: 2,
},
Le = {
class: `kv`,
},
w = {
class: `action-cell`,
},
Re = {
key: 4,
class: `block`,
role: `status`,
},
ze = {
class: `block-desc`,
},
T = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceNetwork`,
props: {
info: {},
hostId: {},
productId: {},
module: {},
caps: {},
},
emits: [`pay`, `refresh`],
setup(h, { emit: y }) {
let T = h,
E = y,
D = useApi(),
O = computed(() => configuration_display_n(T.module, T.info.raw)),
k = computed(() => cloud_instance_management_i(T.module)),
A = ref([]),
Be = computed(() => [...new Set([...T.info.ips, ...A.value])]);
watch(
() => [T.hostId, T.module],
() => {
A.value = [];
},
);
let j = ref(!1),
M = ref(``),
N = ref(``),
P = ref(!1),
F = ref(``),
I = computed(() =>
String(T.info.raw.intranet_ip || F.value || ``).trim(),
),
L = computed(
() =>
T.module === `kky_ecs` &&
!I.value &&
T.caps.upgrade !== !1 &&
[`on`, `off`].includes(T.info.powerStatus) &&
!P.value,
),
R = 0,
z = !1;
function B() {
(++R,
(j.value = !1),
(P.value = !1),
(F.value = ``),
(M.value = ``),
(N.value = ``));
}
async function Ve() {
if (z || j.value || !L.value) return;
let e = T.hostId,
t = ++R,
n = () =>
!z && t === R && T.hostId === e && T.module === `kky_ecs`;
((j.value = !0), (M.value = ``), (N.value = ``));
try {
let t = await D.post(`/kky_ecs/upgrade/${e}/add_intranet_ip`);
if (!n()) return;
((F.value = String(t?.intranet_ip || ``).trim()),
(P.value = !0),
(N.value = F.value
? `内网 IP 已添加`
: `内网 IP 分配请求已提交,请稍后刷新查看`),
F.value && E(`refresh`));
} catch (e) {
n() &&
(M.value =
e instanceof Error
? e.message
: `添加内网 IP 失败,请稍后重试`);
} finally {
n() && (j.value = !1);
}
}
watch(() => [T.hostId, T.module], B, {
flush: `sync`,
});
let V = computed(() =>
[`mf_cloud`, `remf_cloud`, `remf_finance`].includes(T.module),
),
H = ref(null),
U = ref(!1),
W = ref(!1),
G = ref(`loading`),
K = ref(null),
q = ref(``),
J = ref(``);
function He(e) {
return e.status === 1
? `已通过`
: e.status === -1
? `已驳回`
: e.need_review
? `等待人工审核`
: `处理中`;
}
let Y = 0,
X = 0;
function Ue(e) {
return (
typeof e == `object` &&
!!e &&
`status` in e &&
Number(e.status) === 400 &&
`message` in e &&
String(e.message).includes(`该商品暂不支持域名过白`)
);
}
async function Z(e) {
let t = ++X,
n = () => t === X && T.hostId === e;
((G.value = `loading`),
(K.value = null),
(q.value = ``),
(J.value = ``));
try {
if (
(await D.get(`/domain_whitelist/form`, {
host_id: e,
}),
!n())
)
return;
G.value = `supported`;
} catch (e) {
if (!n()) return;
if (Ue(e)) {
G.value = `unsupported`;
return;
}
((G.value = `error`),
(q.value =
e instanceof Error
? e.message
: `暂时无法确认域名白名单状态,请重试`));
return;
}
try {
let t = await D.get(`/domain_whitelist/record`, {
host_id: e,
page: 1,
limit: 1,
});
n() && (K.value = t.list?.[0] ?? null);
} catch (e) {
n() &&
(J.value =
e instanceof Error
? e.message
: `读取白名单记录失败,请重试`);
}
}
function Q() {
Z(T.hostId);
}
async function $() {
let e = ++Y,
t = T.hostId;
if (
((H.value = null),
(U.value = !1),
(W.value =
T.caps.traffic !== !1 &&
[`mf_cloud`, `remf_cloud`].includes(T.module)),
T.caps.traffic !== !1 &&
(T.module === `mf_cloud` || T.module === `remf_cloud`))
)
try {
let n = await D.get(`/${T.module}/${t}/flow`);
e === Y && (H.value = n);
} catch {
e === Y && (U.value = !0);
} finally {
e === Y && (W.value = !1);
}
e === Y && (await Z(t));
}
return (
onMounted($),
watch(() => [T.hostId, T.module], $),
onBeforeUnmount(() => {
(Y++, X++, (z = !0), B());
}),
(n, r) => {
let i = MfCloudIps,
o = button,
l = OperationNotice,
v = MfCloudVpc,
y = MfCloudDefence,
b = InstanceTraffic,
x = FlowPacketPanel,
T = NuxtLink;
return (
openBlock(),
createElementBlock(`div`, ce, [
createElementVNode(`section`, le, [
(r[11] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`公共网络`,
-1,
)),
createElementVNode(`p`, ue, [
(r[5] ||= createTextVNode(
` 任何人都可以通过公共网络地址访问您的服务器。`,
-1,
)),
h.caps.upgrade === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`若您需要调整带宽上限或流量配额,请前往「计费」进行升降级。`,
),
],
64,
)),
]),
createElementVNode(`div`, de, [
createElementVNode(`div`, fe, [
(r[6] ||= createElementVNode(`span`, null, `区域`, -1)),
createElementVNode(
`b`,
null,
toDisplayString(unref(O).region || `—`),
1,
),
]),
createElementVNode(`div`, pe, [
(r[7] ||= createElementVNode(`span`, null, `线路`, -1)),
createElementVNode(
`b`,
null,
toDisplayString(unref(O).line || `—`),
1,
),
]),
unref(O).networkType
? (openBlock(),
createElementBlock(`div`, me, [
(r[8] ||= createElementVNode(
`span`,
null,
`网络类型`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(unref(O).networkType),
1,
),
]))
: createCommentVNode(``, !0),
createElementVNode(`div`, he, [
(r[9] ||= createElementVNode(
`span`,
null,
`带宽上限`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
h.info.bw > 0 ? `${h.info.bw} Mbps` : `不限制`,
),
1,
),
]),
createElementVNode(`div`, ge, [
(r[10] ||= createElementVNode(
`span`,
null,
`防护峰值`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
h.info.protect > 0 ? `${h.info.protect} Gbps` : `—`,
),
1,
),
]),
]),
h.info.protect > 0
? (openBlock(),
createElementBlock(`p`, _e, `在防御峰值内提供保护。`))
: createCommentVNode(``, !0),
]),
createElementVNode(`section`, ve, [
(r[16] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`IP 地址`,
-1,
)),
unref(k)
? (openBlock(),
createBlock(
i,
{
key: 0,
"host-id": h.hostId,
module: h.module,
"upgrade-allowed": h.caps.upgrade,
onAddresses: (r[0] ||= (e) => (A.value = e)),
onPay: (r[1] ||= (e) => E(`pay`, e)),
},
null,
8,
[`host-id`, `module`, `upgrade-allowed`],
))
: (openBlock(),
createElementBlock(`div`, ye, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
h.info.ips,
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t,
class: `kv`,
},
[
(r[12] ||= createElementVNode(
`span`,
null,
`IPv4 地址`,
-1,
)),
createElementVNode(
`b`,
be,
toDisplayString(t),
1,
),
],
)
),
),
128,
)),
unref(I)
? (openBlock(),
createElementBlock(`div`, xe, [
(r[13] ||= createElementVNode(
`span`,
null,
`内网地址`,
-1,
)),
createElementVNode(
`b`,
Se,
toDisplayString(unref(I)),
1,
),
]))
: h.module === `kky_ecs` && h.caps.upgrade !== !1
? (openBlock(),
createElementBlock(`div`, Ce, [
(r[14] ||= createElementVNode(
`span`,
null,
`内网地址`,
-1,
)),
createElementVNode(`div`, we, [
createVNode(
o,
{
label: `添加内网 IP`,
icon: `pi pi-plus`,
size: `small`,
severity: `secondary`,
outlined: ``,
loading: unref(j),
disabled: unref(j) || !unref(L),
onClick: Ve,
},
null,
8,
[`loading`, `disabled`],
),
!unref(L) && !unref(j) && !unref(P)
? (openBlock(),
createElementBlock(
`span`,
Te,
`实例正常开机或关机时可添加`,
))
: createCommentVNode(``, !0),
]),
]))
: createCommentVNode(``, !0),
h.info.ips.length
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, Ee, [
...(r[15] ||= [
createElementVNode(
`span`,
null,
`IPv4 地址`,
-1,
),
createElementVNode(
`b`,
null,
`暂无 IP 地址`,
-1,
),
]),
])),
])),
createVNode(
l,
{
message: unref(M),
severity: `error`,
},
null,
8,
[`message`],
),
createVNode(
l,
{
message: unref(N),
severity: `success`,
},
null,
8,
[`message`],
),
]),
unref(k)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createVNode(
v,
{
"host-id": h.hostId,
"product-id": h.productId,
module: h.module,
"network-type": String(
h.info.raw.network_type ?? ``,
),
"data-center-id":
Number(h.info.raw.data_center?.id) || void 0,
active: [`on`, `off`].includes(
h.info.powerStatus,
),
onRefresh: (r[2] ||= (e) => E(`refresh`)),
},
null,
8,
[
`host-id`,
`product-id`,
`module`,
`network-type`,
`data-center-id`,
`active`,
],
),
createVNode(
y,
{
"host-id": h.hostId,
module: h.module,
ips: unref(Be),
active: [`on`, `off`].includes(
h.info.powerStatus,
),
"upgrade-allowed": h.caps.upgrade,
onPay: (r[3] ||= (e) => E(`pay`, e)),
},
null,
8,
[
`host-id`,
`module`,
`ips`,
`active`,
`upgrade-allowed`,
],
),
],
64,
))
: createCommentVNode(``, !0),
h.caps.traffic === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`section`, De, [
(r[17] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`网络流量`,
-1,
)),
createVNode(
b,
{
layout: `table`,
module: h.module,
"host-id": h.hostId,
raw: h.info.raw,
flow: unref(H),
loading: unref(W),
failed: unref(U),
},
null,
8,
[
`module`,
`host-id`,
`raw`,
`flow`,
`loading`,
`failed`,
],
),
])),
unref(V)
? (openBlock(),
createBlock(
x,
{
key: 2,
"host-id": h.hostId,
module: h.module,
flow: unref(H),
onPay: (r[4] ||= (e) => E(`pay`, e)),
},
null,
8,
[`host-id`, `module`, `flow`],
))
: createCommentVNode(``, !0),
createElementVNode(`section`, Oe, [
(r[20] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`安全组`,
-1,
)),
(r[21] ||= createElementVNode(
`p`,
{
class: `block-desc`,
},
` 安全组是一种虚拟防火墙,用于控制实例级别的入站和出站网络流量。 请确保所选安全组已放通 22 端口(Linux SSH 登录)、3389 端口(Windows 远程登录),否则无法远程登录。 `,
-1,
)),
createElementVNode(`div`, ke, [
unref(V)
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, Ae, [
(r[18] ||= createElementVNode(
`span`,
null,
`当前安全组`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
h.info.securityGroupName || `未加入安全组`,
),
1,
),
])),
createElementVNode(`div`, S, [
(r[19] ||= createElementVNode(
`span`,
null,
`安全组管理`,
-1,
)),
createElementVNode(`div`, C, [
createVNode(
T,
{
to: `/security/groups`,
},
{
default: withCtx(() => [
createVNode(o, {
label: `前往安全组管理`,
size: `small`,
severity: `secondary`,
outlined: ``,
icon: `pi pi-shield`,
}),
]),
_: 1,
},
),
]),
]),
]),
]),
unref(G) === `supported`
? (openBlock(),
createElementBlock(`section`, je, [
(r[24] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`域名白名单`,
-1,
)),
(r[25] ||= createElementVNode(
`p`,
{
class: `block-desc`,
},
` 使用中国大陆机房提供 HTTP/HTTPS 服务前需要先完成域名过白。白名单仅需提交一级域名,通过后所有子域名均可使用。 `,
-1,
)),
createElementVNode(`div`, Me, [
createElementVNode(`div`, Ne, [
(r[22] ||= createElementVNode(
`span`,
null,
`最近提交`,
-1,
)),
unref(J)
? (openBlock(),
createElementBlock(
`b`,
Pe,
`读取失败:` + toDisplayString(unref(J)),
1,
))
: unref(K)
? (openBlock(),
createElementBlock(
`b`,
Fe,
toDisplayString(
unref(K).domains.join(`、`),
) +
` · ` +
toDisplayString(He(unref(K))),
1,
))
: (openBlock(),
createElementBlock(`b`, Ie, `暂无记录`)),
]),
createElementVNode(`div`, Le, [
(r[23] ||= createElementVNode(
`span`,
null,
`白名单管理`,
-1,
)),
createElementVNode(`div`, w, [
createVNode(
T,
{
to: `/security/domains?host_id=${h.hostId}`,
},
{
default: withCtx(() => [
createVNode(o, {
label: `前往域名白名单`,
size: `small`,
severity: `secondary`,
outlined: ``,
icon: `pi pi-shield`,
}),
]),
_: 1,
},
8,
[`to`],
),
unref(J)
? (openBlock(),
createBlock(o, {
key: 0,
label: `重试读取`,
size: `small`,
severity: `secondary`,
text: ``,
icon: `pi pi-refresh`,
onClick: Q,
}))
: createCommentVNode(``, !0),
]),
]),
]),
]))
: unref(G) === `error`
? (openBlock(),
createElementBlock(`section`, Re, [
(r[26] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`域名白名单`,
-1,
)),
createElementVNode(
`p`,
ze,
toDisplayString(unref(q)),
1,
),
createVNode(o, {
label: `重试`,
size: `small`,
severity: `secondary`,
outlined: ``,
icon: `pi pi-refresh`,
onClick: Q,
}),
]))
: createCommentVNode(``, !0),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-aa906366`]],
),
{
__name: `InstanceNetwork`,
},
);
export {};
export default T;
</script>
@@ -0,0 +1,797 @@
<script>
import "~/assets/styles/InstanceOnDemand.okGWwgIJ.css";
import { toDisplayString } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { r as dict_r } from "~/lib/dict.js";
import select from "primevue/select";
import checkbox from "primevue/checkbox";
import skeleton from "primevue/skeleton";
import datepicker from "primevue/datepicker";
var oe = {
class: `on-demand`,
},
se = {
key: 2,
},
ce = {
class: `actions`,
},
le = {
key: 3,
},
x = {
key: 4,
},
S = {
key: 6,
},
ue = {
key: 1,
},
de = {
key: 0,
},
fe = {
class: `confirmation`,
},
C = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceOnDemand`,
props: {
host: {},
hostId: {},
},
emits: [`refresh`, `pay`],
setup(m, { emit: b }) {
let C = m,
w = b,
T = useApi(),
E = computed(() => C.host.billing_cycle === `on_demand`),
D = computed(() => Number(C.host.change_billing_cycle_id) > 0),
O = computed(() => {
if (D.value) return `已设置到期转换计划。`;
if (!E.value && C.host.billing_cycle !== `recurring_prepayment`)
return `当前计费方式不支持到期转为按需计费。`;
let e = E.value
? C.host.product_on_demand?.on_demand_to_duration
: C.host.product_on_demand?.duration_to_on_demand;
return e == null
? `计费转换能力信息未返回,请刷新实例详情。`
: Number(e) === 1
? E.value && Number(C.host.auto_release_time) > 0
? `请先取消自动释放计划,再转为包年包月。`
: (E.value ? [`Active`, `Grace`] : [`Active`]).includes(
C.host.status,
)
? ``
: `当前实例状态不支持计费转换。`
: E.value
? `当前商品未开启按需转包年包月。`
: `当前商品未开启包年包月转按需计费。`;
}),
k = computed(() => {
if (!E.value) return `自动释放设置仅支持按需计费实例。`;
let e = C.host.product_on_demand?.client_auto_delete;
return e == null
? `自动释放能力信息未返回,请刷新实例详情。`
: Number(e) === 1
? C.host.status === `Active`
? ``
: `当前实例状态不支持修改自动释放时间。`
: `当前商品未开启自动释放设置。`;
}),
A = computed(() => !O.value),
j = computed(() => !k.value),
pe = computed(
() =>
(E.value
? C.host.product_on_demand?.on_demand_to_duration
: C.host.product_on_demand?.duration_to_on_demand) == null ||
(E.value &&
C.host.product_on_demand?.client_auto_delete == null),
),
M = computed(
() =>
`/host/${C.hostId}/${E.value ? `on_demand_to_recurring_prepayment` : `recurring_prepayment_to_on_demand`}`,
),
N = ref(!1),
P = ref(!1),
F = ref(!1),
I = ref(``),
L = ref(``),
R = ref([]),
z = ref(null),
B = ref(null),
V = ref(!1),
H = ref(null),
U = ref(!1),
W = ref(!1),
G = 0,
K = !1,
q = () =>
`${C.hostId}:${C.host.billing_cycle}:${C.host.change_billing_cycle_id}:${A.value}:${j.value}`,
J = (e) =>
e != null &&
String(e).trim() !== `` &&
Number.isFinite(Number(e)) &&
Number(e) >= 0,
Y = ``,
X = computed(() => R.value.find((e) => e.id === z.value)),
Z = computed(
() =>
!P.value &&
!F.value &&
A.value &&
Y === q() &&
(E.value ? !!X.value : !!B.value),
);
function Q() {
(G++,
(Y = ``),
(N.value = V.value = W.value = !1),
(P.value = !1),
(R.value = []),
(B.value = null),
(I.value = ``),
(L.value = ``));
}
(watch(q, Q, {
flush: `sync`,
}),
onBeforeUnmount(() => {
((K = !0), Q());
}));
async function $() {
if (!A.value || F.value) return;
((N.value = !0),
(P.value = !0),
(I.value = ``),
(Y = ``),
(R.value = []),
(B.value = null),
(z.value = null));
let e = ++G,
t = q();
try {
let n = await T.get(M.value);
if (K || e !== G || !N.value || t !== q()) return;
if (E.value) {
if (
!Array.isArray(n?.duration) ||
!n.duration.length ||
n.duration.some(
(e) =>
!Number.isSafeInteger(Number(e.id)) ||
Number(e.id) <= 0 ||
!J(e.price),
)
)
throw Error(`未获得可用周期报价,请重试`);
((R.value = n.duration), (z.value = n.duration[0].id));
} else {
if (
!J(n.on_demand_price) ||
(n.keep_time_price != null && !J(n.keep_time_price))
)
throw Error(`按需价格响应无效,请重试`);
B.value = {
...n,
on_demand_price: n.on_demand_price,
};
}
Y = t;
} catch (t) {
e === G &&
!K &&
(I.value = t instanceof Error ? t.message : `计费报价加载失败`);
} finally {
e === G && !K && (P.value = !1);
}
}
async function me() {
if (!Z.value) return;
((F.value = !0), (I.value = ``));
let e = G,
t = E.value,
n = M.value;
try {
let r = await T.post(
n,
t
? {
duration_id: z.value,
}
: void 0,
);
if (K || G !== e) return;
if (t) {
if (
!Number.isSafeInteger(Number(r?.id)) ||
Number(r.id) <= 0 ||
!J(r.amount)
)
throw Error(`转换订单响应无效,请到订单列表核对`);
w(`pay`, {
order_id: r.id,
amount: r.amount,
});
} else L.value = `已申请到期转为按需计费`;
((N.value = !1), (Y = ``), w(`refresh`));
} catch (t) {
e === G &&
!K &&
(I.value = t instanceof Error ? t.message : `转换申请失败`);
} finally {
F.value = !1;
}
}
async function he() {
if (!D.value || F.value || !W.value) return;
((F.value = !0), (I.value = ``));
let e = G;
try {
if (
(await T.del(
`/host/${C.hostId}/recurring_prepayment_to_on_demand`,
),
K || e !== G)
)
return;
((W.value = !1), (L.value = `已取消到期转换计划`), w(`refresh`));
} catch (t) {
!K &&
e === G &&
(I.value = t instanceof Error ? t.message : `取消转换失败`);
} finally {
F.value = !1;
}
}
function ge() {
j.value &&
!F.value &&
((H.value =
Number(C.host.auto_release_time) > 0
? new Date(Number(C.host.auto_release_time) * 1e3)
: null),
(U.value = !1),
(I.value = ``),
(V.value = !0));
}
async function _e() {
if (!j.value || F.value || !V.value || !U.value) return;
let e = H.value ? Math.floor(H.value.getTime() / 1e3) : 0;
if (
H.value &&
(!Number.isSafeInteger(e) || e <= Date.now() / 1e3)
) {
I.value = `请选择将来的释放时间`;
return;
}
((F.value = !0), (I.value = ``));
let t = G;
try {
if (
(await T.put(`/host/${C.hostId}/auto_release_time`, {
auto_release_time: e,
}),
K || t !== G)
)
return;
((V.value = !1),
(L.value = e ? `自动释放时间已保存` : `已取消自动释放`),
w(`refresh`));
} catch (e) {
!K &&
t === G &&
(I.value = e instanceof Error ? e.message : `保存自动释放失败`);
} finally {
F.value = !1;
}
}
return (t, n) => {
let i = message,
s = button,
_ = skeleton,
b = select,
C = dialog,
T = datepicker,
M = checkbox;
return (
openBlock(),
createElementBlock(`section`, oe, [
(n[12] ||= createElementVNode(
`h4`,
null,
`计费转换与自动释放`,
-1,
)),
unref(L)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `success`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(L)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(I)
? (openBlock(),
createBlock(
i,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(I)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(D)
? (openBlock(),
createElementBlock(
`p`,
se,
`已申请到期转为按需计费,取消转换计划后才可续费或升降级。`,
))
: createCommentVNode(``, !0),
createElementVNode(`div`, ce, [
createVNode(
s,
{
label: unref(E) ? `转为包年包月` : `到期转为按需计费`,
disabled: !unref(A) || unref(F),
outlined: ``,
onClick: $,
},
null,
8,
[`label`, `disabled`],
),
unref(D)
? (openBlock(),
createBlock(
s,
{
key: 0,
label: `取消转换计划`,
disabled: unref(F),
outlined: ``,
onClick: (n[0] ||= (e) => (W.value = !0)),
},
null,
8,
[`disabled`],
))
: createCommentVNode(``, !0),
createVNode(
s,
{
label: `设置自动释放`,
disabled: !unref(j) || unref(F),
outlined: ``,
onClick: ge,
},
null,
8,
[`disabled`],
),
]),
unref(O) && !unref(D)
? (openBlock(),
createElementBlock(
`small`,
le,
toDisplayString(unref(O)),
1,
))
: createCommentVNode(``, !0),
unref(k)
? (openBlock(),
createElementBlock(
`small`,
x,
toDisplayString(unref(k)),
1,
))
: createCommentVNode(``, !0),
unref(pe)
? (openBlock(),
createBlock(
s,
{
key: 5,
label: `刷新实例详情`,
text: ``,
size: `small`,
disabled: unref(F),
onClick: (n[1] ||= (e) => w(`refresh`)),
},
null,
8,
[`disabled`],
))
: createCommentVNode(``, !0),
m.host.auto_release_time
? (openBlock(),
createElementBlock(
`p`,
S,
`当前自动释放时间:` +
toDisplayString(
(`formatTime` in t ? t.formatTime : unref(dict_r))(
m.host.auto_release_time,
),
),
1,
))
: createCommentVNode(``, !0),
createVNode(
C,
{
visible: unref(N),
"onUpdate:visible": (n[3] ||= (e) =>
isRef(N) ? (N.value = e) : null),
header: `确认计费转换`,
modal: ``,
closable: !unref(F),
"close-on-escape": !unref(F),
style: {
width: `min(460px, calc(100vw - 28px))`,
},
},
{
footer: withCtx(() => [
createVNode(
s,
{
label: `重新报价`,
text: ``,
disabled: unref(F) || unref(P),
onClick: $,
},
null,
8,
[`disabled`],
),
createVNode(
s,
{
label: `确认转换`,
loading: unref(F),
disabled: !unref(Z),
onClick: me,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
unref(P)
? (openBlock(),
createBlock(_, {
key: 0,
height: `90px`,
}))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
unref(E)
? (openBlock(),
createBlock(
b,
{
key: 0,
modelValue: unref(z),
"onUpdate:modelValue": (n[2] ||= (e) =>
isRef(z) ? (z.value = e) : null),
options: unref(R),
"option-label": `name_show`,
"option-value": `id`,
disabled: unref(F),
placeholder: `选择计费周期`,
},
null,
8,
[`modelValue`, `options`, `disabled`],
))
: createCommentVNode(``, !0),
unref(E) && unref(X)
? (openBlock(),
createElementBlock(
`p`,
ue,
`转换费用:¥` +
toDisplayString(unref(X).price),
1,
))
: createCommentVNode(``, !0),
!unref(E) && unref(B)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createElementVNode(
`p`,
null,
`到期后按需出账:¥` +
toDisplayString(
unref(B).on_demand_price,
) +
` / ` +
toDisplayString(
unref(B).billing_cycle_name,
),
1,
),
unref(B).keep_time_price
? (openBlock(),
createElementBlock(
`p`,
de,
`保留期价格:¥` +
toDisplayString(
unref(B).keep_time_price,
),
1,
))
: createCommentVNode(``, !0),
],
64,
))
: createCommentVNode(``, !0),
],
64,
)),
unref(I)
? (openBlock(),
createBlock(
i,
{
key: 2,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(I)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
createVNode(
C,
{
visible: unref(W),
"onUpdate:visible": (n[4] ||= (e) =>
isRef(W) ? (W.value = e) : null),
header: `取消转换计划`,
modal: ``,
closable: !unref(F),
style: {
width: `min(420px, calc(100vw - 28px))`,
},
},
{
footer: withCtx(() => [
createVNode(
s,
{
label: `确认取消计划`,
loading: unref(F),
onClick: he,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
(n[9] ||= createElementVNode(
`p`,
null,
`取消后将保留当前计费方式。`,
-1,
)),
unref(I)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `error`,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(I)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`],
),
createVNode(
C,
{
visible: unref(V),
"onUpdate:visible": (n[8] ||= (e) =>
isRef(V) ? (V.value = e) : null),
header: `自动释放设置`,
modal: ``,
closable: !unref(F),
"close-on-escape": !unref(F),
style: {
width: `min(460px, calc(100vw - 28px))`,
},
},
{
footer: withCtx(() => [
createVNode(
s,
{
label: `取消自动释放`,
text: ``,
disabled: unref(F),
onClick: (n[7] ||= (e) => (H.value = null)),
},
null,
8,
[`disabled`],
),
createVNode(
s,
{
label: `保存设置`,
loading: unref(F),
disabled: !unref(U),
onClick: _e,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
createVNode(
i,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
...(n[10] ||= [
createTextVNode(
`达到设定时间后,实例将自动释放,数据无法恢复。请提前备份。`,
-1,
),
]),
]),
_: 1,
},
),
createVNode(
T,
{
modelValue: unref(H),
"onUpdate:modelValue": (n[5] ||= (e) =>
isRef(H) ? (H.value = e) : null),
"show-time": ``,
"hour-format": `24`,
"date-format": `yy-mm-dd`,
disabled: unref(F),
placeholder: `选择释放时间,留空取消计划`,
fluid: ``,
},
null,
8,
[`modelValue`, `disabled`],
),
createElementVNode(`label`, fe, [
createVNode(
M,
{
modelValue: unref(U),
"onUpdate:modelValue": (n[6] ||= (e) =>
isRef(U) ? (U.value = e) : null),
binary: ``,
disabled: unref(F),
},
null,
8,
[`modelValue`, `disabled`],
),
(n[11] ||= createTextVNode(
`我已确认释放时间及数据影响`,
-1,
)),
]),
unref(I)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `error`,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(I)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
])
);
};
},
}),
[[`__scopeId`, `data-v-2710106c`]],
),
{
__name: `InstanceOnDemand`,
},
);
export {};
export default C;
</script>
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,640 @@
<script>
import "~/assets/styles/InstanceRenewDialog.BHDAL6d3.css";
import { toDisplayString } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { withKeys } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import inputtext from "primevue/inputtext";
import select from "primevue/select";
import OperationNotice from "~/components/OperationNotice.vue";
import OperatePasswordGate from "~/components/OperatePasswordGate.vue";
import password from "primevue/password";
import skeleton from "primevue/skeleton";
import { n as renewal_quote_n } from "~/lib/renewal-quote.js";
import { r as renewal_quote_r } from "~/lib/renewal-quote.js";
import { t as renewal_quote_t } from "~/lib/renewal-quote.js";
var ue = {
key: 0,
class: `rd`,
},
de = {
key: 1,
class: `rd`,
},
fe = {
class: `rd-row`,
},
pe = [`id`],
me = {
key: 0,
class: `rd-hint`,
},
he = {
class: `rd-row`,
},
ge = [`id`],
_e = [`for`],
ve = [`aria-labelledby`],
ye = {
class: `rd-code`,
},
T = {
key: 3,
class: `rd-promo rd-grow`,
},
E = {
class: `rd-row`,
},
D = [`for`],
O = {
class: `rd-quote`,
},
k = {
key: 0,
class: `rd-quote-row`,
},
A = {
class: `rd-discount`,
},
j = {
class: `rd-quote-row`,
},
M = {
class: `rd-price`,
},
N = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceRenewDialog`,
props: mergeModels(
{
hostId: {},
},
{
modelValue: {
type: Boolean,
default: !1,
},
modelModifiers: {},
},
),
emits: mergeModels([`paid`], [`update:modelValue`]),
setup(r, { emit: _ }) {
let x = useModel(r, `modelValue`),
N = r,
P = _,
F = useApi(),
I = ref(``),
L = useId(),
R = ref(!1),
z = ref(!1),
B = ref([]),
V = ref(``),
H = ref(``),
U = ref([]),
W = ref(``),
G = ref(``),
K = 0,
q = ref(``),
J = computed(
() => B.value.find((e) => e.billing_cycle === V.value) ?? null,
),
Y = () => JSON.stringify([N.hostId, U.value]),
X = computed(
() =>
x.value &&
!R.value &&
!z.value &&
!!V.value &&
!!J.value &&
q.value === Y(),
),
be = computed(() => J.value?.price ?? ``),
Z = computed(() => Number(J.value?.client_level_discount ?? 0));
async function Q() {
let e = ++K,
t = N.hostId,
n = Y(),
r = () => e === K && x.value && t === N.hostId && n === Y();
((R.value = !0), (H.value = ``), (q.value = ``), (B.value = []));
try {
let e = {};
U.value.length && (e[`customfield[promo_code]`] = U.value);
let i = await renewal_quote_t(
() => F.get(`/host/${t}/renew`, e),
r,
);
return r()
? ((B.value = renewal_quote_r(i.host)),
B.value.some((e) => e.billing_cycle === V.value) ||
(V.value =
B.value.find((e) => e.is_current_cycle === 1)
?.billing_cycle ??
B.value[0]?.billing_cycle ??
``),
(q.value = n),
!0)
: !1;
} catch (e) {
return (r() && (H.value = renewal_quote_n(e)), !1);
} finally {
e === K && (R.value = !1);
}
}
(watch(
x,
(e) => {
if (!e) {
(K++, (R.value = !1), (q.value = ``));
return;
}
((V.value = ``),
(U.value = []),
(W.value = ``),
(G.value = ``),
Q());
},
{
immediate: !0,
},
),
watch(
() => N.hostId,
() => {
x.value &&
((V.value = ``), (U.value = []), (W.value = ``), Q());
},
),
onBeforeUnmount(() => {
(K++, (R.value = !1));
}));
async function $() {
let e = W.value.trim();
if (!e || R.value || z.value) return;
let t = U.value.slice();
if (((U.value = [e]), !(await Q()))) {
let n = H.value;
U.value.length === 1 &&
U.value[0] === e &&
((U.value = t),
await Q(),
n && (H.value = `优惠码报价失败,已恢复原报价:${n}`));
return;
}
if (Number(J.value?.manual_promo_code_success ?? 0) !== 1) {
((U.value = t), await Q(), (H.value = `该优惠码不可用`));
return;
}
W.value = ``;
}
async function xe() {
R.value || z.value || ((U.value = []), await Q());
}
async function Se() {
if (X.value) {
((z.value = !0), (H.value = ``), (I.value = ``));
try {
let e = {
billing_cycle: V.value,
};
(U.value.length &&
(e.customfield = {
promo_code: U.value,
}),
G.value && (e.client_operate_password = G.value),
await F.post(`/host/${N.hostId}/renew`, e),
(x.value = !1),
P(`paid`));
} catch (e) {
I.value = e instanceof Error ? e.message : `续费失败`;
} finally {
z.value = !1;
}
}
}
return (t, n) => {
let r = OperationNotice,
i = skeleton,
a = select,
s = button,
u = inputtext,
_ = password,
b = OperatePasswordGate,
C = message,
w = dialog;
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createVNode(
r,
{
message: unref(I),
severity: `error`,
},
null,
8,
[`message`],
),
createVNode(
w,
{
visible: x.value,
"onUpdate:visible": (n[4] ||= (e) => (x.value = e)),
header: `续费`,
modal: ``,
draggable: !1,
style: {
width: `460px`,
maxWidth: `calc(100vw - 32px)`,
},
},
{
footer: withCtx(() => [
createVNode(s, {
label: `取消`,
severity: `secondary`,
text: ``,
onClick: (n[3] ||= (e) => (x.value = !1)),
}),
createVNode(
s,
{
label: `提交续费`,
loading: unref(z),
disabled: !unref(X),
onClick: Se,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
unref(R)
? (openBlock(),
createElementBlock(`div`, ue, [
createVNode(i, {
height: `120px`,
}),
]))
: unref(B).length
? (openBlock(),
createElementBlock(`div`, de, [
createElementVNode(`div`, fe, [
createElementVNode(
`span`,
{
id: `${unref(L)}-cycle-label`,
class: `rd-label`,
},
`续费周期`,
8,
pe,
),
createVNode(
a,
{
"input-id": `${unref(L)}-cycle`,
"aria-labelledby": `${unref(L)}-cycle-label`,
modelValue: unref(V),
"onUpdate:modelValue": (n[0] ||= (e) =>
isRef(V) ? (V.value = e) : null),
options: unref(B),
optionLabel: `name_show`,
optionValue: `billing_cycle`,
placeholder: `选择续费周期`,
class: `rd-grow`,
disabled: unref(R) || unref(z),
},
null,
8,
[
`input-id`,
`aria-labelledby`,
`modelValue`,
`options`,
`disabled`,
],
),
]),
unref(B).length === 1
? (openBlock(),
createElementBlock(
`p`,
me,
`该产品当前仅支持此续费周期。`,
))
: createCommentVNode(``, !0),
createElementVNode(`div`, he, [
unref(U).length
? (openBlock(),
createElementBlock(
`span`,
{
key: 0,
id: `${unref(L)}-promo-label`,
class: `rd-label`,
},
`优惠码`,
8,
ge,
))
: (openBlock(),
createElementBlock(
`label`,
{
key: 1,
for: `${unref(L)}-promo`,
},
`优惠码`,
8,
_e,
)),
unref(U).length
? (openBlock(),
createElementBlock(
`div`,
{
key: 2,
class: `rd-promo rd-grow`,
role: `group`,
"aria-labelledby": `${unref(L)}-promo-label`,
},
[
createElementVNode(
`span`,
ye,
toDisplayString(unref(U)[0]),
1,
),
createVNode(
s,
{
label: `取消`,
size: `small`,
severity: `secondary`,
text: ``,
disabled: unref(R) || unref(z),
onClick: xe,
},
null,
8,
[`disabled`],
),
],
8,
ve,
))
: (openBlock(),
createElementBlock(`div`, T, [
createVNode(
u,
{
id: `${unref(L)}-promo`,
modelValue: unref(W),
"onUpdate:modelValue": (n[1] ||= (
e,
) =>
isRef(W) ? (W.value = e) : null),
placeholder: `选填`,
class: `rd-grow`,
disabled: unref(R) || unref(z),
onKeyup: withKeys($, [`enter`]),
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
createVNode(
s,
{
label: `使用`,
size: `small`,
severity: `secondary`,
outlined: ``,
disabled:
!unref(W).trim() ||
unref(R) ||
unref(z),
onClick: $,
},
null,
8,
[`disabled`],
),
])),
]),
createVNode(b, null, {
default: withCtx(() => [
createElementVNode(`div`, E, [
createElementVNode(
`label`,
{
for: `${unref(L)}-operate-password`,
},
`操作密码`,
8,
D,
),
createVNode(
_,
{
modelValue: unref(G),
"onUpdate:modelValue": (n[2] ||= (
e,
) =>
isRef(G) ? (G.value = e) : null),
"input-id": `${unref(L)}-operate-password`,
feedback: !1,
"toggle-mask": ``,
class: `rd-grow`,
placeholder: `账户已设置时填写`,
disabled: unref(z),
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
]),
]),
_: 1,
}),
createElementVNode(`div`, O, [
unref(Z) > 0
? (openBlock(),
createElementBlock(`div`, k, [
(n[5] ||= createElementVNode(
`span`,
null,
`会员折扣`,
-1,
)),
createElementVNode(
`span`,
A,
`-¥` +
toDisplayString(
unref(Z).toFixed(2),
),
1,
),
]))
: createCommentVNode(``, !0),
createElementVNode(`div`, j, [
(n[6] ||= createElementVNode(
`span`,
null,
`应付金额`,
-1,
)),
createElementVNode(
`span`,
M,
`¥` + toDisplayString(unref(be)),
1,
),
]),
]),
unref(H)
? (openBlock(),
createBlock(
C,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(H)),
1,
),
createVNode(
s,
{
label: `重新获取价格`,
size: `small`,
severity: `secondary`,
text: ``,
disabled: unref(z),
onClick: Q,
},
null,
8,
[`disabled`],
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
(n[7] ||= createElementVNode(
`p`,
{
class: `rd-hint`,
},
`续费订单创建后需前往订单页完成支付。`,
-1,
)),
]))
: unref(H)
? (openBlock(),
createBlock(
C,
{
key: 3,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(H)),
1,
),
createVNode(
s,
{
label: `重新获取价格`,
size: `small`,
severity: `secondary`,
text: ``,
disabled: unref(z),
onClick: Q,
},
null,
8,
[`disabled`],
),
]),
_: 1,
},
))
: (openBlock(),
createBlock(
C,
{
key: 2,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(n[8] ||= [
createTextVNode(
`当前产品暂不可续费。`,
-1,
),
]),
]),
_: 1,
},
)),
]),
_: 1,
},
8,
[`visible`],
),
],
64,
)
);
};
},
}),
[[`__scopeId`, `data-v-01429388`]],
),
{
__name: `InstanceRenewDialog`,
},
);
export {};
export default N;
</script>
@@ -0,0 +1,435 @@
<script>
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
import "~/assets/styles/InstanceServiceInfo.BftSVIeW.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { normalizeClass } from "vue";
import { watch } from "vue";
import { defineAsyncComponent } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { navigateTo } from "#app";
import { loadModule } from "~/utils/load-module.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { r as dict_r } from "~/lib/dict.js";
import { n as instance_status_n } from "~/lib/instance-status.js";
import { t as instance_status_t } from "~/lib/instance-status.js";
import tag from "primevue/tag";
import { c as instance_data_c } from "~/lib/instance-data.js";
import { i as instance_data_i } from "~/lib/instance-data.js";
import { l as instance_data_l } from "~/lib/instance-data.js";
import { n as configuration_display_n } from "~/lib/configuration-display.js";
import FlowPacketPanel from "~/components/instance/FlowPacketPanel.vue";
var N = defineAsyncComponent(() =>
loadModule(
() =>
import("~/components/instance/InstanceRenewDialog.vue").then(
(e) => e.default || e,
),
[],
import.meta.url,
),
),
P = {
class: `service-info`,
"aria-label": `实例信息`,
},
F = {
class: `service-heading`,
},
I = {
key: 2,
class: `traffic-recovery`,
},
L = {
key: 3,
class: `traffic-recovery`,
},
R = {
class: `service-rows`,
},
z = [`aria-label`],
B = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceServiceInfo`,
props: {
host: {},
module: {},
info: {},
},
emits: [`pay`],
setup(i, { emit: g }) {
let b = i,
S = g,
B = computed(() =>
instance_status_t(
b.info?.powerStatus ?? b.info?.power_status,
b.host.status,
),
),
V = computed(() =>
instance_status_n(
b.host,
b.info?.powerStatus ?? b.info?.power_status,
),
),
H = computed(
() =>
b.host.status === `Suspended` &&
b.host.suspend_type === `overdue`,
),
U = computed(() =>
Number(b.host.renew_forbidden) === 1
? `该实例已禁止续费,请联系支持`
: Number(b.host.change_billing_cycle_id) > 0
? `请先取消到期转换计划后再续费`
: [`onetime`, `on_demand`].includes(
b.host.billing_cycle || ``,
)
? `该计费方式不支持续费,请联系支持`
: ``,
),
W = ref(!1);
function G() {
H.value && !U.value && (W.value = !0);
}
watch([() => b.host.id, () => H.value, () => U.value], () => {
W.value = !1;
});
let K = ref(!1),
q = computed(() => {
let e = b.info ?? {},
t = instance_data_l(e.raw ?? e),
n = instance_data_l(b.host.addition),
r = instance_data_l(e.image ?? t.image),
i = instance_data_l(t.model_config),
a = e.ip || b.host.ip || b.host.dedicate_ip || b.host.assign_ip,
o = configuration_display_n(b.module || ``, t, b.host),
s = String(e.password || n.password || ``);
return [
[`实例编号`, `#${b.host.id}`],
[`实例名称`, b.host.name || `—`],
[`配置摘要`, b.host.base_info || `—`],
[`区域`, o.region || `—`],
[`线路`, o.line || `—`],
[
`IP 地址`,
a || (b.host.status === `Pending` ? `待分配` : `未提供`),
],
[
`CPU`,
e.cpu
? `${e.cpu} ${b.module === `jy_dcim` ? `颗 CPU` : `核`}`
: i.cpu || `未提供`,
],
[`内存`, e.memory ? `${e.memory} GB` : i.memory || `未提供`],
[
`磁盘`,
instance_data_i(e.disks)
.map((e) => `${e.name} ${e.size} GB`)
.join(` / `) ||
i.disk ||
`未提供`,
],
[
`带宽`,
t.bw_show ||
(e.bw || t.bw || t.bandwidth
? `${e.bw || t.bw || t.bandwidth} Mbps`
: `未提供`),
],
[
`操作系统`,
r.name || b.host.image_name || n.image_name || `未提供`,
],
[`用户名`, e.username || n.username || `未提供`],
[
`连接端口`,
String(instance_data_c(e.port ?? n.port) || `未提供`),
],
[`密码`, s ? (K.value ? s : `••••••••`) : `未提供`],
[`计费周期`, b.host.billing_cycle_name || `—`],
[
`续费金额`,
b.host.renew_amount == null ? `—` : `¥${b.host.renew_amount}`,
],
[
`开通时间`,
b.host.active_time
? dict_r(b.host.active_time)
: b.host.status === `Pending` || b.host.status === `Unpaid`
? `尚未开通`
: `未提供`,
],
[`到期时间`, dict_r(b.host.due_time)],
];
}),
J = computed(() => {
let e = instance_data_l(b.info?.raw ?? b.info);
return instance_data_i(e.config_options ?? e.configoptions)
.map((e) => ({
label: String(e.option_name ?? e.name ?? ``),
value: String(e.sub_name ?? e.value ?? ``),
}))
.filter((e) => e.label && e.value);
});
return (r, o) => {
let l = tag,
g = message,
b = button,
w = FlowPacketPanel,
T = N;
return (
openBlock(),
createElementBlock(`section`, P, [
createElementVNode(`div`, F, [
(o[4] ||= createElementVNode(`h3`, null, `实例信息`, -1)),
createVNode(
l,
{
value: unref(B).label,
severity: unref(B).severity,
},
null,
8,
[`value`, `severity`],
),
]),
unref(V)
? (openBlock(),
createBlock(
g,
{
key: 0,
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
`暂停原因:` + toDisplayString(unref(V)),
1,
),
]),
_: 1,
},
))
: i.host.status === `Pending`
? (openBlock(),
createBlock(
g,
{
key: 1,
severity: `info`,
closable: !1,
},
{
default: withCtx(() => [
...(o[5] ||= [
createTextVNode(
`实例开通中,IP 和连接信息将在开通完成后显示。`,
-1,
),
]),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(H)
? (openBlock(),
createElementBlock(`div`, I, [
createElementVNode(
`p`,
null,
toDisplayString(
unref(U) ||
`可选择续费周期并完成付款。付款后由平台处理恢复,请稍后刷新查看实例状态。`,
),
1,
),
createElementVNode(`div`, null, [
createVNode(
b,
{
label: `立即续费`,
disabled: !!unref(U),
onClick: G,
},
null,
8,
[`disabled`],
),
]),
]))
: createCommentVNode(``, !0),
i.host.status === `Suspended` &&
i.host.suspend_type === `overtraffic`
? (openBlock(),
createElementBlock(`div`, L, [
(o[6] ||= createElementVNode(
`p`,
null,
`可购买流量包补充可用流量。付款后由平台处理恢复,请稍后刷新查看实例状态。`,
-1,
)),
createVNode(
w,
{
"host-id": String(i.host.id),
module: i.module,
flow: null,
mode: `button`,
onPay: (o[0] ||= (e) => S(`pay`, e)),
},
null,
8,
[`host-id`, `module`],
),
]))
: createCommentVNode(``, !0),
createElementVNode(`dl`, R, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(q),
([t, r]) => (
openBlock(),
createElementBlock(
`div`,
{
key: t,
},
[
createElementVNode(
`dt`,
null,
toDisplayString(t),
1,
),
createElementVNode(`dd`, null, [
createTextVNode(toDisplayString(r), 1),
t === `密码` && r !== `未提供`
? (openBlock(),
createElementBlock(
`button`,
{
key: 0,
type: `button`,
class: `password-toggle`,
"aria-label": unref(K)
? `隐藏密码`
: `显示密码`,
onClick: (o[1] ||= (e) =>
(K.value = !unref(K))),
},
[
createElementVNode(
`i`,
{
class: normalizeClass([
`pi`,
unref(K)
? `pi-eye-slash`
: `pi-eye`,
]),
},
null,
2,
),
],
8,
z,
))
: createCommentVNode(``, !0),
]),
],
)
),
),
128,
)),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(J),
(t, n) => (
openBlock(),
createElementBlock(
`div`,
{
key: `config-${n}`,
},
[
createElementVNode(
`dt`,
null,
toDisplayString(t.label),
1,
),
createElementVNode(
`dd`,
null,
toDisplayString(t.value),
1,
),
],
)
),
),
128,
)),
]),
unref(W)
? (openBlock(),
createBlock(
T,
{
key: 4,
modelValue: unref(W),
"onUpdate:modelValue": (o[2] ||= (e) =>
isRef(W) ? (W.value = e) : null),
"host-id": String(i.host.id),
onPaid: (o[3] ||= (e) =>
(`navigateTo` in r
? r.navigateTo
: unref(navigateTo))(`/orders`)),
},
null,
8,
[`modelValue`, `host-id`],
))
: createCommentVNode(``, !0),
])
);
};
},
}),
[[`__scopeId`, `data-v-0ff5d554`]],
),
{
__name: `InstanceServiceInfo`,
},
);
export {};
export default B;
</script>
+223
View File
@@ -0,0 +1,223 @@
<script>
import "~/assets/styles/GeetestField.DiieTibK.css";
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
import "~/assets/styles/InstanceSmsCode.CsITfIEU.css";
import { toDisplayString } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import inputtext from "primevue/inputtext";
import CaptchaField from "~/components/CaptchaField.vue";
import { t as interval_t } from "~/lib/interval.js";
import { t as useCaptcha_t } from "~/lib/useCaptcha.js";
var T = {
class: `instance-code`,
},
E = [`for`],
D = {
class: `code-row`,
},
O = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceSmsCode`,
props: mergeModels(
{
disabled: {
type: Boolean,
},
},
{
modelValue: {
default: ``,
},
modelModifiers: {},
},
),
emits: [`update:modelValue`],
setup(r) {
let m = r,
y = useModel(r, `modelValue`),
O = useApi(),
k = useCaptcha_t(`verify`),
{
needed: A,
provider: j,
captchaId: M,
img: N,
value: P,
loading: F,
error: I,
} = k,
L = useId(),
R = ref(!1),
z = ref(``),
B = ref(0),
V,
H = !1;
async function U() {
if (
!(m.disabled || R.value || B.value || H) &&
((z.value = k.validationError()), !z.value)
) {
R.value = !0;
try {
if (
(await O.post(`/phone/code`, {
action: `verify`,
captcha: k.value.value.trim(),
token: k.token.value,
}),
H)
)
return;
(k.invalidate(),
(B.value = 60),
(V = interval_t(() => {
--B.value <= 0 && (clearInterval(V), (V = void 0));
}, 1e3)),
k.needed.value && k.load());
} catch (e) {
H ||
((z.value =
e instanceof Error ? e.message : `验证码发送失败`),
await k.handleError(e));
} finally {
H || (R.value = !1);
}
}
}
return (
onBeforeUnmount(() => {
((H = !0), clearInterval(V), k.invalidate(), (y.value = ``));
}),
(t, n) => {
let i = inputtext,
o = button,
m = CaptchaField,
_ = message;
return (
openBlock(),
createElementBlock(`div`, T, [
createElementVNode(
`label`,
{
for: `${unref(L)}-code`,
},
`账户手机验证码`,
8,
E,
),
createElementVNode(`div`, D, [
createVNode(
i,
{
id: `${unref(L)}-code`,
modelValue: y.value,
"onUpdate:modelValue": (n[0] ||= (e) => (y.value = e)),
autocomplete: `one-time-code`,
disabled: r.disabled,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
createVNode(
o,
{
label: unref(B) ? `${unref(B)}s 后重试` : `发送验证码`,
outlined: ``,
loading: unref(R),
disabled: r.disabled || unref(B) > 0,
onClick: U,
},
null,
8,
[`label`, `loading`, `disabled`],
),
]),
unref(A)
? (openBlock(),
createBlock(
m,
{
key: 0,
modelValue: unref(P),
"onUpdate:modelValue": (n[1] ||= (e) =>
isRef(P) ? (P.value = e) : null),
img: unref(N),
provider: unref(j),
"captcha-id": unref(M),
loading: unref(F),
disabled: r.disabled || unref(R),
onVerified: unref(k).complete,
onInvalid: unref(k).invalidate,
onRefresh: unref(k).load,
},
null,
8,
[
`modelValue`,
`img`,
`provider`,
`captcha-id`,
`loading`,
`disabled`,
`onVerified`,
`onInvalid`,
`onRefresh`,
],
))
: createCommentVNode(``, !0),
unref(z) || unref(I)
? (openBlock(),
createBlock(
_,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(z) || unref(I)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-741dd729`]],
),
{
__name: `InstanceSmsCode`,
},
);
export {};
export default O;
</script>
@@ -0,0 +1,45 @@
<script>
import { createBlock } from "vue";
import { computed } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { openBlock } from "vue";
import { t as instance_status_t } from "~/lib/instance-status.js";
import tag from "primevue/tag";
var s = Object.assign(
defineComponent({
__name: `InstanceStatusTag`,
props: {
state: {},
power: {},
lifecycle: {},
},
setup(r) {
let s = r,
c = computed(() => s.state ?? instance_status_t(s.power, s.lifecycle));
return (t, r) => {
let a = tag;
return (
openBlock(),
createBlock(
a,
{
class: `instance-product-status`,
value: unref(c).label,
severity: unref(c).severity,
},
null,
8,
[`value`, `severity`],
)
);
};
},
}),
{
__name: `InstanceStatusTag`,
},
);
export {};
export default s;
</script>
+641
View File
@@ -0,0 +1,641 @@
<script>
import "~/assets/styles/InstanceTraffic.CyyEAXl3.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { normalizeClass } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { d as instance_data_d } from "~/lib/instance-data.js";
import { n as instance_data_n } from "~/lib/instance-data.js";
import progressbar from "primevue/progressbar";
var w = [`aria-busy`],
T = {
key: 0,
class: `traffic-progress`,
},
E = {
class: `traffic-row`,
},
D = {
class: `traffic-row`,
},
O = {
class: `traffic-row`,
},
k = {
class: `traffic-row`,
},
A = {
key: 1,
class: `traffic-row`,
},
j = {
key: 2,
class: `traffic-row`,
},
M = {
key: 3,
class: `traffic-row`,
},
N = {
key: 4,
class: `traffic-actions`,
},
P = {
key: 5,
class: `traffic-note`,
role: `status`,
},
F = {
key: 6,
class: `traffic-error`,
},
I = {
key: 1,
class: `traffic-note`,
role: `status`,
},
L = {
key: 2,
class: `traffic-error`,
},
R = {
key: 0,
class: `traffic-progress`,
},
z = {
class: `traffic-row`,
},
B = {
class: `traffic-row`,
},
V = {
class: `traffic-row`,
},
H = {
key: 1,
class: `traffic-row`,
},
U = {
key: 2,
class: `traffic-row`,
},
W = {
key: 3,
class: `traffic-note`,
},
G = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceTraffic`,
props: {
module: {},
hostId: {},
raw: {},
flow: {},
loading: {
type: Boolean,
},
failed: {
type: Boolean,
},
layout: {},
},
setup(m) {
let y = m,
G = useApi(),
K = ref(null),
q = ref(!1),
J = ref(``),
Y = computed(() =>
instance_data_d(
y.module,
y.raw,
y.module === `kky_ecs` ? K.value : y.flow,
),
),
X = 0,
Z = !1;
async function Q() {
if (Z) return;
let e = ++X,
t = y.hostId,
n = y.module,
r = () => !Z && e === X && t === y.hostId && n === y.module;
if (
((K.value = null),
(J.value = ``),
(q.value = !1),
n === `kky_ecs` && t)
) {
q.value = !0;
try {
let e = await G.get(`/kky_ecs/${t}/traffic`);
r() &&
((K.value = e),
e.usage_status === `unavailable` &&
(J.value =
e.usage_error || `流量统计暂不可用,请稍后重试`));
} catch (e) {
r() &&
(J.value =
e instanceof Error ? e.message : `流量数据获取失败`);
} finally {
r() && (q.value = !1);
}
}
}
return (
onMounted(Q),
watch(() => [y.hostId, y.module, y.raw], Q, {
flush: `sync`,
}),
onBeforeUnmount(() => {
((Z = !0), X++);
}),
(t, r) => {
let i = progressbar,
a = button,
c = message;
return (
openBlock(),
createElementBlock(
`div`,
{
class: normalizeClass([
`traffic-summary`,
{
"traffic-table": m.layout === `table`,
},
]),
"aria-busy": m.module === `kky_ecs` ? unref(q) : m.loading,
},
[
m.module === `kky_ecs`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
unref(Y).quota && unref(Y).quota.percent !== null
? (openBlock(),
createElementBlock(`div`, T, [
createVNode(
i,
{
value: unref(Y).quota.percent,
showValue: !1,
"aria-label": `当前流量包使用进度`,
style: {
height: `6px`,
},
},
null,
8,
[`value`],
),
]))
: createCommentVNode(``, !0),
createElementVNode(`div`, E, [
(r[0] ||= createElementVNode(
`span`,
null,
`已用流量`,
-1,
)),
createElementVNode(`b`, null, [
createTextVNode(
toDisplayString(
unref(Y).quota
? unref(instance_data_n)(
unref(Y).quota.used,
)
: `—`,
),
1,
),
unref(Y).quota &&
unref(Y).quota.percent !== null
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`(` +
toDisplayString(
unref(Y).quota.percent.toFixed(1),
) +
`%)`,
1,
),
],
64,
))
: createCommentVNode(``, !0),
]),
]),
createElementVNode(`div`, D, [
(r[1] ||= createElementVNode(
`span`,
null,
`总流量`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).quota
? unref(instance_data_n)(
unref(Y).quota.total,
)
: unref(Y).quotaLoaded
? unref(Y).metered
? unref(Y).monthlyQuota
? `暂无有效流量包`
: `无固定额度`
: `不限量`
: `—`,
),
1,
),
]),
createElementVNode(`div`, O, [
(r[2] ||= createElementVNode(
`span`,
null,
`剩余流量`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).quota
? unref(instance_data_n)(
unref(Y).quota.remaining,
)
: unref(Y).quotaLoaded
? unref(Y).metered
? `无可抵扣流量`
: `不限量`
: `—`,
),
1,
),
]),
createElementVNode(`div`, k, [
(r[3] ||= createElementVNode(
`span`,
null,
`网络计费`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).metered
? `按流量计费 · 按小时结算`
: `按带宽计费`,
),
1,
),
]),
unref(Y).metered
? (openBlock(),
createElementBlock(`div`, A, [
(r[4] ||= createElementVNode(
`span`,
null,
`超额流量单价`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).unitPrice === null
? `—`
: `¥${unref(Y).unitPrice.toFixed(2)} / GB`,
),
1,
),
]))
: createCommentVNode(``, !0),
unref(Y).metered && unref(Y).monthlyQuota !== null
? (openBlock(),
createElementBlock(`div`, j, [
(r[5] ||= createElementVNode(
`span`,
null,
`每月赠送额度`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(instance_data_n)(
unref(Y).monthlyQuota,
),
),
1,
),
]))
: createCommentVNode(``, !0),
!unref(Y).quota &&
unref(Y).packageRemaining !== null
? (openBlock(),
createElementBlock(`div`, M, [
(r[6] ||= createElementVNode(
`span`,
null,
`流量包剩余`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(instance_data_n)(
unref(Y).packageRemaining,
),
),
1,
),
]))
: createCommentVNode(``, !0),
m.hostId && !unref(J)
? (openBlock(),
createElementBlock(`div`, N, [
createVNode(
a,
{
label: `刷新流量数据`,
icon: `pi pi-refresh`,
size: `small`,
severity: `secondary`,
text: ``,
loading: unref(q),
onClick: Q,
},
null,
8,
[`loading`],
),
]))
: createCommentVNode(``, !0),
unref(q)
? (openBlock(),
createElementBlock(`p`, P, `正在加载流量数据…`))
: unref(J)
? (openBlock(),
createElementBlock(`div`, F, [
createVNode(
c,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(J)),
1,
),
]),
_: 1,
},
),
createVNode(a, {
label: `重试`,
size: `small`,
severity: `secondary`,
outlined: ``,
onClick: Q,
}),
]))
: createCommentVNode(``, !0),
],
64,
))
: m.loading
? (openBlock(),
createElementBlock(`p`, I, `正在加载流量数据…`))
: m.failed
? (openBlock(),
createElementBlock(`div`, L, [
createVNode(
c,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
...(r[7] ||= [
createTextVNode(
`流量数据获取失败,请刷新后重试。`,
-1,
),
]),
]),
_: 1,
},
),
]))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 3,
},
[
unref(Y).percent === null
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, R, [
createVNode(
i,
{
value: unref(Y).percent,
showValue: !1,
style: {
height: `6px`,
},
},
null,
8,
[`value`],
),
])),
createElementVNode(`div`, z, [
(r[8] ||= createElementVNode(
`span`,
null,
`已用流量`,
-1,
)),
createElementVNode(`b`, null, [
createTextVNode(
toDisplayString(
unref(instance_data_n)(unref(Y).used),
),
1,
),
unref(Y).percent === null
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`(` +
toDisplayString(
unref(Y).percent.toFixed(1),
) +
`%)`,
1,
),
],
64,
)),
]),
]),
createElementVNode(`div`, B, [
(r[9] ||= createElementVNode(
`span`,
null,
`总流量`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).unlimited
? `不限量`
: unref(instance_data_n)(
unref(Y).total,
),
),
1,
),
]),
createElementVNode(`div`, V, [
(r[10] ||= createElementVNode(
`span`,
null,
`剩余流量`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(Y).unlimited
? `不限量`
: unref(instance_data_n)(
unref(Y).remaining,
),
),
1,
),
]),
unref(Y).packageRemaining === null
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, H, [
(r[11] ||= createElementVNode(
`span`,
null,
`流量包剩余`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(
unref(instance_data_n)(
unref(Y).packageRemaining,
),
),
1,
),
])),
unref(Y).reset
? (openBlock(),
createElementBlock(`div`, U, [
(r[12] ||= createElementVNode(
`span`,
null,
`重置时间`,
-1,
)),
createElementVNode(
`b`,
null,
toDisplayString(unref(Y).reset),
1,
),
]))
: createCommentVNode(``, !0),
unref(Y).used === null
? (openBlock(),
createElementBlock(
`p`,
W,
toDisplayString(
unref(Y).metered
? `按流量计费,当前用量暂未返回。`
: `当前用量暂未返回。`,
),
1,
))
: createCommentVNode(``, !0),
],
64,
)),
],
10,
w,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-484c7b21`]],
),
{
__name: `InstanceTraffic`,
},
);
export {};
export default G;
</script>
@@ -0,0 +1,870 @@
<script>
import "~/assets/styles/LegacyDcimActions.DcIrQby6.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import inputtext from "primevue/inputtext";
import { n as product_name_n } from "~/lib/product-name.js";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import checkbox from "primevue/checkbox";
import OperationNotice from "~/components/OperationNotice.vue";
import OperatePasswordGate from "~/components/OperatePasswordGate.vue";
import { t as os_name_t } from "~/lib/os-name.js";
import { t as remote_console_t } from "~/lib/remote-console.js";
var de = {
class: `legacy-actions`,
},
fe = {
class: `action-buttons`,
},
pe = {
class: `action-form`,
},
me = {
class: `target`,
},
he = [`for`],
ge = {
key: 0,
class: `muted`,
},
_e = [`for`],
ve = [`for`],
ye = [`for`],
be = {
key: 0,
class: `muted`,
},
xe = [`for`],
Se = [`for`],
Ce = {
key: 4,
class: `ack`,
},
we = [`for`],
S = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `LegacyDcimActions`,
props: {
hostId: {},
host: {},
data: {},
disabled: {
type: Boolean,
},
},
emits: [`refresh`],
setup(g, { expose: b, emit: S }) {
let C = g,
Te = S,
Ee = useApi(),
w = useId(),
T = (e) =>
e && typeof e == `object` && !Array.isArray(e) ? e : null,
E = (e) =>
e === !0 || e === 1 || e === `1` || e === `on` || e === `true`,
D = (e) =>
e === !1 || e === 0 || e === `0` || e === `off` || e === `false`,
O = {
vnc: `打开 VNC 控制台`,
reset_password: `重置密码`,
reinstall: `重装系统`,
rescue: `进入救援模式`,
cancel_task: `取消当前任务`,
reset_bmc: `重置 BMC`,
},
k = {
vnc: `novnc`,
reset_password: `crack_pass`,
reinstall: `reinstall`,
rescue: `rescue`,
cancel_task: `rescue`,
reset_bmc: `reset_bmc`,
},
A = computed(() => T(C.data)),
j = computed(() => T(A.value?.dcim)),
De = ref(C.hostId),
M = computed(
() =>
!C.disabled &&
/^[1-9]\d*$/.test(C.hostId) &&
String(C.host.id) === C.hostId &&
De.value === C.hostId &&
C.host.status === `Active` &&
!!A.value &&
!!j.value,
);
function Oe(e) {
let t = A.value?.module_button,
n = Array.isArray(t) ? t : [t];
for (let t of n) {
let n = T(t);
if (!n) continue;
let r =
`func` in n
? [n]
: [n.console, n.control].flatMap((e) =>
Array.isArray(e) ? e : [],
);
for (let t of r) {
let n = T(t);
if (
!(
!n ||
(n.type && n.type !== "default") ||
![e, k[e]].includes(String(n.func))
) &&
(E(n.disabled) || D(n.enabled) || D(n.enable))
)
return !0;
}
}
return !1;
}
function N(e) {
if (!Object.hasOwn(O, e) || !j.value || Oe(e)) return !1;
let t = j.value.auth,
n = T(t);
return e === `reset_bmc`
? !!n && E(n.reset_bmc)
: D(t) || (n && (D(n[k[e]]) || D(n[e])))
? !1
: E(t) || !!(n && E(n[k[e]]));
}
let ke = computed(() => Object.keys(O).filter(N)),
P = computed(() => {
let e = [
...(Array.isArray(A.value?.cloud_os_group)
? A.value.cloud_os_group
: []),
...(Array.isArray(j.value?.os_group) ? j.value.os_group : []),
],
t = Array.isArray(A.value?.cloud_os) ? A.value.cloud_os : [],
n = Array.isArray(j.value?.os) ? j.value.os : [],
r = [];
for (let i of t.length ? t : n) {
let t = T(i);
if (
!t ||
!Number.isSafeInteger(Number(t.id)) ||
Number(t.id) <= 0 ||
typeof t.name != `string` ||
!t.name.trim()
)
continue;
let n = t.group ?? t.group_id,
a = e.map(T).find((e) => e && String(e.id) === String(n)),
o = typeof a?.name == `string` ? a.name : ``;
r.some((e) => e.id === Number(t.id)) ||
r.push({
id: Number(t.id),
name: t.name,
group: o,
windows:
Number(t.ostype) === 1 ||
/windows/i.test(t.name + ` ` + o),
});
}
return r;
}),
Ae = (e) => os_name_t(e.name),
F = ref(null),
I = ref(``),
L = ref(!1),
R = ref(``),
z = ref(``),
B = ref(null),
V = ref(22),
H = ref(0),
U = ref(2),
W = ref(!1),
G = ref(``),
K = ref(!1),
q = ref(``),
J = computed(() => P.value.find((e) => e.id === B.value)),
Y = computed(
() => F.value === `reset_password` || F.value === `reinstall`,
),
je = computed(() =>
F.value === `reinstall`
? J.value?.windows && H.value === 1
? `重装将格式化第一分区并删除其中的数据。请先完成备份,再确认继续。`
: `重装将格式化全盘并删除数据。请先完成备份,再确认继续。`
: F.value === `rescue`
? `进入救援模式可能中断当前连接和服务,请确认可以暂时停止业务。`
: F.value === `cancel_task`
? `取消当前重装或救援任务可能使系统暂时不可用,请确认后继续。`
: F.value === `reset_bmc`
? `重置 BMC 会暂时中断带外管理连接,请确认后继续。`
: `重置后请使用新密码连接服务器。部分系统可能需要重启后生效。`,
),
Me = computed(() => {
let e = T(T(A.value?.host_data)?.password_rule),
t = T(e?.rule);
if (!t) return ``;
let n = [],
r = Number(t.len_num);
Number.isSafeInteger(r) && r > 0 && r <= 128 && n.push(`${r} 位`);
for (let [e, r] of [
[`upper`, `大写字母`],
[`lower`, `小写字母`],
[`num`, `数字`],
[`special`, `特殊字符`],
])
e && r && E(t[e]) && n.push(r);
return n.length
? `服务器密码要求:${n.join(`、`)},具体规则由服务器校验。`
: ``;
}),
X = 0,
Z = !1,
Q = null;
function Ne(e) {
return (
!Z && M.value && N(e) && I.value === C.hostId && Q === C.data
);
}
function $() {
(X++,
(F.value = null),
(I.value = ``),
(Q = null),
(L.value = !1),
(R.value = ``),
(z.value = ``),
(G.value = ``),
(q.value = ``),
(K.value = !1));
}
function Pe() {
L.value || $();
}
function Fe(e) {
if (!Z && !L.value && M.value && N(e)) {
if (e === `vnc`) {
remote_console_t(C.hostId, `remf_finance_dcim`);
return;
}
(X++,
(I.value = C.hostId),
(Q = C.data),
(F.value = e),
(R.value = ``),
(z.value = ``),
(G.value = ``),
(q.value = ``),
(K.value = !1),
(B.value = null),
(V.value = 22),
(H.value = 0),
(U.value = 2),
(W.value = !1));
}
}
async function Ie() {
let e = F.value;
if (!e || e === `vnc` || L.value || !Ne(e)) return;
if (
((G.value = ``),
(K.value = !1),
Y.value && (!R.value.trim() || R.value.includes(`\0`)))
) {
G.value = `请输入有效的新密码`;
return;
}
if (e === `reinstall`) {
if (!J.value) {
G.value = `请选择可用的操作系统`;
return;
}
if (
!Number.isInteger(V.value) ||
Number(V.value) < 1 ||
Number(V.value) > 65535
) {
G.value = `请输入 1 到 65535 之间的端口`;
return;
}
if (![0, 1].includes(H.value)) {
G.value = `请选择有效的分区方式`;
return;
}
if (!W.value) {
G.value = `请确认已备份数据并了解重装影响`;
return;
}
}
if (e === `rescue` && ![1, 2].includes(U.value)) {
G.value = `请选择救援系统`;
return;
}
let t = X,
n = C.hostId,
r = {
client_operate_password: z.value,
};
(Y.value && (r.password = R.value),
e === `rescue` && (r.type = U.value),
e === `reinstall` &&
Object.assign(r, {
os: B.value,
port: V.value,
part_type: J.value?.windows ? H.value : 0,
}));
let i = () => t === X && Ne(e);
L.value = !0;
try {
if ((await Ee.post(`/remf_finance_dcim/${n}/${e}`, r), !i()))
return;
((q.value = `${O[e]}指令已提交,请等待实例状态更新。`),
(F.value = null),
(R.value = ``),
(z.value = ``),
Te(`refresh`));
} catch (t) {
i() &&
((K.value = !0),
(G.value =
t instanceof Error ? t.message : `${O[e]}失败,请重试`));
} finally {
t === X && (L.value = !1);
}
}
return (
watch(
[
() => C.hostId,
() => C.host.id,
() => C.host.status,
() => C.host.module,
() => C.data,
() => C.disabled,
],
$,
{
flush: `sync`,
},
),
watch(
() => C.data,
() => {
De.value = C.hostId;
},
{
flush: `sync`,
},
),
watch(B, () => {
((V.value = J.value?.windows ? 3389 : 22), (H.value = 0));
}),
onBeforeUnmount(() => {
((Z = !0), $());
}),
b({
request: Fe,
busy: L,
}),
(n, r) => {
let i = button,
o = OperationNotice,
l = message,
y = select,
b = inputnumber,
x = inputtext,
ue = OperatePasswordGate,
S = checkbox,
C = dialog;
return (
openBlock(),
createElementBlock(`div`, de, [
createElementVNode(`div`, fe, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(ke),
(e) => (
openBlock(),
createBlock(
i,
{
key: e,
label: O[e],
icon:
e === `vnc`
? `pi pi-desktop`
: e === `reset_password`
? `pi pi-key`
: `pi pi-wrench`,
outlined: ``,
size: `small`,
disabled: !unref(M) || unref(L),
onClick: (t) => Fe(e),
},
null,
8,
[`label`, `icon`, `disabled`, `onClick`],
)
),
),
128,
)),
]),
unref(q)
? (openBlock(),
createBlock(
o,
{
key: 0,
message: unref(q),
},
null,
8,
[`message`],
))
: createCommentVNode(``, !0),
unref(G) && unref(K)
? (openBlock(),
createBlock(
o,
{
key: 1,
severity: `error`,
message: unref(G),
},
null,
8,
[`message`],
))
: createCommentVNode(``, !0),
createVNode(
C,
{
visible: !!unref(F),
header: unref(F) ? O[unref(F)] : ``,
modal: ``,
style: {
width: `540px`,
maxWidth: `calc(100vw - 24px)`,
},
draggable: !1,
closable: !unref(L),
"close-on-escape": !unref(L),
"onUpdate:visible": (r[7] ||= (e) => {
e || Pe();
}),
},
{
footer: withCtx(() => [
createVNode(
i,
{
label: `取消`,
outlined: ``,
severity: `secondary`,
disabled: unref(L),
onClick: Pe,
},
null,
8,
[`disabled`],
),
createVNode(
i,
{
label: `确认${unref(F) ? O[unref(F)] : ``}`,
severity: `danger`,
loading: unref(L),
disabled:
unref(L) ||
!unref(M) ||
!unref(F) ||
!N(unref(F)),
onClick: Ie,
},
null,
8,
[`label`, `loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, pe, [
createElementVNode(`p`, me, [
(r[8] ||= createTextVNode(`目标实例:`, -1)),
createElementVNode(
`strong`,
null,
toDisplayString(
g.host.name ||
unref(product_name_n)(g.host.product_name),
),
1,
),
createTextVNode(
`(#` + toDisplayString(g.hostId) + `)`,
1,
),
]),
createVNode(
l,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(je)), 1),
]),
_: 1,
},
),
unref(G) && !unref(K)
? (openBlock(),
createBlock(
l,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(G)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(F) === `reinstall`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`label`,
{
for: `${unref(w)}-image`,
},
`操作系统`,
8,
he,
),
createVNode(
y,
{
modelValue: unref(B),
"onUpdate:modelValue": (r[0] ||= (e) =>
isRef(B) ? (B.value = e) : null),
"input-id": `${unref(w)}-image`,
options: unref(P),
"option-label": Ae,
"option-value": `id`,
placeholder: `请选择操作系统`,
disabled: unref(L),
fluid: ``,
},
null,
8,
[
`modelValue`,
`input-id`,
`options`,
`disabled`,
],
),
unref(P).length
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
ge,
`此实例暂无可用系统镜像,请刷新详情后重试。`,
)),
createElementVNode(
`label`,
{
for: `${unref(w)}-port`,
},
`连接端口`,
8,
_e,
),
createVNode(
b,
{
modelValue: unref(V),
"onUpdate:modelValue": (r[1] ||= (e) =>
isRef(V) ? (V.value = e) : null),
"input-id": `${unref(w)}-port`,
min: 1,
max: 65535,
"use-grouping": !1,
disabled: unref(L),
fluid: ``,
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
unref(J)?.windows
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`label`,
{
for: `${unref(w)}-partition`,
},
`分区方式`,
8,
ve,
),
createVNode(
y,
{
modelValue: unref(H),
"onUpdate:modelValue": (r[2] ||= (
e,
) =>
isRef(H)
? (H.value = e)
: null),
"input-id": `${unref(w)}-partition`,
options: [
{
label: `格式化全盘`,
value: 0,
},
{
label: `仅格式化第一分区`,
value: 1,
},
],
"option-label": `label`,
"option-value": `value`,
disabled: unref(L),
fluid: ``,
},
null,
8,
[
`modelValue`,
`input-id`,
`disabled`,
],
),
],
64,
))
: createCommentVNode(``, !0),
],
64,
))
: createCommentVNode(``, !0),
unref(Y)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createElementVNode(
`label`,
{
for: `${unref(w)}-password`,
},
`新密码`,
8,
ye,
),
createVNode(
x,
{
id: `${unref(w)}-password`,
modelValue: unref(R),
"onUpdate:modelValue": (r[3] ||= (e) =>
isRef(R) ? (R.value = e) : null),
type: `password`,
autocomplete: `new-password`,
disabled: unref(L),
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
unref(Me)
? (openBlock(),
createElementBlock(
`p`,
be,
toDisplayString(unref(Me)),
1,
))
: createCommentVNode(``, !0),
],
64,
))
: createCommentVNode(``, !0),
unref(F) === `rescue`
? (openBlock(),
createElementBlock(
Fragment,
{
key: 3,
},
[
createElementVNode(
`label`,
{
for: `${unref(w)}-rescue`,
},
`救援系统`,
8,
xe,
),
createVNode(
y,
{
modelValue: unref(U),
"onUpdate:modelValue": (r[4] ||= (e) =>
isRef(U) ? (U.value = e) : null),
"input-id": `${unref(w)}-rescue`,
options: [
{
label: `Linux`,
value: 2,
},
{
label: `Windows`,
value: 1,
},
],
"option-label": `label`,
"option-value": `value`,
disabled: unref(L),
fluid: ``,
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
],
64,
))
: createCommentVNode(``, !0),
createVNode(ue, null, {
default: withCtx(() => [
createElementVNode(
`label`,
{
for: `${unref(w)}-operate`,
},
`操作密码(如已设置)`,
8,
Se,
),
createVNode(
x,
{
id: `${unref(w)}-operate`,
modelValue: unref(z),
"onUpdate:modelValue": (r[5] ||= (e) =>
isRef(z) ? (z.value = e) : null),
type: `password`,
autocomplete: `off`,
disabled: unref(L),
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
]),
_: 1,
}),
unref(F) === `reinstall`
? (openBlock(),
createElementBlock(`div`, Ce, [
createVNode(
S,
{
modelValue: unref(W),
"onUpdate:modelValue": (r[6] ||= (e) =>
isRef(W) ? (W.value = e) : null),
"input-id": `${unref(w)}-ack`,
binary: ``,
disabled: unref(L),
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
createElementVNode(
`label`,
{
for: `${unref(w)}-ack`,
},
`我已备份数据,了解所选分区的数据将被清除`,
8,
we,
),
]))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`, `header`, `closable`, `close-on-escape`],
),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-e3236d5c`]],
),
{
__name: `LegacyDcimActions`,
},
);
export {};
export default S;
</script>
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,340 @@
<script>
import "~/assets/styles/LegacyProductUpgrade.dzWGwGgY.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import select from "primevue/select";
var C = {
key: 0,
class: `product-upgrade`,
},
w = {
key: 2,
},
T = {
key: 0,
},
E = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `LegacyProductUpgrade`,
props: {
hostId: {},
module: {
default: `remf_finance`,
},
upgradeAllowed: {
type: Boolean,
default: !0,
},
},
emits: [`pay`],
setup(h, { expose: b, emit: E }) {
let D = h,
O = E,
k = useApi(),
A = ref([]),
j = ref(null),
M = ref(``),
N = ref(!1),
P = ref(!1),
F = ref(!1),
I = ref(``),
L = ref(``),
R = computed(() => A.value.find((e) => e.pid === j.value)),
z = computed(() =>
JSON.stringify([D.hostId, D.module, j.value, M.value]),
),
B = 0,
V = 0,
H = !1,
U = ``;
function W() {
(B++, (L.value = ``), (U = ``), (P.value = !1), (I.value = ``));
}
async function G() {
if (D.upgradeAllowed === !1 || H) return;
let e = ++V;
((N.value = !0), (I.value = ``), W());
try {
let t = await k.get(`/${D.module}/${D.hostId}/upgrade_product`);
if (H || e !== V) return;
if (!Array.isArray(t.host))
throw Error(`可升级商品列表无效,请重试`);
((A.value = t.host.filter(
(e) =>
/^[1-9]\d*$/.test(String(e.pid)) && Array.isArray(e.cycle),
)),
(j.value = null),
(M.value = ``));
} catch (t) {
!H &&
e === V &&
(I.value = t instanceof Error ? t.message : `升级商品加载失败`);
} finally {
e === V && (N.value = !1);
}
}
async function K() {
if (
D.upgradeAllowed === !1 ||
F.value ||
!R.value?.cycle.some((e) => e.billingcycle === M.value)
)
return;
let e = ++B,
t = z.value;
((P.value = !0), (L.value = ``), (I.value = ``), (U = ``));
try {
let n = await k.post(
`/${D.module}/${D.hostId}/sync_upgrade_product_price`,
{
product_id: j.value,
cycle: M.value,
},
);
if (H || e !== B || t !== z.value) return;
if (
n.price === null ||
n.price === void 0 ||
String(n.price).trim() === `` ||
!Number.isFinite(Number(n.price))
)
throw Error(`升级报价无效,请重试`);
((L.value = String(n.price)), (U = t));
} catch (t) {
!H &&
e === B &&
(I.value = t instanceof Error ? t.message : `升级询价失败`);
} finally {
e === B && (P.value = !1);
}
}
async function q() {
if (
D.upgradeAllowed === !1 ||
F.value ||
P.value ||
!L.value ||
U !== z.value ||
H
)
return;
let e = z.value,
t = L.value,
n = {
product_id: j.value,
cycle: M.value,
};
((F.value = !0), (I.value = ``));
try {
let r = await k.post(
`/${D.module}/${D.hostId}/upgrade_product`,
n,
);
if (H || e !== z.value) return;
if (!/^[1-9]\d*$/.test(String(r.id)))
throw Error(`升级订单无效,请重试`);
(W(),
O(`pay`, {
order_id: r.id,
amount: t,
}));
} catch (t) {
!H &&
e === z.value &&
(I.value = t instanceof Error ? t.message : `升级订单创建失败`);
} finally {
H || (F.value = !1);
}
}
return (
watch(
j,
() => {
((M.value = ``), W());
},
{
flush: `sync`,
},
),
watch(M, W, {
flush: `sync`,
}),
watch(
[() => D.hostId, () => D.module, () => D.upgradeAllowed],
() => {
(W(), (A.value = []), (j.value = null), G());
},
{
flush: `sync`,
},
),
onMounted(G),
onBeforeUnmount(() => {
((H = !0), B++, V++);
}),
b({
busy: F,
}),
(t, n) => {
let r = message,
a = button,
c = select;
return h.upgradeAllowed === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`section`, C, [
(n[2] ||= createElementVNode(`h4`, null, `变更商品`, -1)),
unref(I)
? (openBlock(),
createBlock(
r,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(I)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(A).length
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
a,
{
key: 1,
label: unref(N)
? `正在加载可升级商品`
: `刷新可升级商品`,
text: ``,
loading: unref(N),
onClick: G,
},
null,
8,
[`label`, `loading`],
)),
!unref(N) && !unref(I) && !unref(A).length
? (openBlock(),
createElementBlock(`p`, w, `当前暂无可升级商品。`))
: createCommentVNode(``, !0),
unref(A).length
? (openBlock(),
createElementBlock(
Fragment,
{
key: 3,
},
[
createVNode(
c,
{
modelValue: unref(j),
"onUpdate:modelValue": (n[0] ||= (e) =>
isRef(j) ? (j.value = e) : null),
"aria-label": `升级目标商品`,
options: unref(A),
"option-label": `host`,
"option-value": `pid`,
placeholder: `选择目标商品`,
disabled: unref(F),
},
null,
8,
[`modelValue`, `options`, `disabled`],
),
createVNode(
c,
{
modelValue: unref(M),
"onUpdate:modelValue": (n[1] ||= (e) =>
isRef(M) ? (M.value = e) : null),
"aria-label": `升级计费周期`,
options: unref(R)?.cycle ?? [],
"option-label": `billingcycle_zh`,
"option-value": `billingcycle`,
placeholder: `选择计费周期`,
disabled: unref(F) || !unref(R),
},
null,
8,
[`modelValue`, `options`, `disabled`],
),
createVNode(
a,
{
label: `计算变更费用`,
outlined: ``,
loading: unref(P),
disabled: unref(F) || !unref(M),
onClick: K,
},
null,
8,
[`loading`, `disabled`],
),
unref(L) === ``
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
T,
`变更费用:¥` + toDisplayString(unref(L)),
1,
)),
createVNode(
a,
{
label: `确认生成升级订单`,
loading: unref(F),
disabled: unref(L) === `` || unref(P),
onClick: q,
},
null,
8,
[`loading`, `disabled`],
),
],
64,
))
: createCommentVNode(``, !0),
]));
}
);
},
}),
[[`__scopeId`, `data-v-3bd25322`]],
),
{
__name: `LegacyProductUpgrade`,
},
);
export {};
export default E;
</script>
+641
View File
@@ -0,0 +1,641 @@
<script>
import "~/assets/styles/RemfUpgrade.4stQ5ASH.css";
import { nextTick } from "vue";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import OperationNotice from "~/components/OperationNotice.vue";
import { t as configuration_display_t } from "~/lib/configuration-display.js";
var se = {
key: 0,
class: `upg`,
},
ce = {
key: 0,
class: `upg-state`,
},
le = {
key: 1,
class: `upg-state`,
},
x = {
class: `info-table`,
},
S = [`id`, `for`],
C = {
class: `config-field`,
},
w = {
key: 3,
class: `upg-unsupported`,
},
T = {
class: `kv`,
},
ue = {
class: `upg-price`,
"aria-live": `polite`,
},
de = {
key: 0,
class: `upg-loading`,
},
fe = {
key: 1,
},
pe = {
key: 2,
class: `upg-idle`,
},
me = {
key: 3,
},
he = {
class: `kv`,
},
ge = {
class: `action-cell`,
},
_e = {
key: 0,
class: `upg-note`,
},
E = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `RemfUpgrade`,
props: {
hostId: {},
module: {
default: `remf_finance`,
},
upgradeAllowed: {
type: Boolean,
default: !0,
},
},
emits: [`pay`],
setup(h, { expose: v, emit: E }) {
let D = h,
O = computed(() => D.module || `remf_finance`),
ve = E,
k = useApi(),
A = ref(``),
j = useId(),
M = [4, 7, 9, 11, 14, 15, 16, 17, 18, 19],
N = [1, 2, 3, 6, 8, 10, 13],
P = ref([]),
F = ref({}),
I = ref(!1),
L = ref(``),
R = ref(``),
z = ref(``),
B = ref(!1),
V = ref(!1),
H = ref(!1),
U = !1,
W,
G = 0,
K = !1,
q = 0,
J = ``,
Y = computed(() => JSON.stringify([D.hostId, O.value, F.value]));
function X(e) {
return e.option_type === 5 && e.sub && !Array.isArray(e.sub)
? Object.entries(e.sub).flatMap(([e, t]) =>
(t.child ?? []).map((t) => ({
...t,
option_name: `${e} / ${t.version || t.option_name || t.id}`,
})),
)
: e.option_type === 12 && Array.isArray(e.sub)
? e.sub.flatMap((e) =>
(e.area ?? []).map((t) => ({
id: t.id,
option_name: [e.option_name, t.area_zh || t.area]
.filter(Boolean)
.join(` / `),
})),
)
: Array.isArray(e.sub)
? e.sub
: [];
}
let Z = (e) =>
M.includes(e.option_type) ||
N.includes(e.option_type) ||
([5, 12].includes(e.option_type) && X(e).length > 0),
Q = computed(() =>
P.value
.filter((e) => !Z(e))
.map((e) =>
configuration_display_t(e.option_name, e.option_type),
),
);
async function $() {
if (D.upgradeAllowed === !1) return;
let t = ++q;
((I.value = !0), (L.value = ``));
try {
let n = await k.get(`/${O.value}/${D.hostId}/upgrade_config`);
if (K || t !== q) return;
P.value = n.host ?? [];
let r = {};
for (let e of P.value)
Z(e) &&
(r[String(e.id)] = M.includes(e.option_type)
? Number(e.qty ?? e.qty_minimum ?? 1)
: Number(e.subid ?? X(e)[0]?.id ?? 0));
((U = !0),
(F.value = r),
await nextTick(),
(U = !1),
(H.value = !1));
} catch (e) {
!K &&
t === q &&
(L.value =
e instanceof Error ? e.message : `加载升降级配置失败`);
} finally {
t === q && (I.value = !1);
}
}
function ye() {
D.upgradeAllowed === !1 ||
U ||
((H.value = !0),
G++,
(J = ``),
(B.value = !1),
clearTimeout(W),
(z.value = ``),
(L.value = ``),
(W = setTimeout(be, 400)));
}
async function be() {
if (
D.upgradeAllowed === !1 ||
!P.value.length ||
!Object.keys(F.value).length
)
return;
for (let e of P.value.filter(Z)) {
let t = F.value[String(e.id)];
if (!(
Number.isFinite(t) &&
(M.includes(e.option_type)
? Number(t) >= Number(e.qty_minimum ?? 0) &&
Number(t) <= Number(e.qty_maximum ?? 1 / 0)
: (e.option_type === 3 && t === 0) ||
X(e).some((e) => e.id === t))
)) {
L.value = `请检查${configuration_display_t(e.option_name, e.option_type)}的配置`;
return;
}
}
let e = ++G,
t = Y.value,
n = {
...F.value,
};
((B.value = !0), (L.value = ``));
try {
let r = await k.post(
`/${O.value}/${D.hostId}/sync_upgrade_config_price`,
{
id: D.hostId,
configoption: n,
},
);
if (K || e !== G || t !== Y.value) return;
if (
r?.price === null ||
r?.price === void 0 ||
String(r.price).trim() === `` ||
!Number.isFinite(Number(r.price))
)
throw Error(`升级报价无效,请重试`);
((z.value = String(r.price)), (J = t));
} catch (n) {
if (K || e !== G || t !== Y.value) return;
((z.value = ``),
(L.value = n instanceof Error ? n.message : `询价失败`));
} finally {
e === G && (B.value = !1);
}
}
async function xe() {
if (
D.upgradeAllowed === !1 ||
!z.value ||
V.value ||
B.value ||
K ||
J !== Y.value
)
return;
let e = Y.value,
t = {
...F.value,
},
n = z.value;
((V.value = !0), (L.value = ``), (A.value = ``), (R.value = ``));
try {
let r = await k.post(`/${O.value}/${D.hostId}/upgrade_config`, {
configoption: t,
buy: !1,
});
if (K || e !== Y.value) return;
if (!/^[1-9]\d*$/.test(String(r.id)))
throw Error(`升级订单无效,请重试`);
((J = ``),
(z.value = ``),
ve(`pay`, {
order_id: r.id,
amount: n,
}));
} catch (e) {
A.value = e instanceof Error ? e.message : `提交失败`;
} finally {
V.value = !1;
}
}
return (
watch(F, ye, {
deep: !0,
flush: `sync`,
}),
watch(
[() => D.hostId, O, () => D.upgradeAllowed],
() => {
(G++,
q++,
clearTimeout(W),
(J = ``),
(z.value = ``),
(P.value = []),
$());
},
{
flush: `sync`,
},
),
onMounted($),
onBeforeUnmount(() => {
((K = !0), G++, q++, clearTimeout(W));
}),
v({
busy: V,
}),
(e, r) => {
let i = OperationNotice,
a = inputnumber,
o = select,
c = button,
u = message;
return h.upgradeAllowed === !1
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, se, [
createVNode(
i,
{
message: unref(A),
severity: `error`,
},
null,
8,
[`message`],
),
unref(I)
? (openBlock(), createElementBlock(`div`, ce, `加载中…`))
: unref(P).length
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createElementVNode(`div`, x, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(P),
(e) => (
openBlock(),
createElementBlock(
`div`,
{
key: e.id,
class: `kv`,
},
[
createElementVNode(
`label`,
{
id: `${unref(j)}-option-${e.id}-label`,
for: Z(e)
? `${unref(j)}-option-${e.id}`
: void 0,
},
toDisplayString(
unref(configuration_display_t)(
e.option_name,
e.option_type,
),
),
9,
S,
),
createElementVNode(`div`, C, [
M.includes(e.option_type)
? (openBlock(),
createBlock(
a,
{
key: 0,
"input-id": `${unref(j)}-option-${e.id}`,
modelValue:
unref(F)[String(e.id)],
"onUpdate:modelValue": (
t,
) =>
(unref(F)[String(e.id)] =
t),
min: Number(
e.qty_minimum ?? 1,
),
max: Number(
e.qty_maximum ?? 99,
),
disabled: unref(V),
showButtons: ``,
buttonLayout: `horizontal`,
suffix: e.unit
? ` ${e.unit}`
: ``,
},
null,
8,
[
`input-id`,
`modelValue`,
`onUpdate:modelValue`,
`min`,
`max`,
`disabled`,
`suffix`,
],
))
: e.option_type === 1 ||
e.option_type === 3
? (openBlock(),
createBlock(
o,
{
key: 1,
"input-id": `${unref(j)}-option-${e.id}`,
"aria-labelledby": `${unref(j)}-option-${e.id}-label`,
modelValue:
unref(F)[String(e.id)],
"onUpdate:modelValue": (
t,
) =>
(unref(F)[
String(e.id)
] = t),
options:
e.option_type === 3
? [
{
id: 0,
option_name: `不启用`,
},
...X(e),
]
: X(e),
disabled: unref(V),
optionLabel: `option_name`,
optionValue: `id`,
},
null,
8,
[
`input-id`,
`aria-labelledby`,
`modelValue`,
`onUpdate:modelValue`,
`options`,
`disabled`,
],
))
: Z(e)
? (openBlock(),
createBlock(
o,
{
key: 2,
"input-id": `${unref(j)}-option-${e.id}`,
"aria-labelledby": `${unref(j)}-option-${e.id}-label`,
modelValue:
unref(F)[
String(e.id)
],
"onUpdate:modelValue": (
t,
) =>
(unref(F)[
String(e.id)
] = t),
options: X(e),
disabled: unref(V),
optionLabel: `option_name`,
optionValue: `id`,
},
null,
8,
[
`input-id`,
`aria-labelledby`,
`modelValue`,
`onUpdate:modelValue`,
`options`,
`disabled`,
],
))
: (openBlock(),
createElementBlock(
`span`,
w,
`该配置项暂不支持在线调整,请联系客服`,
)),
]),
],
)
),
),
128,
)),
createElementVNode(`div`, T, [
(r[1] ||= createElementVNode(
`span`,
null,
`升级费用`,
-1,
)),
createElementVNode(`div`, ue, [
unref(B)
? (openBlock(),
createElementBlock(`b`, de, [
...(r[0] ||= [
createElementVNode(
`i`,
{
class: `pi pi-spin pi-spinner`,
},
null,
-1,
),
]),
]))
: unref(z) === ``
? unref(H)
? (openBlock(),
createElementBlock(`b`, me, `—`))
: (openBlock(),
createElementBlock(
`b`,
pe,
`调整配置后显示`,
))
: (openBlock(),
createElementBlock(
`b`,
fe,
`¥` + toDisplayString(unref(z)),
1,
)),
]),
]),
createElementVNode(`div`, he, [
(r[2] ||= createElementVNode(
`span`,
null,
`操作`,
-1,
)),
createElementVNode(`div`, ge, [
createVNode(
c,
{
label: `提交升级`,
loading: unref(V),
disabled: !unref(z),
onClick: xe,
},
null,
8,
[`loading`, `disabled`],
),
]),
]),
]),
unref(Q).length && unref(P).length
? (openBlock(),
createElementBlock(
`div`,
_e,
` 以下配置项需联系客服调整:` +
toDisplayString(unref(Q).join(`、`)),
1,
))
: createCommentVNode(``, !0),
unref(L)
? (openBlock(),
createBlock(
u,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(L)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
i,
{
message: unref(R),
severity: `success`,
},
null,
8,
[`message`],
),
(r[3] ||= createElementVNode(
`p`,
{
class: `upg-desc`,
},
`提交后生成升级订单,支付完成后生效;费用按剩余周期折算。`,
-1,
)),
],
64,
))
: (openBlock(),
createElementBlock(
`div`,
le,
toDisplayString(
unref(L) || `该实例暂无可调整的配置项`,
),
1,
)),
]));
}
);
},
}),
[[`__scopeId`, `data-v-7efd9d4d`]],
),
{
__name: `RemfUpgrade`,
},
);
export {};
export default E;
</script>
+923
View File
@@ -0,0 +1,923 @@
<script>
import "~/assets/styles/RemoteConsole.DLmX5UZu.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { useId } from "vue";
import { normalizeClass } from "vue";
import { onBeforeUnmount } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { withModifiers } from "vue";
import { loadModule } from "~/utils/load-module.js";
import { useAuth } from "~/lib/auth.js";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import inputtext from "primevue/inputtext";
var T = /^[a-f0-9]{64}$/;
function E(e, n) {
let r = useAuth(),
o = ref(`idle`),
c = ref(``),
l = ref(!0),
u = ref([]),
d = 0,
f = !1,
p = null,
m = null,
h = null,
g = null,
_ = [];
function v() {
(m !== null && clearTimeout(m), (m = null));
}
async function y(e, t) {
if (T.test(e))
try {
await fetch(`/remote-console/sessions/${e}`, {
method: `DELETE`,
headers: {
Authorization: `Bearer ${t}`,
},
credentials: `same-origin`,
cache: `no-store`,
keepalive: !0,
});
} catch {}
}
function S() {
if ((d++, p?.abort(), (p = null), v(), g)) {
for (let [e, t] of _) g.removeEventListener(e, t);
try {
g.disconnect();
} catch {}
g = null;
}
if (((_ = []), (u.value = []), h)) {
let e = h;
((h = null), y(e.id, e.token));
}
}
function C() {
(S(), (c.value = ``), (o.value = `disconnected`));
}
function w(e) {
(S(), (c.value = e), (o.value = `error`));
}
function E(e) {
(v(),
(m = setTimeout(() => {
e === d && !f && w(`连接超时,请重新连接。`);
}, 45e3)));
}
function D(e, t) {
if (t === 401) return `登录已失效,请重新登录后打开控制台。`;
if (t === 403) return `暂时无法访问此实例的控制台,请核对账号后重试。`;
let n = e && typeof e == `object` && `error` in e ? e.error : null;
return typeof n == `string` &&
/^[\u3400-\u9fff\s,。!?、:()…0-9-]{1,100}$/u.test(n)
? n
: `控制台暂时无法连接,请稍后重试。`;
}
async function O() {
if ((S(), (c.value = ``), f || !n.visible() || !e.value)) {
o.value = `idle`;
return;
}
let t = localStorage.getItem(`jwt`);
if (!t || r.token !== t) {
((o.value = `error`), (c.value = `请重新登录后打开控制台。`));
return;
}
let i = String(n.hostId()),
a = n.module(),
s = e.value;
if (!/^\d+$/.test(i) || Number(i) < 1 || !a) {
((o.value = `error`), (c.value = `实例信息尚未就绪,请重新打开控制台。`));
return;
}
let m = d,
x = () =>
m === d &&
!f &&
n.visible() &&
e.value === s &&
String(n.hostId()) === i &&
n.module() === a &&
r.token === t &&
localStorage.getItem(`jwt`) === t;
((o.value = `creating`), (p = new AbortController()));
let C = p.signal;
E(m);
try {
let e = await fetch(`/remote-console/sessions`, {
method: `POST`,
credentials: `same-origin`,
cache: `no-store`,
signal: C,
headers: {
Authorization: `Bearer ${t}`,
"Content-Type": `application/json`,
},
body: JSON.stringify({
hostId: i,
module: a,
...(n.operatePassword()
? {
client_operate_password: n.operatePassword(),
}
: {}),
}),
}),
r = await e.json().catch(() => null),
d =
typeof r?.sessionId == `string` && T.test(r.sessionId)
? r.sessionId
: ``;
if (!x()) {
d && y(d, t);
return;
}
if (!e.ok) {
(d && y(d, t), w(D(r, e.status)));
return;
}
if (
(d &&
(h = {
id: d,
token: t,
}),
!d || r?.websocketPath !== `/remote-console/sessions/${d}/socket`)
) {
w(`控制台连接信息无效,请重新连接。`);
return;
}
let { default: f } = await loadModule(
async () => {
let { default: e } = await import("@novnc/novnc");
return {
default: e,
};
},
[],
import.meta.url,
);
if (!x()) return;
o.value = `connecting`;
let p = new f(
s,
`${window.location.protocol === `https:` ? `wss:` : `ws:`}//${window.location.host}${r.websocketPath}`,
{
...(typeof r.credentials?.password == `string`
? {
credentials: {
password: r.credentials.password,
},
}
: {}),
},
);
((g = p), (p.scaleViewport = l.value), (p.resizeSession = !1));
let m = (e, t) => {
(p.addEventListener(e, t), _.push([e, t]));
};
(m(`connect`, () => {
x() && (v(), (u.value = []), (o.value = `connected`));
}),
m(`disconnect`, () => {
if (!x()) return;
let e = o.value === `connected`;
(S(),
(o.value = e ? `disconnected` : `error`),
(c.value = e ? `` : `连接未能建立,请重新连接。`));
}),
m(`credentialsrequired`, (e) => {
if (!x()) return;
v();
let t = e.detail?.types;
if (
((u.value = Array.isArray(t)
? t.filter((e) => [`username`, `password`, `target`].includes(e))
: [`password`]),
!u.value.length)
) {
w(`此控制台暂不支持当前验证方式,请联系支持。`);
return;
}
o.value = `credentials`;
}),
m(`securityfailure`, () => {
x() && w(`控制台验证失败,请重新连接。`);
}));
} catch {
x() && w(`控制台暂时无法连接,请稍后重试。`);
}
}
function k(e) {
if (!g || o.value !== `credentials` || u.value.some((t) => !e[t]))
return !1;
try {
return (
g.sendCredentials(e),
(o.value = `connecting`),
(u.value = []),
E(d),
!0
);
} catch {
return (w(`控制台验证失败,请重新连接。`), !1);
}
}
function A() {
if (o.value === `connected` && g)
try {
(g.sendCtrlAltDel(), g.focus());
} catch {
w(`连接已中断,请重新连接。`);
}
}
(watch(l, (e) => {
g && (g.scaleViewport = e);
}),
watch(
[n.visible, n.hostId, n.module, e],
() => {
n.visible() && e.value
? O()
: (S(), (o.value = `idle`), (c.value = ``));
},
{
flush: `post`,
immediate: !0,
},
),
watch(
() => r.token,
() => {
(S(), (o.value = `idle`), n.visible() && n.close());
},
{
flush: `sync`,
},
));
function j(e) {
(e.key === `jwt` || e.key === null) &&
n.visible() &&
(S(), (o.value = `idle`), n.close());
}
return (
onMounted(() => window.addEventListener(`storage`, j)),
onBeforeUnmount(() => {
((f = !0), S(), window.removeEventListener(`storage`, j));
}),
{
state: o,
error: c,
fit: l,
credentialTypes: u,
connect: O,
disconnect: C,
submitCredentials: k,
sendCtrlAltDel: A,
}
);
}
var D = [`aria-labelledby`],
O = {
class: `console-header`,
},
k = {
class: `console-heading`,
},
A = [`id`],
j = {
class: `host-id`,
},
M = {
key: 0,
class: `console-target`,
},
ee = {
class: `console-toolbar`,
role: `toolbar`,
"aria-label": `远程控制台操作`,
},
te = {
class: `toolbar-group`,
},
ne = {
class: `toolbar-group`,
},
re = {
key: 0,
class: `toolbar-message`,
role: `status`,
},
ie = [`aria-busy`],
ae = [`aria-label`],
oe = {
key: 0,
class: `console-overlay`,
},
se = [`for`],
ce = [`for`],
N = [`for`],
P = {
key: 3,
class: `credential-error`,
role: `alert`,
},
F = {
key: 1,
class: `connection-message`,
role: `status`,
"aria-live": `polite`,
},
I = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `RemoteConsole`,
props: {
visible: {
type: Boolean,
},
hostId: {},
module: {},
hostName: {},
operatePassword: {},
},
emits: [`update:visible`],
setup(g, { emit: b }) {
let x = g,
C = b,
T = useId(),
I = ref(null),
L = ref(null),
R = ref(!1),
z = ref(``),
B = ref(``),
V = ref(``),
H = ref(``),
U = ref(``),
{
state: W,
error: le,
fit: G,
credentialTypes: K,
connect: q,
disconnect: J,
submitCredentials: ue,
sendCtrlAltDel: de,
} = E(I, {
visible: () => x.visible,
hostId: () => x.hostId,
module: () => x.module,
operatePassword: () => x.operatePassword,
close: () => C(`update:visible`, !1),
}),
Y = computed(
() => W.value === `creating` || W.value === `connecting`,
),
X = computed(
() =>
({
idle: `准备连接`,
creating: `正在建立会话`,
connecting: `正在连接`,
credentials: `等待验证`,
connected: `已连接`,
disconnected: `已断开`,
error: `连接失败`,
})[W.value],
),
Z = computed(() => x.hostName?.trim() || `服务器实例`);
function Q() {
((z.value = ``), (B.value = ``), (V.value = ``), (H.value = ``));
}
watch([W, () => x.visible], Q);
function fe() {
((H.value = ``),
ue({
password: z.value,
username: B.value,
target: V.value,
})
? Q()
: W.value === `credentials` &&
(H.value = `请填写所需的验证信息。`));
}
function pe() {
(J(), Q(), C(`update:visible`, !1));
}
async function me() {
U.value = ``;
try {
document.fullscreenElement === L.value
? await document.exitFullscreen()
: L.value?.requestFullscreen
? await L.value.requestFullscreen()
: (U.value = `当前浏览器不支持全屏,可使用浏览器缩放调整显示。`);
} catch {
U.value = `未能进入全屏,请重试。`;
}
}
function $() {
R.value = !!L.value && document.fullscreenElement === L.value;
}
return (
onMounted(() => document.addEventListener(`fullscreenchange`, $)),
onBeforeUnmount(() =>
document.removeEventListener(`fullscreenchange`, $),
),
(t, n) => {
let i = button,
a = inputtext;
return g.visible
? (openBlock(),
createElementBlock(
`section`,
{
key: 0,
ref_key: `surface`,
ref: L,
class: normalizeClass([
`remote-console`,
{
"is-fullscreen": unref(R),
},
]),
"aria-labelledby": `${unref(T)}-title`,
},
[
createElementVNode(`header`, O, [
(n[7] ||= createElementVNode(
`span`,
{
class: `console-mark`,
"aria-hidden": `true`,
},
[
createElementVNode(`i`, {
class: `pi pi-desktop`,
}),
],
-1,
)),
createElementVNode(`div`, k, [
(n[5] ||= createElementVNode(
`p`,
{
class: `console-brand`,
},
`破碎工坊云`,
-1,
)),
createElementVNode(
`h1`,
{
id: `${unref(T)}-title`,
},
[
(n[4] ||= createTextVNode(`远程控制台`, -1)),
createElementVNode(
`span`,
j,
`#` + toDisplayString(g.hostId),
1,
),
],
8,
A,
),
g.hostName
? (openBlock(),
createElementBlock(
`p`,
M,
toDisplayString(unref(Z)),
1,
))
: createCommentVNode(``, !0),
]),
createElementVNode(
`span`,
{
class: normalizeClass([
`connection-state`,
`state-${unref(W)}`,
]),
role: `status`,
"aria-live": `polite`,
},
[
(n[6] ||= createElementVNode(
`span`,
{
class: `state-dot`,
"aria-hidden": `true`,
},
null,
-1,
)),
createTextVNode(toDisplayString(unref(X)), 1),
],
2,
),
createVNode(i, {
icon: `pi pi-times`,
"aria-label": `关闭远程控制台`,
text: ``,
severity: `secondary`,
rounded: ``,
onClick: pe,
}),
]),
createElementVNode(`div`, ee, [
createElementVNode(`div`, te, [
createVNode(
i,
{
label: `适应窗口`,
icon: `pi pi-expand`,
outlined: !unref(G),
severity: unref(G) ? `primary` : `secondary`,
size: `small`,
"aria-pressed": unref(G),
onClick: (n[0] ||= (e) => (G.value = !unref(G))),
},
null,
8,
[`outlined`, `severity`, `aria-pressed`],
),
createVNode(
i,
{
label: unref(R) ? `退出全屏` : `全屏`,
icon: unref(R)
? `pi pi-window-minimize`
: `pi pi-window-maximize`,
outlined: ``,
severity: `secondary`,
size: `small`,
onClick: me,
},
null,
8,
[`label`, `icon`],
),
createVNode(
i,
{
label: `Ctrl + Alt + Del`,
outlined: ``,
severity: `secondary`,
size: `small`,
disabled: unref(W) !== `connected`,
onClick: unref(de),
},
null,
8,
[`disabled`, `onClick`],
),
]),
createElementVNode(`div`, ne, [
createVNode(
i,
{
label: `重新连接`,
icon: `pi pi-refresh`,
outlined: ``,
severity: `secondary`,
size: `small`,
disabled: unref(Y),
onClick: unref(q),
},
null,
8,
[`disabled`, `onClick`],
),
createVNode(
i,
{
label: `断开`,
icon: `pi pi-power-off`,
text: ``,
severity: `secondary`,
size: `small`,
disabled:
unref(W) === `idle` ||
unref(W) === `disconnected` ||
unref(W) === `error`,
onClick: unref(J),
},
null,
8,
[`disabled`, `onClick`],
),
]),
]),
unref(U)
? (openBlock(),
createElementBlock(
`p`,
re,
toDisplayString(unref(U)),
1,
))
: createCommentVNode(``, !0),
createElementVNode(
`div`,
{
class: `console-display`,
"aria-busy": unref(Y),
},
[
createElementVNode(
`div`,
{
ref_key: `screen`,
ref: I,
class: `console-screen`,
"aria-label": `${unref(Z)} 的远程屏幕`,
},
null,
8,
ae,
),
unref(W) === `connected`
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, oe, [
unref(W) === `credentials`
? (openBlock(),
createElementBlock(
`form`,
{
key: 0,
class: `credential-form`,
onSubmit: withModifiers(fe, [
`prevent`,
]),
},
[
(n[8] ||= createElementVNode(
`i`,
{
class: `pi pi-lock state-icon`,
"aria-hidden": `true`,
},
null,
-1,
)),
(n[9] ||= createElementVNode(
`h3`,
null,
`验证控制台连接`,
-1,
)),
(n[10] ||= createElementVNode(
`p`,
null,
`请输入此控制台要求的连接凭据。`,
-1,
)),
unref(K).includes(`username`)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createElementVNode(
`label`,
{
for: `${unref(T)}-username`,
},
`用户名`,
8,
se,
),
createVNode(
a,
{
id: `${unref(T)}-username`,
modelValue: unref(B),
"onUpdate:modelValue":
(n[1] ||= (e) =>
isRef(B)
? (B.value = e)
: null),
autocomplete: `off`,
fluid: ``,
},
null,
8,
[`id`, `modelValue`],
),
],
64,
))
: createCommentVNode(``, !0),
unref(K).includes(`target`)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`label`,
{
for: `${unref(T)}-target`,
},
`目标`,
8,
ce,
),
createVNode(
a,
{
id: `${unref(T)}-target`,
modelValue: unref(V),
"onUpdate:modelValue":
(n[2] ||= (e) =>
isRef(V)
? (V.value = e)
: null),
autocomplete: `off`,
fluid: ``,
},
null,
8,
[`id`, `modelValue`],
),
],
64,
))
: createCommentVNode(``, !0),
unref(K).includes(`password`)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 2,
},
[
createElementVNode(
`label`,
{
for: `${unref(T)}-password`,
},
`控制台密码`,
8,
N,
),
createVNode(
a,
{
id: `${unref(T)}-password`,
modelValue: unref(z),
"onUpdate:modelValue":
(n[3] ||= (e) =>
isRef(z)
? (z.value = e)
: null),
type: `password`,
autocomplete: `off`,
fluid: ``,
},
null,
8,
[`id`, `modelValue`],
),
],
64,
))
: createCommentVNode(``, !0),
unref(H)
? (openBlock(),
createElementBlock(
`p`,
P,
toDisplayString(unref(H)),
1,
))
: createCommentVNode(``, !0),
createVNode(i, {
type: `submit`,
label: `连接`,
fluid: ``,
}),
],
32,
))
: (openBlock(),
createElementBlock(`div`, F, [
createElementVNode(
`i`,
{
class: normalizeClass([
unref(Y)
? `pi pi-spinner pi-spin`
: unref(W) === `error`
? `pi pi-exclamation-circle`
: `pi pi-desktop`,
`state-icon`,
]),
"aria-hidden": `true`,
},
null,
2,
),
createElementVNode(
`h3`,
null,
toDisplayString(unref(X)),
1,
),
createElementVNode(
`p`,
null,
toDisplayString(
unref(le) ||
(unref(Y)
? `连接启动可能需要一些时间,请稍候。`
: unref(W) === `disconnected`
? `远程会话已结束,实例继续运行。`
: `正在准备您的远程屏幕。`),
),
1,
),
unref(W) === `error` ||
unref(W) === `disconnected`
? (openBlock(),
createBlock(
i,
{
key: 0,
label: `重新连接`,
icon: `pi pi-refresh`,
onClick: unref(q),
},
null,
8,
[`onClick`],
))
: createCommentVNode(``, !0),
])),
])),
],
8,
ie,
),
(n[11] ||= createElementVNode(
`footer`,
{
class: `console-footer`,
},
[
createElementVNode(
`span`,
null,
`点击远程屏幕后使用键盘与鼠标操作。`,
),
createElementVNode(
`span`,
null,
`关闭控制台不会关闭实例`,
),
],
-1,
)),
],
10,
D,
))
: createCommentVNode(``, !0);
}
);
},
}),
[[`__scopeId`, `data-v-e696489e`]],
),
{
__name: `RemoteConsole`,
},
);
export {};
export default I;
</script>