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

647 lines
27 KiB
Vue

<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);
}
}
// 初始化配置不触发报价;用户改动后立即废弃旧报价,防抖 400ms 再请求。
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>