294 lines
10 KiB
Vue
294 lines
10 KiB
Vue
<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) {
|
|
(j.delete(P(e)), (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 { order } = await E.get(`/order/${i}`);
|
|
if (!n()) return;
|
|
if (!order || String(order.id) !== String(i))
|
|
throw Error(`镜像订单信息无效,请稍后重试`);
|
|
if (order.status === `Cancelled`) {
|
|
j.delete(P(e));
|
|
i = null;
|
|
} else if (order.status === `Paid`)
|
|
// 已付款不等于授权已同步,不能因授权延迟再创建一张收费订单。
|
|
throw Error(`镜像订单已支付,授权尚未生效,请稍后重新检查`);
|
|
else if (order.status !== `Unpaid`)
|
|
throw Error(`当前镜像订单状态不支持支付,请稍后重试`);
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
// 支付回调不等于授权已生效,只有检查接口费用变为 0 才通知调用方继续操作。
|
|
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>
|