修复商品库存与网络摘要并校验订购编号

This commit is contained in:
cieanyau committed 2026-11-06 04:48:38 +08:00
1 parent 28894e0813
commit d8224ec5b7
15 files changed
+529 -68

No files matched your search

+3 -2
View File
@@ -1,8 +1,9 @@
/** 优先使用商品已有描述;缺失时按商品 id 补查,最多等待 5 秒,失败不阻塞配置页。 */
import { productId } from "~/lib/product-id.js";
async function e(e, t) {
if (typeof t.description == `string`) return t.description;
let n = Number(t.id);
if (!Number.isSafeInteger(n) || n <= 0) return ``;
let n = productId(t.id);
if (n === null) return ``;
try {
let t = await e.get(
`/product`,
+8
View File
@@ -0,0 +1,8 @@
/** 商品接口使用有符号 32 位正整数;在拼接后端路径之前拒绝数组、精度丢失和超限编号。 */
export function productId(value) {
if (typeof value !== "string" && typeof value !== "number") return null;
const text = String(value);
if (!/^[1-9]\d{0,9}$/.test(text)) return null;
const id = Number(text);
return id <= 2147483647 ? id : null;
}
+14
View File
@@ -0,0 +1,14 @@
/** 只有已开启控制且数量有效的库存才约束购买;null 表示没有可展示的确定数量,不代表无限库存。 */
export function productStock(product, model) {
const quantities = [
[product?.stock_control, product?.qty],
[model?.auto_sync_dcim_stock, model?.qty],
]
.filter(
([enabled, quantity]) =>
Number(enabled) === 1 && quantity != null && quantity !== "",
)
.map(([, quantity]) => Number(quantity))
.filter((quantity) => Number.isFinite(quantity) && quantity >= 0);
return quantities.length ? Math.min(...quantities) : null;
}
+2
View File
@@ -1,4 +1,5 @@
/** 下单前确认真实配置模块;本地 DCIM 与转售 DCIM 使用不同配置组件,不能仅看商品名。 */
import { productId } from "~/lib/product-id.js";
function e(e) {
let t = typeof e.module == `string` ? e.module.trim() : ``,
n = typeof e.res_module == `string` ? e.res_module.trim() : ``;
@@ -7,6 +8,7 @@ function e(e) {
}
// 已知非 mf_cloud 模块可直接使用;缺失/含糊时读取配置接口,取不到模块就明确失败。
async function t(t, n) {
if (productId(n.id) === null) throw Error(`商品编号无效`);
let r = typeof n.module == `string` ? n.module.trim() : ``,
i = e(n);
if (i) return i;
+11
View File
@@ -0,0 +1,11 @@
/** radio 的 value 是可选值;step/total 的 value 可能只是占位,默认值应从区间下限读取。 */
export function resourceOptionValue(option) {
if (!option) return;
const value =
option.type === "step" || option.type === "total"
? (option.min_value ?? option.value)
: option.value;
if (value == null || value === "") return;
const number = Number(value);
return Number.isFinite(number) ? number : undefined;
}