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

865 lines
31 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/MfCloudVpc.CpOEbuWs.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 { 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 datatable from "primevue/datatable";
import select from "primevue/select";
import column from "primevue/column";
import { c as cloud_instance_management_c } from "~/lib/cloud-instance-management.js";
import { i as cloud_instance_management_i } from "~/lib/cloud-instance-management.js";
var ie = {
class: `vpc-panel network-section`,
},
ae = {
class: `network-head`,
},
T = {
class: `network-actions`,
},
oe = {
key: 0,
class: `muted`,
},
se = {
class: `form`,
},
ce = [`for`],
E = [`for`],
le = {
key: 0,
class: `muted`,
},
ue = {
class: `form`,
},
de = [`for`],
D = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `MfCloudVpc`,
props: {
hostId: {},
productId: {},
module: {},
networkType: {},
dataCenterId: {},
active: {
type: Boolean,
},
},
emits: [`refresh`],
setup(h, { emit: y }) {
let D = h,
O = y,
k = useApi(),
A = useId(),
j = ref(!1),
M = computed(
() =>
cloud_instance_management_i(D.module) &&
(D.networkType === `vpc` || j.value),
),
N = computed(() => `/${D.module}/${D.hostId}/vpc_network`),
P = ref([]),
F = ref([]),
I = ref([]),
L = ref([]),
R = ref(!1),
z = ref(!1),
B = ref(``),
V = ref(``),
H = ref(!1),
U = ref(``),
W = ref(``),
G = ref(null),
K = ref(null),
q = ref(null),
J = ref(!1),
Y = 0,
X = 0,
Z = !1;
async function Q() {
let e = ++Y,
t = N.value;
((B.value = ``), (R.value = !0));
try {
if (
cloud_instance_management_i(D.module) &&
D.networkType !== `vpc` &&
D.productId
) {
let t = await k.get(
`/product/${D.productId}/${D.module}/order_page`,
);
if (Z || e !== Y) return;
if (t.config?.support_vpc_network === void 0)
throw Error(`VPC 能力信息未返回,请重试`);
j.value = Number(t.config.support_vpc_network) === 1;
}
if (!M.value) {
((P.value = []), (F.value = []));
return;
}
let n = [],
r = 1;
for (;;) {
let i = await k.get(t, {
page: r,
limit: 100,
orderby: `id`,
sort: `desc`,
});
if (Z || e !== Y) return;
if (!Array.isArray(i.list)) throw Error(`VPC 列表无效,请重试`);
if (
(n.push(...i.list),
(L.value = i.vpc_cidr_limit ?? []),
i.count === void 0
? i.list.length < 100
: n.length >= Number(i.count))
)
break;
if (!i.list.length) throw Error(`VPC 列表不完整,请刷新重试`);
r++;
}
if (((P.value = n), (F.value = n), D.productId)) {
let t = await k.get(
`/product/${D.productId}/${D.module}/vpc_network/search`,
{
...(D.dataCenterId
? {
data_center_id: D.dataCenterId,
}
: {}),
},
);
if (Z || e !== Y) return;
if (!Array.isArray(t.list))
throw Error(`可用 VPC 网络列表无效,请重试`);
F.value = t.list;
}
} catch (t) {
!Z &&
e === Y &&
(B.value = t instanceof Error ? t.message : `加载 VPC 失败`);
} finally {
!Z && e === Y && (R.value = !1);
}
}
function fe() {
!M.value ||
z.value ||
R.value ||
B.value ||
!D.active ||
((U.value = ``), (W.value = ``), (V.value = ``), (H.value = !0));
}
async function pe() {
if (z.value || !H.value || !M.value || !D.active) return;
let e;
try {
e = cloud_instance_management_c(U.value, W.value, L.value);
} catch (e) {
V.value = e.message;
return;
}
let t = N.value,
n = Y;
((z.value = !0), (V.value = ``));
try {
if ((await k.post(t, e), Z || n !== Y)) return;
((H.value = !1), await Q());
} catch (e) {
!Z &&
t === N.value &&
(V.value = e instanceof Error ? e.message : `创建失败`);
} finally {
!Z && t === N.value && (z.value = !1);
}
}
async function $(e) {
if (
!M.value ||
z.value ||
B.value ||
!D.active ||
!F.value.some((t) => t.id === e.id) ||
((K.value = e),
(q.value = Number(D.hostId)),
(V.value = ``),
(I.value = [
{
id: Number(D.hostId),
name: `当前实例 #${D.hostId}`,
},
]),
D.module !== `mf_cloud`)
)
return;
let t = ++X;
J.value = !0;
try {
let e = [],
n = 1;
for (;;) {
let r = await k.get(`/mf_cloud/vpc_network/host`, {
page: n,
limit: 100,
...(D.dataCenterId
? {
data_center_id: D.dataCenterId,
}
: {}),
});
if (Z || t !== X) return;
if (!Array.isArray(r.list)) throw Error(`可分配实例列表无效`);
if (
(e.push(...r.list),
r.count === void 0
? r.list.length < 100
: e.length >= Number(r.count))
)
break;
if (!r.list.length) throw Error(`可分配实例列表不完整,请重试`);
n++;
}
((I.value = e),
e.some((e) => e.id === q.value) ||
(q.value = e[0]?.id ?? null));
} catch (e) {
!Z &&
t === X &&
((I.value = []),
(V.value =
e instanceof Error ? e.message : `加载可分配实例失败`));
} finally {
!Z && t === X && (J.value = !1);
}
}
async function me() {
let e = K.value,
t = q.value;
if (
!e ||
!t ||
z.value ||
J.value ||
!M.value ||
!D.active ||
!I.value.some((e) => e.id === t) ||
!F.value.some((t) => t.id === e.id)
)
return;
let n = N.value,
r = Y,
i = D.module;
((z.value = !0), (V.value = ``));
try {
if (
(await k.put(`/${i}/${t}/vpc_network`, {
vpc_network_id: e.id,
}),
Z || r !== Y)
)
return;
((K.value = null), await Q(), O(`refresh`));
} catch (e) {
!Z &&
n === N.value &&
(V.value = e instanceof Error ? e.message : `分配网络失败`);
} finally {
!Z && n === N.value && (z.value = !1);
}
}
async function he() {
let e = G.value;
if (
!e ||
z.value ||
!M.value ||
!D.active ||
e.host?.length ||
!P.value.some((t) => t.id === e.id)
)
return;
let t = N.value,
n = Y;
((z.value = !0), (V.value = ``));
try {
if ((await k.del(`${t}/${e.id}`), Z || n !== Y)) return;
((G.value = null), await Q());
} catch (e) {
!Z &&
t === N.value &&
(V.value = e instanceof Error ? e.message : `删除失败`);
} finally {
!Z && t === N.value && (z.value = !1);
}
}
return (
watch(
() => [D.hostId, D.module, D.networkType, D.productId],
() => {
(X++,
(j.value = !1),
(P.value = []),
(z.value = !1),
(H.value = !1),
(G.value = null),
(K.value = null),
Q());
},
),
onMounted(Q),
onBeforeUnmount(() => {
((Z = !0), Y++, X++);
}),
(t, n) => {
let r = button,
i = message,
o = column,
l = datatable,
v = inputtext,
y = dialog,
C = select;
return (
openBlock(),
createElementBlock(`section`, ie, [
createElementVNode(`div`, ae, [
(n[10] ||= createElementVNode(`h4`, null, `VPC 网络`, -1)),
createElementVNode(`div`, T, [
createVNode(
r,
{
label: `新建 VPC`,
icon: `pi pi-plus`,
size: `small`,
disabled:
!unref(M) ||
!h.active ||
unref(z) ||
unref(R) ||
!!unref(B),
onClick: fe,
},
null,
8,
[`disabled`],
),
unref(M)
? (openBlock(),
createBlock(
r,
{
key: 0,
label: `刷新`,
text: ``,
size: `small`,
loading: unref(R),
disabled: unref(z),
onClick: Q,
},
null,
8,
[`loading`, `disabled`],
))
: createCommentVNode(``, !0),
]),
]),
!unref(M) && !unref(R) && !unref(B)
? (openBlock(),
createElementBlock(
`p`,
oe,
`当前实例未开放 VPC 网络能力。`,
))
: createCommentVNode(``, !0),
unref(B)
? (openBlock(),
createBlock(
i,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(B)), 1),
createVNode(r, {
label: `重试`,
text: ``,
size: `small`,
onClick: Q,
}),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
unref(M)
? (openBlock(),
createBlock(
l,
{
key: 2,
class: `network-table`,
value: unref(P),
loading: unref(R),
size: `small`,
scrollable: ``,
},
{
empty: withCtx(() => [
...(n[11] ||= [
createTextVNode(`暂无 VPC 网络`, -1),
]),
]),
default: withCtx(() => [
createVNode(o, {
field: `name`,
header: `名称`,
}),
createVNode(o, {
field: `ips`,
header: `网段`,
}),
createVNode(
o,
{
header: `已分配实例`,
},
{
body: withCtx(({ data: t }) => [
createTextVNode(
toDisplayString(
(t.host || [])
.map((e) => e.name)
.join(`、`) || `未分配`,
),
1,
),
]),
_: 1,
},
),
createVNode(
o,
{
header: `操作`,
},
{
body: withCtx(({ data: e }) => [
createVNode(
r,
{
label: `分配 / 切换`,
text: ``,
size: `small`,
disabled:
unref(z) ||
!h.active ||
!!unref(B) ||
!unref(F).some((t) => t.id === e.id),
onClick: (t) => $(e),
},
null,
8,
[`disabled`, `onClick`],
),
createVNode(
r,
{
label: `删除`,
text: ``,
severity: `danger`,
size: `small`,
disabled:
unref(z) ||
!h.active ||
!!e.host?.length,
onClick: (t) => {
((G.value = e), (V.value = ``));
},
},
null,
8,
[`disabled`, `onClick`],
),
]),
_: 1,
},
),
]),
_: 1,
},
8,
[`value`, `loading`],
))
: createCommentVNode(``, !0),
createVNode(
y,
{
visible: unref(H),
"onUpdate:visible": (n[3] ||= (e) =>
isRef(H) ? (H.value = e) : null),
header: `新建 VPC 网络`,
modal: ``,
closable: !unref(z),
"close-on-escape": !unref(z),
},
{
footer: withCtx(() => [
createVNode(
r,
{
label: `取消`,
text: ``,
severity: `secondary`,
disabled: unref(z),
onClick: (n[2] ||= (e) => (H.value = !1)),
},
null,
8,
[`disabled`],
),
createVNode(
r,
{
label: `创建`,
loading: unref(z),
onClick: pe,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, se, [
createElementVNode(
`label`,
{
for: `${unref(A)}-name`,
},
`名称`,
8,
ce,
),
createVNode(
v,
{
id: `${unref(A)}-name`,
modelValue: unref(U),
"onUpdate:modelValue": (n[0] ||= (e) =>
isRef(U) ? (U.value = e) : null),
disabled: unref(z),
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
createElementVNode(
`label`,
{
for: `${unref(A)}-cidr`,
},
`网段(留空自动分配)`,
8,
E,
),
createVNode(
v,
{
id: `${unref(A)}-cidr`,
modelValue: unref(W),
"onUpdate:modelValue": (n[1] ||= (e) =>
isRef(W) ? (W.value = e) : null),
placeholder: `10.0.0.0/16`,
disabled: unref(z),
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
unref(L).length
? (openBlock(),
createElementBlock(
`p`,
le,
`允许掩码:` +
toDisplayString(unref(L).join(`、`)),
1,
))
: createCommentVNode(``, !0),
unref(V)
? (openBlock(),
createBlock(
i,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(V)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
createVNode(
y,
{
visible: !!unref(K),
header: `分配 / 切换 VPC`,
modal: ``,
closable: !unref(z),
"close-on-escape": !unref(z),
"onUpdate:visible": (n[7] ||= (e) => {
!e && !unref(z) && (K.value = null);
}),
},
{
footer: withCtx(() => [
createVNode(
r,
{
label: `取消`,
text: ``,
severity: `secondary`,
disabled: unref(z),
onClick: (n[6] ||= (e) => (K.value = null)),
},
null,
8,
[`disabled`],
),
createVNode(
r,
{
label: `确认分配`,
loading: unref(z),
disabled: !unref(q) || unref(J) || !unref(I).length,
onClick: me,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
createElementVNode(`div`, ue, [
createElementVNode(
`p`,
null,
`目标网络:` + toDisplayString(unref(K)?.name),
1,
),
createElementVNode(
`label`,
{
for: `${unref(A)}-host`,
},
`实例`,
8,
de,
),
createVNode(
C,
{
"input-id": `${unref(A)}-host`,
modelValue: unref(q),
"onUpdate:modelValue": (n[4] ||= (e) =>
isRef(q) ? (q.value = e) : null),
options: unref(I),
"option-label": `name`,
"option-value": `id`,
loading: unref(J),
disabled: unref(z),
},
null,
8,
[
`input-id`,
`modelValue`,
`options`,
`loading`,
`disabled`,
],
),
createVNode(
i,
{
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
...(n[12] ||= [
createTextVNode(
`切换 VPC 会改变实例内网连接,请确认相关服务已准备好。`,
-1,
),
]),
]),
_: 1,
},
),
unref(V)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(V)),
1,
),
!unref(I).length && unref(K)
? (openBlock(),
createBlock(r, {
key: 0,
label: `重试`,
text: ``,
size: `small`,
onClick: (n[5] ||= (e) =>
$(unref(K))),
}))
: createCommentVNode(``, !0),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
createVNode(
y,
{
visible: !!unref(G),
header: `删除 VPC 网络`,
modal: ``,
closable: !unref(z),
"close-on-escape": !unref(z),
"onUpdate:visible": (n[9] ||= (e) => {
!e && !unref(z) && (G.value = null);
}),
},
{
footer: withCtx(() => [
createVNode(
r,
{
label: `取消`,
text: ``,
severity: `secondary`,
disabled: unref(z),
onClick: (n[8] ||= (e) => (G.value = null)),
},
null,
8,
[`disabled`],
),
createVNode(
r,
{
label: `确认删除`,
severity: `danger`,
loading: unref(z),
onClick: he,
},
null,
8,
[`loading`],
),
]),
default: withCtx(() => [
createElementVNode(
`p`,
null,
`确认删除 ` + toDisplayString(unref(G)?.name) + `?`,
1,
),
unref(V)
? (openBlock(),
createBlock(
i,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(toDisplayString(unref(V)), 1),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `closable`, `close-on-escape`],
),
])
);
}
);
},
}),
[[`__scopeId`, `data-v-1d12fc4b`]],
),
{
__name: `MfCloudVpc`,
},
);
export {};
export default D;
</script>