Files
console-dev/app/components/instance/DcimActions.vue
T
2026-11-06 00:04:38 +08:00

839 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>