更新 Scripts/NewAddToCart_Web.js

This commit is contained in:
2026-06-02 19:18:03 +09:00
parent 85266685dd
commit aa70d1c9c6

View File

@@ -72,6 +72,131 @@ const HEADERS = {
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1"
};
const normId = v => String(v ?? "").trim().toUpperCase();
const arr = v => Array.isArray(v) ? v : [];
function parseJsonBody(raw) {
if (raw && typeof raw === "object") return { ok: true, value: raw };
try {
return { ok: true, value: JSON.parse(String(raw || "{}")) };
} catch (e) {
return { ok: false, error: String(e) };
}
}
function getStatusCode(response) {
return Number(response && (response.status || response.statusCode)) || 0;
}
function collectLineItems(cart) {
const out = [];
const addItems = items => {
for (const item of arr(items)) {
if (item && typeof item === "object") out.push(item);
}
};
addItems(cart && cart.lineItems);
addItems(cart && cart.bundleLineItems);
for (const bundle of arr(cart && cart.bundleLineItems)) {
addItems(bundle && bundle.lineItems);
addItems(bundle && bundle.items);
}
return out;
}
function collectBusinessErrors(payload) {
const events = payload && payload.events;
if (!events || typeof events !== "object") return [];
const found = [];
const visit = (section, value) => {
if (Array.isArray(value)) {
for (const event of value) visit(section, event);
return;
}
if (!value || typeof value !== "object") return;
const data = value.data || {};
const status = Number(data.httpStatusCode || value.httpStatusCode || 0);
const type = String(value.type || value.severity || "").toLowerCase();
if (type === "error" || status >= 400) {
found.push({ section, event: value });
return;
}
for (const key of Object.keys(value)) {
if (Array.isArray(value[key])) visit(`${section}.${key}`, value[key]);
}
};
for (const key of Object.keys(events)) visit(key, events[key]);
return found;
}
function formatBusinessError(item) {
const event = item.event || {};
const data = event.data || {};
const parts = [];
if (item.section) parts.push(item.section);
if (event.provider) parts.push(`provider=${event.provider}`);
if (event.code) parts.push(`code=${event.code}`);
if (data.reason) parts.push(`reason=${data.reason}`);
if (Array.isArray(data.subReasons) && data.subReasons.length) {
parts.push(`sub=${data.subReasons.filter(Boolean).join(" / ")}`);
}
if (data.httpStatusCode) parts.push(`http=${data.httpStatusCode}`);
return parts.join(", ") || "unknown business error";
}
function validateAddResult(rawBody, target) {
const parsed = parseJsonBody(rawBody);
if (!parsed.ok) {
return { ok: false, reason: `响应不是合法 JSON: ${parsed.error}` };
}
const payload = parsed.value || {};
const cart = payload.cart || {};
const market = cart.market ? String(cart.market).toUpperCase() : "";
const language = cart.language ? String(cart.language).toLowerCase() : "";
const contextProblems = [];
if (market && market !== MARKET) contextProblems.push(`market=${cart.market}`);
if (language && language !== LOCALE.toLowerCase()) contextProblems.push(`language=${cart.language}`);
const errors = collectBusinessErrors(payload);
const lineItems = collectLineItems(cart);
const matchedLine = lineItems.find(item =>
normId(item.productId) === normId(target.productId) &&
normId(item.skuId) === normId(target.skuId) &&
normId(item.availabilityId) === normId(target.availabilityId)
);
if (errors.length > 0) {
const detail = errors.map(formatBusinessError).join(" | ");
const context = contextProblems.length ? ` | context: ${contextProblems.join(", ")}` : "";
return { ok: false, reason: `${detail}${context} | lineItems=${lineItems.length}` };
}
if (contextProblems.length > 0) {
return { ok: false, reason: `购物车上下文不匹配: ${contextProblems.join(", ")} | lineItems=${lineItems.length}` };
}
if (!matchedLine) {
return {
ok: false,
reason: `HTTP 200 但未在 cart.lineItems 找到目标商品 | lineItems=${lineItems.length} | cartId=${cart.id || ""}`
};
}
const title = matchedLine.title ? ` | ${matchedLine.title}` : "";
const qty = matchedLine.quantity ? ` | qty=${matchedLine.quantity}` : "";
const amount = matchedLine.totalAmount ? ` | amount=${matchedLine.totalAmount}` : "";
return { ok: true, detail: `${cart.language || ""}/${cart.market || ""}${title}${qty}${amount}` };
}
function finalizeAndClean() {
const successCount = results.success.length;
const failureCount = results.failure.length;
@@ -221,20 +346,27 @@ function sendRequest() {
itemsToAdd: { items: [{ productId, skuId, availabilityId, campaignId: "xboxcomct", quantity: 1 }] }
};
$httpClient.put({ url: API_URL, headers: HEADERS, body: JSON.stringify(bodyObj) }, (error, response) => {
$httpClient.put({ url: API_URL, headers: HEADERS, body: JSON.stringify(bodyObj) }, (error, response, data) => {
const idStr = `${productId}`;
// 显示标签(序号+游戏名)和现价,取不到时回退到 bigId
const priceNGN = (_remoteGroupRaw && key && _remoteGroupRaw[key]?.PriceNGN)
? ` | NGN ${Number(_remoteGroupRaw[key].PriceNGN).toFixed(2)}`
: '';
const displayLabel = key ? `${key}${priceNGN}` : idStr;
if (error || response.status !== 200) {
const statusCode = getStatusCode(response);
if (error || statusCode !== 200) {
results.failure.push(idStr);
log("error", "失败", displayLabel);
log("error", "失败", `${displayLabel} | HTTP ${statusCode || "ERR"} ${error ? String(error) : ""}`);
} else {
results.success.push(idStr);
if (key) successKeys.push(key);
log("success", "成功", displayLabel);
const verdict = validateAddResult(data != null ? data : (response && response.body), { productId, skuId, availabilityId });
if (verdict.ok) {
results.success.push(idStr);
if (key) successKeys.push(key);
log("success", "成功", `${displayLabel}${verdict.detail ? " | " + verdict.detail : ""}`);
} else {
results.failure.push(idStr);
log("error", "失败", `${displayLabel} | ${verdict.reason}`);
}
}
currentIndex++;
setTimeout(sendRequest, 50);
@@ -280,4 +412,4 @@ $httpClient.get(REMOTE_READ_URL, (error, response, data) => {
}
startTask();
}
});
});