Files
console-dev/app/components/instance/InstanceAccess.vue
T

2214 lines
89 KiB
Vue

<script>
/**
* 实例访问控制:展示登录信息并编排重置密码、救援、重装及付费镜像确认。
* info/caps/detail 来自实例详情适配层;refresh 要求父级回读状态,action-consumed 确认消费外部动作。
*/
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/CloudAccessExtras.CnBJlFAZ.css";
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
import "~/assets/styles/InstanceAccess.DIZBrksv.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 { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { reactive } 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 radiobutton from "primevue/radiobutton";
import inputtext from "primevue/inputtext";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import checkbox from "primevue/checkbox";
import OsIcon from "~/components/OsIcon.vue";
import OperationNotice from "~/components/OperationNotice.vue";
import OperatePasswordGate from "~/components/OperatePasswordGate.vue";
import password from "primevue/password";
import skeleton from "primevue/skeleton";
import { t as os_name_t } from "~/lib/os-name.js";
import { t as password_t } from "~/lib/password-2.js";
import CloudAccessExtras from "~/components/instance/CloudAccessExtras.vue";
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 xe = {
class: `ac`,
},
Se = {
class: `block`,
},
Ce = {
class: `info-table`,
},
we = {
class: `kv`,
},
Te = {
class: `kv`,
},
Ee = [`aria-label`],
De = {
class: `kv`,
},
Oe = {
class: `os-opt`,
},
ke = {
class: `kv`,
},
Ae = {
class: `kv`,
},
je = {
class: `password-cell`,
},
Me = {
class: `password-value`,
},
Ne = [`aria-label`, `aria-pressed`],
Pe = {
key: 1,
class: `block`,
},
Fe = {
class: `info-table`,
},
Ie = {
class: `kv`,
},
Le = {
class: `action-cell`,
},
Re = {
key: 2,
class: `block`,
},
ze = {
class: `info-table`,
},
Be = {
key: 0,
class: `kv`,
},
Ve = {
class: `action-cell`,
},
He = {
key: 1,
class: `kv`,
},
Ue = {
class: `action-cell`,
},
We = {
key: 2,
class: `re-loading`,
},
Ge = {
key: 3,
class: `re-form`,
},
Ke = {
class: `form-row`,
},
qe = [`id`],
Je = {
class: `os-opt`,
},
Ye = {
key: 0,
class: `os-opt`,
},
Xe = {
class: `form-row`,
},
Ze = [`id`],
Qe = {
class: `re-login`,
},
$e = {
class: `re-login-options`,
},
et = {
class: `re-choice`,
},
tt = [`for`],
nt = {
class: `re-choice`,
},
rt = [`for`],
it = {
key: 0,
class: `form-row`,
},
at = [`for`],
ot = {
class: `re-password`,
},
st = {
key: 1,
class: `form-row`,
},
ct = [`id`],
lt = {
key: 1,
class: `form-row`,
},
ut = [`for`],
dt = {
class: `form-row`,
},
ft = [`for`],
pt = {
key: 2,
class: `form-row`,
},
mt = {
class: `re-choice`,
},
ht = [`for`],
gt = {
key: 3,
class: `hint`,
},
_t = {
class: `dlg`,
},
vt = {
class: `form-row`,
},
yt = [`for`],
bt = {
class: `form-row`,
},
xt = [`for`],
St = {
class: `confirm-text`,
},
Ct = {
key: 0,
class: `form-list`,
},
wt = {
class: `form-row`,
},
Tt = [`id`],
Et = {
class: `form-row`,
},
Dt = [`for`],
Ot = {
class: `form-row`,
},
kt = [`for`],
At = {
class: `confirm-text`,
},
x = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `InstanceAccess`,
props: {
info: {},
hostId: {},
productId: {},
module: {},
caps: {},
pendingAction: {},
detail: {},
},
emits: [`refresh`, `action-consumed`],
setup(g, { emit: y }) {
let x = g,
S = y,
C = useApi(),
w = useId(),
T = ref(``),
E = ref(``),
jt = ref(``);
function D() {
((T.value = ``), (E.value = ``), (jt.value = ``));
}
function Mt(e) {
((jt.value = e), setTimeout(() => (jt.value = ``), 4e3));
}
function O(e, t) {
E.value = e instanceof Error ? e.message : t;
}
let k = x.detail,
A = ref(``),
j = ref(!1);
async function Nt(e, t) {
if (e)
try {
(await navigator.clipboard.writeText(e),
(A.value = t),
setTimeout(() => (A.value = ``), 1500));
} catch {}
}
let M = ref(!1),
N = ref(!1),
P = reactive({
password: ``,
operate_password: ``,
}),
F = ref(``),
I = ref(``),
Pt = computed(() => x.info.raw.config ?? {}),
Ft = computed(
() => Number(Pt.value.reset_password_sms_verify) === 1,
),
It = computed(() => Number(Pt.value.reinstall_sms_verify) === 1);
function Lt() {
(D(),
(P.password = password_t()),
(P.operate_password = ``),
(F.value = ``),
(M.value = !0));
}
async function Rt() {
// 站点要求短信时必须带当前验证码;“指令已下发”只表示接口接受,不代表密码已即时生效。
if (!N.value) {
if (Ft.value && !F.value.trim()) {
T.value = `请输入账户手机验证码`;
return;
}
if (!P.password) {
T.value = `请输入新密码`;
return;
}
((N.value = !0), D());
try {
(await k.resetPassword(
P.password,
P.operate_password,
F.value.trim(),
),
(M.value = !1),
Mt(`密码重置指令已下发`),
S(`refresh`));
} catch (e) {
O(e, `重置失败`);
} finally {
N.value = !1;
}
}
}
function zt() {
(D(), remote_console_t(x.hostId, x.module));
}
let L = ref(!1),
R = ref(!1),
Bt = computed(() => {
if (x.module !== `remf_finance`) return !0;
let e = k.statusData?.value?.rescue;
return (
typeof e == `boolean` || [`0`, `1`].includes(String(e ?? ``))
);
}),
z = computed(() =>
x.module === `remf_finance`
? k.statusData.value?.rescue === !0 ||
String(k.statusData.value?.rescue ?? ``) === `1`
: String(x.info.raw.rescue ?? ``) === `1` ||
x.info.raw.rescue === !0,
),
B = reactive({
type: 2,
password: ``,
operate_password: ``,
});
function Vt() {
if (!Bt.value) {
T.value = `救援状态尚未加载,请先刷新状态`;
return;
}
let e = /windows/i.test(x.info.image.name || ``);
((B.type = e ? 1 : 2),
(B.password = password_t()),
(B.operate_password = ``),
(R.value = !0));
}
async function Ht(e) {
// 财务模块的救援密码字段和退出路径不同,必须保留模块差异,不能统一拼一个接口。
if (!Bt.value || L.value) return;
let t = q;
((L.value = !0), D());
try {
if (e) {
let e = {
type: B.type,
...($.value
? {
temp_pass: B.password,
}
: {
password: B.password,
}),
client_operate_password: B.operate_password,
client_operate_methods: `rescueSub`,
remember_operate_password: 0,
};
await C.post(`/${x.module}/${x.hostId}/rescue`, e);
} else
await C.post(
`/${x.module}/${x.hostId}/${$.value ? `exit_rescue` : `rescue/exit`}`,
{
id: x.hostId,
client_operate_password: B.operate_password,
client_operate_methods: `reQuitSub`,
remember_operate_password: 0,
},
);
if (J || t !== q) return;
((R.value = !1),
Mt(e ? `已进入救援模式` : `已退出救援模式`),
S(`refresh`));
} catch (n) {
!J &&
t === q &&
O(n, e ? `进入救援模式失败` : `退出救援模式失败`);
} finally {
!J && t === q && (L.value = !1);
}
}
let V = ref([]),
Ut = ref(!1),
Wt = ref([]),
H = ref(!1),
U = ref(!1),
W = ref(!1),
G = ref(null),
K = ref(!1),
Gt = ref(``),
q = 0,
J = !1,
Y = reactive({
osGroupId: null,
image_id: null,
type: `pass`,
password: ``,
ssh_key_id: null,
port: 22,
format_data_disk: !1,
operate_password: ``,
}),
X = computed(
() => V.value.find((e) => e.id === Y.osGroupId) ?? null,
),
Kt = (e) => os_name_t(e.name),
Z = computed(() => /windows/i.test(X.value?.name ?? ``)),
Q = computed(() => x.module === `kky_ecs`),
$ = computed(() => x.module === `remf_finance`);
async function qt() {
// 镜像来源随模块变化:财务模块读取详情内嵌列表,智简模块需要当前节点参数。
if (!x.caps.reinstall || V.value.length) return;
let e = q;
Ut.value = !0;
try {
if ($.value) {
let e = x.info.raw,
t = e.cloud_os_group ?? [],
n = e.cloud_os ?? [];
V.value = t.map((e, t) => ({
id: t + 1,
name: e.name,
icon: ``,
icon_type: 0,
image: n
.filter((t) => t.group === e.id)
.map((e) => ({
id: e.id,
name: e.name,
image_group_id: t + 1,
charge: 0,
price: ``,
is_market: 0,
})),
}));
let r = V.value[0];
if (r) {
((Y.osGroupId = r.id),
(Y.image_id =
r.image?.find((e) => e.name === x.info.image.name)?.id ??
r.image?.[0]?.id ??
null));
let t = e.host_data ?? {};
Y.port =
Number(t.port ?? 0) ||
(/windows/i.test(r.name) ? 3389 : 22);
}
return;
}
let t = x.module === `jy_cloud` || x.module === `jy_dcim`,
n = x.info.raw.node?.id,
r = await C.get(
`/product/${x.productId}/${x.module}/image`,
t && n
? {
node_id: Number(n),
}
: void 0,
);
if (J || e !== q) return;
V.value = r.list ?? [];
let i = Number(x.info.raw.image?.id),
a = (e) => (t && e.id === i) || e.name === x.info.image.name,
o =
(t ? V.value.find((e) => e.image?.some(a)) : void 0) ??
V.value[0];
o &&
((Y.osGroupId = o.id),
(Y.image_id = o.image?.find(a)?.id ?? o.image?.[0]?.id ?? null),
(Y.port =
(t ? x.info.port : null) ||
(/windows/i.test(o.name) ? 3389 : 22)));
} catch (t) {
!J &&
e === q &&
(T.value = t instanceof Error ? t.message : `镜像列表加载失败`);
} finally {
e === q && (Ut.value = !1);
}
}
async function Jt() {
// SSH 密钥需要读取全部分页并去重;服务端分页无进展时报告错误,不能静默截断选项。
if (!x.caps.reinstall || Wt.value.length || K.value) return;
let e = q;
((K.value = !0), (Gt.value = ``));
try {
let t = [];
for (let n = 1; ; n++) {
let r = await C.get(`/ssh_key`, {
page: n,
limit: 100,
orderby: `id`,
sort: `asc`,
});
if (J || e !== q) return;
let i = r.list ?? [],
a = i.filter((e) => !t.some((t) => t.id === e.id));
if (
(t.push(...a),
r.count === void 0
? i.length < 100
: t.length >= Number(r.count))
)
break;
if (!a.length) throw Error(`密钥列表分页未完整返回,请重试`);
}
Wt.value = t;
} catch (t) {
e === q &&
(Gt.value =
t instanceof Error ? t.message : `SSH 密钥加载失败`);
} finally {
e === q && (K.value = !1);
}
}
function Yt() {
((Y.image_id = X.value?.image?.[0]?.id ?? null),
(Y.port = Z.value ? 3389 : 22));
}
function Xt() {
x.caps.reinstall &&
((W.value = !0),
D(),
$.value || ((Y.password = password_t()), Jt()),
(Y.operate_password = ``),
(I.value = ``),
qt());
}
function Zt() {
let e = x.pendingAction;
e && (S(`action-consumed`), e.kind === `rescue` ? Vt() : Xt());
}
watch(() => x.pendingAction?.id, Zt, {
immediate: !0,
});
function Qt() {
// 重装前确认验证码、系统及密码/密钥,再打开二次确认,避免单次点击直接破坏实例数据。
if (It.value && !I.value.trim()) {
T.value = `请输入账户手机验证码`;
return;
}
if (!Y.image_id) {
T.value = `请选择操作系统`;
return;
}
if (!Q.value && !$.value) {
if (Y.type === `pass` && !Y.password) {
T.value = `请输入密码`;
return;
}
if (Y.type === `key` && !Y.ssh_key_id) {
T.value = `请选择 SSH 密钥`;
return;
}
}
U.value = !0;
}
async function $t(e) {
let t = q;
(await C.post(`/${x.module}/${x.hostId}/reinstall`, e),
!(J || t !== q) &&
((U.value = !1),
(W.value = !1),
Mt(`重装指令已下发,请等待实例状态更新`),
S(`refresh`)));
}
async function en() {
// 重装提交绑定实例和镜像快照;支持的模块先检查镜像价格,付费镜像进入购买确认。
// 财务、快快云与其他云模块的重装字段不同,保留既有协议而非按显示文案猜字段。
if (!x.caps.reinstall || H.value || J) return;
if (It.value && !I.value.trim()) {
T.value = `请输入账户手机验证码`;
return;
}
let e = q,
t = Y.image_id,
n = `${x.module}:${x.hostId}`,
r = () =>
!J &&
e === q &&
t === Y.image_id &&
n === `${x.module}:${x.hostId}`;
if (((H.value = !0), D(), $.value)) {
try {
(await C.post(`/remf_finance/${x.hostId}/reinstall`, {
id: x.hostId,
os: Y.image_id,
port: Y.port,
client_operate_password: Y.operate_password,
client_operate_methods: `doReinstall`,
remember_operate_password: 0,
format_data_disk: +!!Y.format_data_disk,
}),
(U.value = !1),
(W.value = !1),
Mt(`重装指令已下发,实例将自动重启`),
S(`refresh`));
} catch (e) {
((U.value = !1), O(e, `重装失败`));
} finally {
H.value = !1;
}
return;
}
let i = {
id: x.hostId,
image_id: Y.image_id,
client_operate_password: Y.operate_password,
client_operate_methods: `doReinstall`,
remember_operate_password: 0,
};
Q.value ||
((i.port = Y.port),
Y.type === `pass`
? (i.password = Y.password)
: (i.ssh_key_id = Y.ssh_key_id),
x.module !== `jy_cloud` &&
x.module !== `jy_dcim` &&
(i.app_preset_id = 0),
(i.code = I.value.trim()),
(i.format_data_disk = +!!Y.format_data_disk));
try {
if (
x.module === `mf_cloud` ||
x.module === `remf_cloud` ||
x.module === `jy_cloud` ||
x.module === `jy_dcim`
) {
let e = await C.get(`/${x.module}/${x.hostId}/image/check`, {
image_id: t,
});
if (!r()) return;
let n = Number(e?.price);
if (
e?.price === void 0 ||
e.price === null ||
String(e.price).trim() === `` ||
!Number.isFinite(n) ||
n < 0
)
throw Error(`镜像费用信息无效,请稍后重试`);
if (n > 0) {
if (x.module === `jy_cloud` || x.module === `jy_dcim`)
throw Error(
`该镜像需要付费,Cloudnova 暂不支持在线购买,请选择免费镜像或提交工单`,
);
((G.value = {
module: x.module,
hostId: x.hostId,
imageId: Number(t),
price: n.toFixed(2),
description: e.description,
}),
(U.value = !1));
return;
}
}
r() && (await $t(i));
} catch (e) {
r() && ((U.value = !1), O(e, `重装失败`));
} finally {
e === q && (H.value = !1);
}
}
return (
onMounted(() => {
x.caps.reinstall && (qt(), $.value || Jt());
}),
watch(
[() => x.hostId, () => x.module, () => x.productId],
() => {
(q++,
(W.value = !1),
(U.value = !1),
(G.value = null),
(V.value = []),
(Wt.value = []),
(K.value = !1),
(H.value = !1),
(R.value = !1),
(L.value = !1),
(B.operate_password = ``),
(Y.operate_password = ``));
},
{
flush: `sync`,
},
),
watch(
() => Y.image_id,
() => {
G.value = null;
},
{
flush: `sync`,
},
),
watch(
W,
(e) => {
e || (G.value = null);
},
{
flush: `sync`,
},
),
onBeforeUnmount(() => {
((J = !0), q++);
}),
(t, n) => {
let i = OperationNotice,
a = message,
s = OsIcon,
u = button,
ee = CloudAccessExtras,
ne = skeleton,
y = select,
be = radiobutton,
x = inputtext,
C = inputnumber,
D = password,
O = OperatePasswordGate,
q = checkbox,
J = InstanceSmsCode,
Z = dialog,
qt = ImagePurchaseDialog;
return (
openBlock(),
createElementBlock(`div`, xe, [
createVNode(
i,
{
message: unref(E),
severity: `error`,
},
null,
8,
[`message`],
),
unref(T)
? (openBlock(),
createBlock(
a,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(T)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
createVNode(
i,
{
message: unref(jt),
severity: `success`,
},
null,
8,
[`message`],
),
createElementVNode(`section`, Se, [
(n[43] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`访问信息`,
-1,
)),
(n[44] ||= createElementVNode(
`p`,
{
class: `block-desc`,
},
`访问信息可以帮助您访问您的服务器。`,
-1,
)),
createElementVNode(`div`, Ce, [
createElementVNode(`div`, we, [
(n[35] ||= createElementVNode(
`span`,
null,
`主 IP 地址`,
-1,
)),
createElementVNode(
`div`,
null,
toDisplayString(g.info.ip || `—`),
1,
),
]),
createElementVNode(`div`, Te, [
(n[37] ||= createElementVNode(
`span`,
null,
`连接端口`,
-1,
)),
createElementVNode(`div`, null, [
createTextVNode(
toDisplayString(g.info.port || `未提供`),
1,
),
g.info.port
? (openBlock(),
createElementBlock(
`button`,
{
key: 0,
type: `button`,
class: normalizeClass([
`act`,
{
ok: unref(A) === `port`,
},
]),
"aria-label":
unref(A) === `port`
? `连接端口已复制`
: `复制连接端口`,
onClick: (n[0] ||= (e) =>
Nt(String(g.info.port), `port`)),
},
[
...(n[36] ||= [
createElementVNode(
`i`,
{
class: `pi pi-copy`,
"aria-hidden": `true`,
},
null,
-1,
),
]),
],
10,
Ee,
))
: createCommentVNode(``, !0),
]),
]),
createElementVNode(`div`, De, [
(n[38] ||= createElementVNode(
`span`,
null,
`操作系统`,
-1,
)),
createElementVNode(`div`, Oe, [
createVNode(
s,
{
url: g.info.image.iconUrl,
name: g.info.image.name,
size: 28,
},
null,
8,
[`url`, `name`],
),
createTextVNode(
toDisplayString(
unref(os_name_t)(g.info.image.name) || `—`,
),
1,
),
]),
]),
createElementVNode(`div`, ke, [
(n[40] ||= createElementVNode(
`span`,
null,
`用户名`,
-1,
)),
createElementVNode(`div`, null, [
createTextVNode(
toDisplayString(g.info.username || `—`),
1,
),
createElementVNode(
`button`,
{
type: `button`,
class: normalizeClass([
`act`,
{
ok: unref(A) === `u`,
},
]),
"aria-label": `复制用户名`,
onClick: (n[1] ||= (e) =>
Nt(g.info.username, `u`)),
},
[
...(n[39] ||= [
createElementVNode(
`i`,
{
class: `pi pi-copy`,
"aria-hidden": `true`,
},
null,
-1,
),
]),
],
2,
),
]),
]),
createElementVNode(`div`, Ae, [
(n[42] ||= createElementVNode(
`span`,
null,
`密码`,
-1,
)),
createElementVNode(`div`, je, [
createElementVNode(`div`, Me, [
createTextVNode(
toDisplayString(
unref(j) ? g.info.password : `••••••••`,
) + ` `,
1,
),
createElementVNode(
`button`,
{
type: `button`,
class: `act`,
"aria-label": unref(j)
? `隐藏密码`
: `显示密码`,
"aria-pressed": unref(j),
onClick: (n[2] ||= (e) =>
(j.value = !unref(j))),
},
[
createElementVNode(
`i`,
{
class: normalizeClass([
`pi`,
unref(j) ? `pi-eye-slash` : `pi-eye`,
]),
"aria-hidden": `true`,
},
null,
2,
),
],
8,
Ne,
),
createElementVNode(
`button`,
{
type: `button`,
class: normalizeClass([
`act`,
{
ok: unref(A) === `p`,
},
]),
"aria-label": `复制密码`,
onClick: (n[3] ||= (e) =>
Nt(g.info.password, `p`)),
},
[
...(n[41] ||= [
createElementVNode(
`i`,
{
class: `pi pi-copy`,
"aria-hidden": `true`,
},
null,
-1,
),
]),
],
2,
),
]),
g.caps.passwordReset
? (openBlock(),
createBlock(u, {
key: 0,
label: `重置密码`,
onClick: Lt,
}))
: createCommentVNode(``, !0),
]),
]),
]),
]),
g.caps.remoteConsole
? (openBlock(),
createElementBlock(`section`, Pe, [
(n[47] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`VNC 连接`,
-1,
)),
createElementVNode(`div`, Fe, [
createElementVNode(`div`, Ie, [
(n[46] ||= createElementVNode(
`span`,
null,
`VNC 连接`,
-1,
)),
createElementVNode(`div`, Le, [
g.caps.remoteConsole
? (openBlock(),
createBlock(u, {
key: 0,
label: `启动 VNC 连接`,
icon: `pi pi-desktop`,
onClick: zt,
}))
: createCommentVNode(``, !0),
(n[45] ||= createElementVNode(
`p`,
{
class: `repair-desc`,
},
`通过 VNC 连接,您仅需使用网页浏览器即可远程控制您的实例,无需安装任何额外软件。`,
-1,
)),
]),
]),
]),
]))
: createCommentVNode(``, !0),
createVNode(
ee,
{
"host-id": g.hostId,
module: g.module,
"image-name": g.info.image.name,
config: unref(Pt),
onRefresh: (n[4] ||= (e) => S(`refresh`)),
},
null,
8,
[`host-id`, `module`, `image-name`, `config`],
),
g.caps.rescue || g.caps.reinstall
? (openBlock(),
createElementBlock(`section`, Re, [
(n[52] ||= createElementVNode(
`h4`,
{
class: `block-title`,
},
`系统修复`,
-1,
)),
(n[53] ||= createElementVNode(
`p`,
{
class: `block-desc`,
},
`系统修复可以帮助您修复系统损坏的问题。`,
-1,
)),
createElementVNode(`div`, ze, [
g.caps.rescue
? (openBlock(),
createElementBlock(`div`, Be, [
(n[49] ||= createElementVNode(
`span`,
null,
`救援模式`,
-1,
)),
createElementVNode(`div`, Ve, [
unref(Bt)
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
u,
{
key: 0,
label: `刷新救援状态`,
size: `small`,
text: ``,
loading: unref(k).statusLoading.value,
onClick: unref(k).loadStatus,
},
null,
8,
[`loading`, `onClick`],
)),
createVNode(
u,
{
label: unref(z)
? `退出救援模式`
: `进入救援模式`,
icon: `pi pi-angle-right`,
"icon-pos": `right`,
loading: unref(L),
disabled: !unref(Bt),
onClick: Vt,
},
null,
8,
[`label`, `loading`, `disabled`],
),
(n[48] ||= createElementVNode(
`p`,
{
class: `repair-desc`,
},
`当您的系统损坏无法启动时,可以进入救援模式。`,
-1,
)),
]),
]))
: createCommentVNode(``, !0),
g.caps.reinstall
? (openBlock(),
createElementBlock(`div`, He, [
(n[51] ||= createElementVNode(
`span`,
null,
`重装系统`,
-1,
)),
createElementVNode(`div`, Ue, [
createVNode(u, {
label: `重装系统`,
icon: `pi pi-angle-right`,
"icon-pos": `right`,
onClick: Xt,
}),
(n[50] ||= createElementVNode(
`p`,
{
class: `repair-desc`,
},
`重装系统会清除系统盘上的所有数据,包括操作系统、已安装的软件和系统设置。`,
-1,
)),
]),
]))
: createCommentVNode(``, !0),
]),
]))
: createCommentVNode(``, !0),
createVNode(
Z,
{
visible: unref(W),
"onUpdate:visible": (n[17] ||= (e) =>
isRef(W) ? (W.value = e) : null),
header: `重装系统`,
modal: ``,
style: {
width: `720px`,
maxWidth: `calc(100vw - 28px)`,
},
draggable: !1,
closable: !1,
"close-on-escape": !unref(H),
pt: {
header: {
style: `padding: 18px`,
},
content: {
style: `padding: 0 18px 18px`,
},
footer: {
style: `padding: 0 18px 18px`,
},
},
},
{
footer: withCtx(() => [
createVNode(
u,
{
label: `取消`,
icon: `pi pi-times`,
severity: `secondary`,
outlined: ``,
disabled: unref(H),
onClick: (n[16] ||= (e) => (W.value = !1)),
},
null,
8,
[`disabled`],
),
createVNode(
u,
{
label: `确认`,
icon: `pi pi-check`,
loading: unref(H),
disabled: unref(Ut),
onClick: Qt,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
unref(T)
? (openBlock(),
createBlock(
a,
{
key: 0,
severity: `error`,
closable: !1,
class: `dialog-error`,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(T)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
(n[58] ||= createElementVNode(
`div`,
{
class: `re-notice`,
},
[
createElementVNode(`h4`, null, `重装系统注意事项`),
createElementVNode(`ol`, null, [
createElementVNode(
`li`,
null,
`重装系统会清除系统盘上的所有数据,包括操作系统、已安装的软件和系统设置。`,
),
createElementVNode(
`li`,
null,
`请提前备份重要数据,并确认所选镜像和数据盘处理方式。`,
),
createElementVNode(
`li`,
null,
`在 Linux 与 Windows 系统之间切换后,数据盘可能无法直接识别或访问。`,
),
]),
],
-1,
)),
g.caps.snapshot
? (openBlock(),
createBlock(
a,
{
key: 1,
severity: `error`,
icon: `pi pi-exclamation-triangle`,
closable: !1,
class: `re-snapshot`,
},
{
default: withCtx(() => [
...(n[54] ||= [
createTextVNode(
`重装可能影响已有快照的可用性,请在操作前确认备份已完成。`,
-1,
),
]),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(Ut)
? (openBlock(),
createElementBlock(`div`, We, [
createVNode(ne, {
height: `120px`,
}),
]))
: (openBlock(),
createElementBlock(`div`, Ge, [
createElementVNode(`div`, Ke, [
createElementVNode(
`span`,
{
id: `${unref(w)}-os-label`,
class: `field-label`,
},
`操作系统`,
8,
qe,
),
createVNode(
y,
{
modelValue: unref(Y).osGroupId,
"onUpdate:modelValue": (n[5] ||= (e) =>
(unref(Y).osGroupId = e)),
"aria-labelledby": `${unref(w)}-os-label`,
options: unref(V),
optionLabel: Kt,
optionValue: `id`,
class: `grow`,
placeholder: `请选择操作系统`,
onChange: Yt,
},
{
option: withCtx(({ option: t }) => [
createElementVNode(`div`, Je, [
createVNode(
s,
{
url: t.icon_url,
name: t.name,
size: 20,
},
null,
8,
[`url`, `name`],
),
createElementVNode(
`span`,
null,
toDisplayString(
unref(os_name_t)(t.name),
),
1,
),
]),
]),
value: withCtx(() => [
unref(X)
? (openBlock(),
createElementBlock(`div`, Ye, [
createVNode(
s,
{
url: unref(X).icon_url,
name: unref(X).name,
size: 20,
},
null,
8,
[`url`, `name`],
),
createElementVNode(
`span`,
null,
toDisplayString(
unref(os_name_t)(unref(X).name),
),
1,
),
]))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`modelValue`, `aria-labelledby`, `options`],
),
]),
createElementVNode(`div`, Xe, [
createElementVNode(
`span`,
{
id: `${unref(w)}-version-label`,
class: `field-label`,
},
`镜像版本`,
8,
Ze,
),
createVNode(
y,
{
modelValue: unref(Y).image_id,
"onUpdate:modelValue": (n[6] ||= (e) =>
(unref(Y).image_id = e)),
"aria-labelledby": `${unref(w)}-version-label`,
options: unref(X)?.image ?? [],
optionLabel: Kt,
optionValue: `id`,
class: `grow`,
placeholder: `请选择镜像版本`,
},
null,
8,
[`modelValue`, `aria-labelledby`, `options`],
),
]),
!unref(Q) && !unref($)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createElementVNode(`fieldset`, Qe, [
(n[55] ||= createElementVNode(
`legend`,
null,
`登录方式`,
-1,
)),
createElementVNode(`div`, $e, [
createElementVNode(`div`, et, [
createVNode(
be,
{
modelValue: unref(Y).type,
"onUpdate:modelValue": (n[7] ||=
(e) => (unref(Y).type = e)),
"input-id": `${unref(w)}-login-pass`,
name: `${unref(w)}-login-type`,
value: `pass`,
},
null,
8,
[
`modelValue`,
`input-id`,
`name`,
],
),
createElementVNode(
`label`,
{
for: `${unref(w)}-login-pass`,
},
`密码`,
8,
tt,
),
]),
createElementVNode(`div`, nt, [
createVNode(
be,
{
modelValue: unref(Y).type,
"onUpdate:modelValue": (n[8] ||=
(e) => (unref(Y).type = e)),
"input-id": `${unref(w)}-login-key`,
name: `${unref(w)}-login-type`,
value: `key`,
},
null,
8,
[
`modelValue`,
`input-id`,
`name`,
],
),
createElementVNode(
`label`,
{
for: `${unref(w)}-login-key`,
},
`SSH 密钥`,
8,
rt,
),
]),
]),
]),
unref(Y).type === `pass`
? (openBlock(),
createElementBlock(`div`, it, [
createElementVNode(
`label`,
{
for: `${unref(w)}-reinstall-password`,
},
`登录密码`,
8,
at,
),
createElementVNode(`div`, ot, [
createVNode(
x,
{
id: `${unref(w)}-reinstall-password`,
modelValue: unref(Y).password,
"onUpdate:modelValue":
(n[9] ||= (e) =>
(unref(Y).password = e)),
class: `grow`,
placeholder: `输入密码`,
},
null,
8,
[`id`, `modelValue`],
),
createVNode(u, {
label: `自动生成密码`,
icon: `pi pi-copy`,
onClick: (n[10] ||= (e) =>
(unref(Y).password = (
`randomPassword` in t
? t.randomPassword
: unref(password_t)
)())),
}),
]),
]))
: (openBlock(),
createElementBlock(`div`, st, [
createElementVNode(
`span`,
{
id: `${unref(w)}-key-label`,
class: `field-label`,
},
`SSH 密钥`,
8,
ct,
),
createVNode(
y,
{
modelValue: unref(Y).ssh_key_id,
"onUpdate:modelValue":
(n[11] ||= (e) =>
(unref(Y).ssh_key_id = e)),
"aria-labelledby": `${unref(w)}-key-label`,
options: unref(Wt),
optionLabel: `name`,
optionValue: `id`,
class: `grow`,
placeholder: `请选择密钥`,
loading: unref(K),
disabled: unref(K),
},
null,
8,
[
`modelValue`,
`aria-labelledby`,
`options`,
`loading`,
`disabled`,
],
),
unref(Gt)
? (openBlock(),
createBlock(
a,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(
unref(Gt),
),
1,
),
createVNode(u, {
label: `重试`,
text: ``,
onClick: Jt,
}),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
])),
],
64,
))
: createCommentVNode(``, !0),
unref(Q)
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, lt, [
createElementVNode(
`label`,
{
for: `${unref(w)}-port`,
},
`SSH/RDP 端口`,
8,
ut,
),
createVNode(
C,
{
modelValue: unref(Y).port,
"onUpdate:modelValue": (n[12] ||= (e) =>
(unref(Y).port = e)),
"input-id": `${unref(w)}-port`,
min: 1,
max: 65535,
"use-grouping": !1,
fluid: ``,
},
null,
8,
[`modelValue`, `input-id`],
),
])),
createVNode(O, null, {
default: withCtx(() => [
createElementVNode(`div`, dt, [
createElementVNode(
`label`,
{
for: `${unref(w)}-reinstall-operate-password`,
},
`操作密码`,
8,
ft,
),
createVNode(
D,
{
modelValue: unref(Y).operate_password,
"onUpdate:modelValue": (n[13] ||= (e) =>
(unref(Y).operate_password = e)),
"input-id": `${unref(w)}-reinstall-operate-password`,
feedback: !1,
toggleMask: ``,
class: `grow`,
placeholder: `账户已设置操作密码时必填`,
},
null,
8,
[`modelValue`, `input-id`],
),
]),
]),
_: 1,
}),
!unref(Q) &&
(!unref($) ||
g.info.raw.reinstall_format_data_disk)
? (openBlock(),
createElementBlock(`div`, pt, [
(n[57] ||= createElementVNode(
`span`,
{
class: `field-label`,
},
`数据盘处理`,
-1,
)),
createElementVNode(`div`, mt, [
createVNode(
q,
{
modelValue: unref(Y).format_data_disk,
"onUpdate:modelValue": (n[14] ||= (
e,
) => (unref(Y).format_data_disk = e)),
binary: ``,
"input-id": `${unref(w)}-format-disk`,
"aria-describedby": `${unref(w)}-format-warning`,
},
null,
8,
[
`modelValue`,
`input-id`,
`aria-describedby`,
],
),
createElementVNode(
`label`,
{
for: `${unref(w)}-format-disk`,
},
`格式化数据盘`,
8,
ht,
),
]),
createVNode(
a,
{
id: `${unref(w)}-format-warning`,
severity: `warn`,
icon: `pi pi-exclamation-triangle`,
closable: !1,
class: `re-format-warning`,
},
{
default: withCtx(() => [
...(n[56] ||= [
createTextVNode(
`警告:格式化数据盘将清除盘上所有数据,请谨慎操作!`,
-1,
),
]),
]),
_: 1,
},
8,
[`id`],
),
]))
: createCommentVNode(``, !0),
unref(Q)
? (openBlock(),
createElementBlock(
`p`,
gt,
`重装后系统将使用镜像默认密码,请重装完成后用上方「重置密码」设置新密码。`,
))
: createCommentVNode(``, !0),
])),
unref(It)
? (openBlock(),
createBlock(
J,
{
key: 4,
modelValue: unref(I),
"onUpdate:modelValue": (n[15] ||= (e) =>
isRef(I) ? (I.value = e) : null),
disabled: unref(H),
},
null,
8,
[`modelValue`, `disabled`],
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `close-on-escape`],
),
createVNode(
qt,
{
modelValue: unref(G),
"onUpdate:modelValue": (n[18] ||= (e) =>
isRef(G) ? (G.value = e) : null),
onAuthorized: (n[19] ||= (e) =>
Mt(`镜像已授权,请再次确认重装`)),
},
null,
8,
[`modelValue`],
),
createVNode(
Z,
{
visible: unref(M),
"onUpdate:visible": (n[25] ||= (e) =>
isRef(M) ? (M.value = e) : null),
header: `重置密码`,
modal: ``,
style: {
width: `560px`,
},
draggable: !1,
},
{
footer: withCtx(() => [
createVNode(u, {
label: `取消`,
severity: `secondary`,
text: ``,
onClick: (n[24] ||= (e) => (M.value = !1)),
}),
createVNode(
u,
{
label: `确定`,
loading: unref(N),
onClick: Rt,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, _t, [
createElementVNode(`div`, vt, [
createElementVNode(
`label`,
{
for: `${unref(w)}-new-password`,
},
`新密码`,
8,
yt,
),
createVNode(
x,
{
id: `${unref(w)}-new-password`,
modelValue: unref(P).password,
"onUpdate:modelValue": (n[20] ||= (e) =>
(unref(P).password = e)),
class: `grow`,
},
null,
8,
[`id`, `modelValue`],
),
createVNode(u, {
label: `随机`,
size: `small`,
severity: `secondary`,
text: ``,
onClick: (n[21] ||= (e) =>
(unref(P).password = (
`randomPassword` in t
? t.randomPassword
: unref(password_t)
)())),
}),
]),
createVNode(O, null, {
default: withCtx(() => [
createElementVNode(`div`, bt, [
createElementVNode(
`label`,
{
for: `${unref(w)}-reset-operate-password`,
},
`操作密码`,
8,
xt,
),
createVNode(
D,
{
modelValue: unref(P).operate_password,
"onUpdate:modelValue": (n[22] ||= (e) =>
(unref(P).operate_password = e)),
"input-id": `${unref(w)}-reset-operate-password`,
feedback: !1,
toggleMask: ``,
class: `grow`,
placeholder: `账户已设置操作密码时必填`,
},
null,
8,
[`modelValue`, `input-id`],
),
]),
]),
_: 1,
}),
(n[59] ||= createElementVNode(
`p`,
{
class: `hint`,
},
`密码需包含大小写字母与数字,长度不少于 6 位。`,
-1,
)),
unref(Ft)
? (openBlock(),
createBlock(
J,
{
key: 0,
modelValue: unref(F),
"onUpdate:modelValue": (n[23] ||= (e) =>
isRef(F) ? (F.value = e) : null),
disabled: unref(N),
},
null,
8,
[`modelValue`, `disabled`],
))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`],
),
createVNode(
Z,
{
visible: unref(R),
header: unref(z) ? `退出救援模式` : `进入救援模式`,
modal: ``,
style: {
width: `560px`,
maxWidth: `94vw`,
},
closable: !unref(L),
"close-on-escape": !unref(L),
draggable: !1,
"onUpdate:visible": (n[32] ||= (e) =>
!unref(L) && (R.value = !1)),
},
{
footer: withCtx(() => [
createVNode(
u,
{
label: `取消`,
severity: `secondary`,
text: ``,
disabled: unref(L),
onClick: (n[30] ||= (e) => (R.value = !1)),
},
null,
8,
[`disabled`],
),
createVNode(
u,
{
label: unref(z) ? `确定退出` : `确定进入`,
loading: unref(L),
disabled: !unref(z) && !unref(B).password,
onClick: (n[31] ||= (e) => Ht(!unref(z))),
},
null,
8,
[`label`, `loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`p`, St, [
unref(z)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`退出救援模式后实例将恢复正常启动流程。`,
),
],
64,
))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createTextVNode(
`进入救援模式后实例将以救援系统启动,可用于修复系统损坏问题。`,
),
],
64,
)),
]),
unref(z)
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, Ct, [
createElementVNode(`div`, wt, [
createElementVNode(
`span`,
{
id: `${unref(w)}-rescue-label`,
class: `field-label`,
},
`救援系统`,
8,
Tt,
),
createVNode(
y,
{
modelValue: unref(B).type,
"onUpdate:modelValue": (n[26] ||= (e) =>
(unref(B).type = e)),
"aria-labelledby": `${unref(w)}-rescue-label`,
options: [
{
label: `Linux`,
value: 2,
},
{
label: `Windows`,
value: 1,
},
],
optionLabel: `label`,
optionValue: `value`,
class: `grow`,
},
null,
8,
[`modelValue`, `aria-labelledby`],
),
]),
createElementVNode(`div`, Et, [
createElementVNode(
`label`,
{
for: `${unref(w)}-rescue-password`,
},
`临时密码`,
8,
Dt,
),
createVNode(
D,
{
modelValue: unref(B).password,
"onUpdate:modelValue": (n[27] ||= (e) =>
(unref(B).password = e)),
"input-id": `${unref(w)}-rescue-password`,
feedback: !1,
toggleMask: ``,
class: `grow`,
placeholder: `救援系统登录密码`,
},
null,
8,
[`modelValue`, `input-id`],
),
createVNode(u, {
label: `随机`,
size: `small`,
severity: `secondary`,
text: ``,
onClick: (n[28] ||= (e) =>
(unref(B).password = (
`randomPassword` in t
? t.randomPassword
: unref(password_t)
)())),
}),
]),
])),
createVNode(O, null, {
default: withCtx(() => [
createElementVNode(`div`, Ot, [
createElementVNode(
`label`,
{
for: `${unref(w)}-rescue-operate-password`,
},
`操作密码`,
8,
kt,
),
createVNode(
D,
{
modelValue: unref(B).operate_password,
"onUpdate:modelValue": (n[29] ||= (e) =>
(unref(B).operate_password = e)),
"input-id": `${unref(w)}-rescue-operate-password`,
feedback: !1,
disabled: unref(L),
toggleMask: ``,
class: `grow`,
placeholder: `账户已设置操作密码时必填`,
},
null,
8,
[`modelValue`, `input-id`, `disabled`],
),
]),
]),
_: 1,
}),
unref(E)
? (openBlock(),
createBlock(
a,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(E)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `header`, `closable`, `close-on-escape`],
),
createVNode(
Z,
{
visible: unref(U),
"onUpdate:visible": (n[34] ||= (e) =>
isRef(U) ? (U.value = e) : null),
header: `确认重装系统`,
modal: ``,
style: {
width: `560px`,
},
draggable: !1,
},
{
footer: withCtx(() => [
createVNode(u, {
label: `取消`,
severity: `secondary`,
text: ``,
onClick: (n[33] ||= (e) => (U.value = !1)),
}),
createVNode(
u,
{
label: `确认重装`,
severity: `danger`,
loading: unref(H),
onClick: en,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(`p`, At, [
(n[60] ||= createTextVNode(` 重装将`, -1)),
(n[61] ||= createElementVNode(
`strong`,
null,
`清空系统盘数据`,
-1,
)),
(n[62] ||= createTextVNode(
`并恢复为所选系统,操作不可撤销。 `,
-1,
)),
unref(Y).format_data_disk
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`已选择同时格式化数据盘,数据盘数据也将丢失。`,
),
],
64,
))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`],
),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-cd28d8b4`]],
),
{
__name: `InstanceAccess`,
},
);
export {};
export default x;
</script>