diff --git a/Scripts/NewAddToCart_Web.js b/Scripts/NewAddToCart_Web.js
index ab55921..04daed2 100644
--- a/Scripts/NewAddToCart_Web.js
+++ b/Scripts/NewAddToCart_Web.js
@@ -30,19 +30,20 @@ let currentIndex = 0;
let productList = [];
let sourceLabel = "";
let useRemote = false;
+let _remoteGroupRaw = null; // 保留原始远程数据,用于构建 failedProducts
function log(type, message, detail = "") {
const icon = type === "success" ? "✅" : (type === "error" ? "❌" : "ℹ️");
- const color = type === "success" ? "#52b043" : (type === "error" ? "#e05050" : "#777");
+ const color = type === "success" ? "green" : (type === "error" ? "red" : "#666");
console.log(`${icon} ${message} ${detail}`);
- logBuffer.push(`
${icon} ${message} ${detail}`);
+ logBuffer.push(`${icon} ${message} ${detail}
`);
}
const generateRiskSessionId = () =>
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c =>
(c === "x" ? (Math.random() * 16 | 0) : ((Math.random() * 4 | 8) | 0)).toString(16));
-const toNum = k => { const m = /^product(\d+)$/.exec(k); return m ? parseInt(m[1], 10) : Number.MAX_SAFE_INTEGER; };
+const toNum = k => { const m = /^product(\d+)$/.exec(k) || /^\((\d+)\)/.exec(k); return m ? parseInt(m[1], 10) : Number.MAX_SAFE_INTEGER; };
const normEntry = v => {
if (!v || typeof v !== "object") return null;
const productId = String(v.ProductId ?? v.productId ?? "").trim();
@@ -55,7 +56,7 @@ const normEntry = v => {
function parseProductList(raw) {
let parsed; try { parsed = JSON.parse(raw || "{}"); } catch { parsed = {}; }
return Object.keys(parsed)
- .filter(k => /^product\d+$/.test(k))
+ .filter(k => normEntry(parsed[k]) !== null) // 接受任意 key,只要 value 有效
.sort((a, b) => toNum(a) - toNum(b))
.map(k => { const norm = normEntry(parsed[k]); return norm ? { key: k, ...norm } : null; })
.filter(Boolean);
@@ -82,10 +83,10 @@ function finalizeAndClean() {
: `成功: ${successCount} / 失败: ${failureCount}${priceNote}`;
const failedHtml = failedNames.length > 0
- ? `加购失败的游戏:${failedNames.map(n => `- ${n}
`).join('')}
`
+ ? `加购失败的游戏:${failedNames.map(n => `- ${n}
`).join('')}
`
: '';
const priceHtml = ngnStr
- ? `游戏总价 ${ngnStr}
`
+ ? `游戏总价: ${ngnStr}
`
: '';
$notification.post(
@@ -93,58 +94,18 @@ function finalizeAndClean() {
notifSubtitle,
`来源: ${sourceLabel}`
);
- const html = `
-
-
-
-
-Xbox Cart · 尼区
-
-
-
-
-
-
-
-
${successCount + failureCount}
合计
-
-${priceHtml}${failedHtml}
-来源: ${sourceLabel}
-
-
-`;
+ const html = `Xbox Cart执行结果: 成功 ${successCount} / 失败 ${failureCount} | 来源: ${sourceLabel}
${priceHtml}${failedHtml}${logBuffer.join("")}
`;
$done({ response: { status: 200, headers: { "Content-Type": "text/html;charset=utf-8", "Cache-Control": "no-store, no-cache, must-revalidate", "Pragma": "no-cache" }, body: html } });
};
if (useRemote) {
- // 构建失败的 product 对象(重新编号 product1, product2...)
+ // 构建失败的 product 对象:优先从原始远程数据取(保留 PriceNGN 等完整字段)
const failedProducts = {};
- let fi = 1;
for (const item of productList) {
if (results.failure.includes(item.productId)) {
- failedProducts[`product${fi++}`] = {
+ // 从原始数据里找到对应的完整 product(含 PriceNGN)
+ const originalProduct = _remoteGroupRaw ? _remoteGroupRaw[item.key] : null;
+ failedProducts[item.key] = originalProduct || {
ProductId: item.productId,
SkuId: item.skuId,
AvailabilityId: item.availabilityId
@@ -267,6 +228,8 @@ $httpClient.get(REMOTE_READ_URL, (error, response, data) => {
sourceLabel = `远程第 ${groupIndex} 组`;
log("info", "使用远程待同步 Product", `第 ${groupIndex} 组,共 ${Object.keys(remoteGroup).length} 个`);
productList = parseProductList(JSON.stringify(remoteGroup));
+ // ★ 保留原始数据,供构建 failedProducts 时还原完整字段(含 PriceNGN)
+ _remoteGroupRaw = remoteGroup;
startTask();
} else {
useRemote = false;