1 parent
e27f08e36e
commit
b788f890f8
5 files changed
+288
-59
No files matched your search
+19
-9
@@ -17,8 +17,14 @@ function e(e, t = {}) {
|
||||
function t(e) {
|
||||
return JSON.parse(JSON.stringify(e));
|
||||
}
|
||||
function n(n) {
|
||||
return n.map((n) => t(e(n)));
|
||||
// 版本只接受服务端对规范购物车生成的 SHA-256,缺失时停止位置写入。
|
||||
function requireCartRevision(cart) {
|
||||
if (
|
||||
typeof cart?.revision !== `string` ||
|
||||
!/^[a-f0-9]{64}$/.test(cart.revision)
|
||||
)
|
||||
throw Error(`购物车版本缺失,请返回购物车刷新后重试`);
|
||||
return cart.revision;
|
||||
}
|
||||
// 递归排序对象键并省略 undefined,使相同内容不受属性插入顺序影响。
|
||||
function r(e) {
|
||||
@@ -76,11 +82,12 @@ async function l(e) {
|
||||
});
|
||||
}
|
||||
/**
|
||||
* n 为 API 客户端,r 包含 position/item;返回函数的第二参 u 检查报价是否仍有效。
|
||||
* 保存前重取购物车并比较原始项,提交 expected_item 供后端进一步检测并发变更。
|
||||
* n 为 API 客户端,r 包含首次读取时绑定的 position/item/revision;第二参 u 检查报价是否仍有效。
|
||||
* 保存始终提交原始版本;冲突必须返回购物车重新确认,不能用新版本授权旧位置。
|
||||
*/
|
||||
function u(n, r) {
|
||||
let a = r ? t(r.item) : null,
|
||||
revision = r ? requireCartRevision(r) : null,
|
||||
c = !1;
|
||||
return async (l, u) => {
|
||||
if (!r || !a) throw Error(`购物车编辑上下文缺失`);
|
||||
@@ -88,13 +95,10 @@ function u(n, r) {
|
||||
c = !0;
|
||||
let d = t(e(a, l));
|
||||
try {
|
||||
let c = (await n.get(`/cart`)).list?.[r.position];
|
||||
if (!c || i(c) !== i(a))
|
||||
throw Error(`购物车商品已变化,请返回购物车刷新后重新编辑`);
|
||||
if (!u()) throw Error(`配置已改变,请重新确认报价后保存`);
|
||||
let l = await n.put(`/cart/${r.position}`, {
|
||||
...d,
|
||||
expected_item: e(a),
|
||||
expected_revision: revision,
|
||||
}),
|
||||
f = a;
|
||||
a = t({
|
||||
@@ -109,9 +113,15 @@ function u(n, r) {
|
||||
(p.fingerprints[r.position] = await s(a)),
|
||||
l
|
||||
);
|
||||
} catch (error) {
|
||||
if ([409, 428].includes(Number(error?.status)))
|
||||
throw Error(`购物车状态已变化,请返回购物车刷新并重新确认配置`, {
|
||||
cause: error,
|
||||
});
|
||||
throw error;
|
||||
} finally {
|
||||
c = !1;
|
||||
}
|
||||
};
|
||||
}
|
||||
export { l as a, c as i, t as n, a as o, u as r, n as t };
|
||||
export { l as a, c as i, t as n, a as o, u as r, requireCartRevision };
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
/**
|
||||
* 购物车:读取服务端购物车、逐项重新报价、保留选择并结算。修改使用 revision 或 expected_cart 进行并发校验,不能把列表下标当作永久商品标识。
|
||||
* 购物车:读取服务端购物车、逐项重新报价、保留选择并结算。位置写入必须携带同次读取的 revision,不能把列表下标当作永久商品标识。
|
||||
*/
|
||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||
import "~/assets/styles/cart.CSS2vTmS.css";
|
||||
@@ -42,7 +42,7 @@ import { t as configuration_display_t } from "~/lib/configuration-display.js";
|
||||
import { t as purchase_limit_state_t } from "~/lib/purchase-limit-state.js";
|
||||
import { a as cart_edit_a } from "~/lib/cart-edit.js";
|
||||
import { i as cart_edit_i } from "~/lib/cart-edit.js";
|
||||
import { t as cart_edit_t } from "~/lib/cart-edit.js";
|
||||
import { requireCartRevision } from "~/lib/cart-edit.js";
|
||||
// 只接受普通对象形状的数据,供配置摘要解析使用。
|
||||
function E(e) {
|
||||
return typeof e == `object` && e && !Array.isArray(e) ? e : void 0;
|
||||
@@ -387,14 +387,7 @@ var me = {
|
||||
G = !1,
|
||||
K = new Map(),
|
||||
q = () => JSON.stringify(D.value),
|
||||
J = () =>
|
||||
O.value
|
||||
? {
|
||||
expected_revision: O.value,
|
||||
}
|
||||
: {
|
||||
expected_cart: cart_edit_t(D.value),
|
||||
},
|
||||
J = () => ({ expected_revision: O.value }),
|
||||
Y = (e) =>
|
||||
JSON.stringify([
|
||||
e.product_id,
|
||||
@@ -524,11 +517,7 @@ var me = {
|
||||
if (G || t !== W) return;
|
||||
if (
|
||||
((D.value = i.list ?? []),
|
||||
(O.value =
|
||||
typeof i.revision == `string` &&
|
||||
/^[a-f0-9]{64}$/.test(i.revision)
|
||||
? i.revision
|
||||
: ``),
|
||||
(O.value = requireCartRevision(i)),
|
||||
(z.value = Object.fromEntries(
|
||||
D.value.flatMap((e, t) => {
|
||||
let n = r.get(Y(e));
|
||||
@@ -563,15 +552,17 @@ var me = {
|
||||
let t = A.value.indexOf(e);
|
||||
t === -1 ? A.value.push(e) : A.value.splice(t, 1);
|
||||
}
|
||||
// 遇到 409 并发冲突时重载购物车并清空选择,要求用户重新确认,避免误改已移动的下标。
|
||||
// 并发冲突或版本缺失时重载列表并清空选择,只在重新确认后允许用户再提交。
|
||||
async function Q(e, t) {
|
||||
let n = e instanceof Error ? e.message : t;
|
||||
e && typeof e == `object` && `status` in e && e.status === 409
|
||||
e && typeof e == `object` && [409, 428].includes(Number(e.status))
|
||||
? (($.value = null),
|
||||
(A.value = []),
|
||||
await Z(),
|
||||
(A.value = []),
|
||||
(M.value = N.value ? `${n};${M.value}` : n))
|
||||
(M.value = N.value
|
||||
? `${n};${M.value}`
|
||||
: `${n};请重新选择商品并确认后再提交`))
|
||||
: (M.value = n);
|
||||
}
|
||||
// 先保存购物车编辑上下文,再进入对应商品页;商品页会再次确认该位置仍匹配商品。
|
||||
|
||||
@@ -50,6 +50,7 @@ import PaymentDialog from "~/components/PaymentDialog.vue";
|
||||
import { t as product_order_module_t } from "~/lib/product-order-module.js";
|
||||
import ConfigLoadingShell from "~/components/config/ConfigLoadingShell.vue";
|
||||
import { n as cart_edit_n } from "~/lib/cart-edit.js";
|
||||
import { requireCartRevision } from "~/lib/cart-edit.js";
|
||||
import CommonConfig from "~/components/config/CommonConfig.vue";
|
||||
import FinanceConfig from "~/components/config/FinanceConfig.vue";
|
||||
import JyCloudConfig from "~/components/config/JyCloudConfig.vue";
|
||||
@@ -119,7 +120,8 @@ var j = {
|
||||
if (K.value !== null && U.value)
|
||||
return {
|
||||
position: K.value,
|
||||
item: U.value,
|
||||
item: U.value.item,
|
||||
revision: U.value.revision,
|
||||
};
|
||||
return undefined;
|
||||
}),
|
||||
@@ -150,11 +152,15 @@ var j = {
|
||||
if (r.order_allowed === !1)
|
||||
throw Error(r.order_block_reason || `该产品已停止订购`);
|
||||
if (K.value !== null) {
|
||||
let t = (await L.get(`/cart`))?.list?.[K.value];
|
||||
if (!t || Number(t.product_id) !== Number(R))
|
||||
let t = await L.get(`/cart`),
|
||||
item = t?.list?.[K.value];
|
||||
if (!item || Number(item.product_id) !== Number(R))
|
||||
throw Error(`购物车商品已变化,请返回购物车重新编辑`);
|
||||
if (e !== Z) return;
|
||||
U.value = cart_edit_n(t);
|
||||
U.value = {
|
||||
item: cart_edit_n(item),
|
||||
revision: requireCartRevision(t),
|
||||
};
|
||||
}
|
||||
let i = await product_order_module_t(L, r);
|
||||
if (e !== Z) return;
|
||||
|
||||
Reference in new issue
Block a user