修复镜像订单重试与级联配置可见性一致性

This commit is contained in:
cieanyau committed 2026-11-06 01:44:02 +08:00
1 parent 4bc84717ff
commit 695bc9192f
3 files changed
+497 -47

No files matched your search

+50 -45
View File
@@ -59,6 +59,33 @@ var ce = {
"24:month": `biennially`,
"36:month": `triennially`,
};
// 默认值、购物车回填和界面共用可见叶子集合;隐藏祖先会隐藏整个子树。
// 保留后端遍历顺序供默认值使用,显示排序仅由界面处理。
function cascadeItems(option) {
const items = [];
function visit(nodes, path) {
for (const node of nodes) {
if (!node || typeof node !== `object` || Array.isArray(node)) continue;
if (Number(node.hidden) === 1) continue;
const name = String(node.item_name ?? ``).trim();
const labels = name ? [...path, name] : path;
const children = Array.isArray(node.children) ? node.children : [];
const id = Number(node.item_id);
if (
(Number(node.is_leaf) === 1 || children.length === 0) &&
Number.isInteger(id) &&
id > 0
)
items.push({ item_id: id, label: labels.join(` / `) || `选项 ${id}` });
else if (children.length) visit(children, labels);
}
}
visit(option.tree ?? [], []);
return items.filter(
(item, index) =>
items.findIndex((other) => other.item_id === item.item_id) === index,
);
}
function R(e, t = {}) {
// 业务状态按普通配置 u、级联 d、重复数量 p 分开存储,再按现有后端契约组装。
let n = useApi(),
@@ -218,7 +245,7 @@ function R(e, t = {}) {
(p.value[String(n.id)] = [Number(e ?? n.qty_min ?? 1)]),
n.option_type === `cascade`)
) {
let e = fe(n)[0];
let e = cascadeItems(n)[0];
e &&
(d.value[String(n.id)] = {
item_id: e.item_id,
@@ -268,15 +295,11 @@ function R(e, t = {}) {
e.id
);
});
function fe(e) {
let t = (e) => e.flatMap((e) => (e.children?.length ? t(e.children) : [e]));
return t(e.tree ?? []).filter((e) => Number(e.hidden) !== 1);
}
function pe(e, t, n = 1) {
let r = l.value?.configoptions.find((t) => t.id === e);
r &&
r.option_type === `cascade` &&
fe(r).some((e) => e.item_id === t) &&
cascadeItems(r).some((e) => e.item_id === t) &&
((d.value[String(e)] = {
item_id: t,
quantity: Math.max(1, Number(n) || 1),
@@ -373,17 +396,25 @@ function R(e, t = {}) {
let n = t,
r = Number(n.item_id),
i = Number(n.quantity ?? 1);
return Number.isFinite(r)
? [
[
e,
{
item_id: r,
quantity: Math.max(1, Number.isFinite(i) ? i : 1),
},
],
]
: [];
const option = l.value?.configoptions.find(
(option) => String(option.id) === e,
);
// 已保存的级联项不可静默替换成另一资源,也不能继续提交已隐藏的节点。
if (
!option ||
option.option_type !== `cascade` ||
!cascadeItems(option).some((item) => item.item_id === r)
)
throw Error(`商品级联配置已调整,请返回购物车删除该项后重新配置`);
return [
[
e,
{
item_id: r,
quantity: Math.max(1, Number.isFinite(i) ? i : 1),
},
],
];
}),
));
let i = t.repeat_configoption;
@@ -773,34 +804,8 @@ var le = {
? configuration_display_r(t)
: t;
function Z(e) {
let t = [],
n = (e, r) => {
for (let i of e) {
if (!i || typeof i != `object` || Array.isArray(i)) continue;
let e = i;
if (Number(e.hidden) === 1) continue;
let a = String(e.item_name ?? ``).trim(),
o = a ? [...r, a] : r,
s = Array.isArray(e.children) ? e.children : [],
c = Number(e.item_id);
(Number(e.is_leaf) === 1 || s.length === 0) &&
Number.isInteger(c) &&
c > 0
? t.push({
item_id: c,
label: o.join(` / `) || `选项 ${c}`,
})
: s.length && n(s, o);
}
};
return (
n(e.tree ?? [], []),
t
.sort((e, t) => e.label.localeCompare(t.label, `zh-Hans-CN`))
.filter(
(e, t, n) =>
n.findIndex((t) => t.item_id === e.item_id) === t,
)
return cascadeItems(e).sort((e, t) =>
e.label.localeCompare(t.label, `zh-Hans-CN`),
);
}
function Re(e) {
@@ -1,5 +1,5 @@
<script>
// 付费镜像授权弹窗:复查实时价格、复用本组件已建订单,并在支付后重新检查授权。
// 付费镜像授权弹窗:复查实时价格和已建订单状态,并在支付后重新检查授权。
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
import { toDisplayString } from "vue";
import { onBeforeUnmount } from "vue";
@@ -73,7 +73,7 @@ var C = {
if (!n()) return;
let r = F(t.price);
if (Number(r) === 0) {
((w.value = null), T(`authorized`));
(j.delete(P(e)), (w.value = null), T(`authorized`));
return;
}
if (r !== F(e.price)) {
@@ -85,6 +85,21 @@ var C = {
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,