feat: remove shop feature (Phase 2)

Delete all shop domain classes, controllers, schema builders, templates,
JS/CSS, admin SPA pages, and shop-only payment classes (Shipping,
AfterSale, Discount). Remove shop-only DB table definitions (product_variant,
after_sale, order_shipping, card_key) from migrator and add their DROP
to uninstall.php. Clean up shared files:

- Remove aksrt_product CPT + taxonomies from Setup.php
- Remove shop rewrite rules/query vars/template redirect from SetupPart2.php
- Remove shop widget areas from SetupPart1.php
- Remove shop enqueues from ScriptsPart1b.php
- Remove sepakerator-aksrt-shop from SetupPart2.php
- Remove get_shop_settings facade (delete ForumShop.php, clean DomainGroups.php)
- Remove ORDER_PRODUCT_SHOP constant from DomainModel.php
- Remove Shop::class fallback branches from UserOrders.php, OrderCenterRest.php
- Remove shipping/after-sale branches from OrderRepositoryAdmin.php, PayMenus.php, PayOrders.php
- Remove shop product widgets from widgets-register.php
- Remove cart page from template-registry.php, routing.php, ScriptsPart2.php
- Remove cart UI from sidebar-nav.php, profile-orders.php, sidebar-orders.php
- Clean up order-center.js (remove rebuy/cartUrl/receipt/after-sale handlers)
- Remove aksrt_get_cart_page_url/product_page/product_edit from transactions.php
- Clean up aksrt_product_cat references in Coupon.php, PayCoupons.php

Shared payment/order/credits/content-pay stack fully retained.
This commit is contained in:
kate522 committed 2026-08-02 21:25:52 +08:00
1 parent 2bbd7c01a3
commit 1d2505356e
103 files changed
+46 -21267

No files matched your search

-483
View File
@@ -1,483 +0,0 @@
(function () {
"use strict";
var page = document.querySelector("[data-aksrt-cart-page]");
if (!page || !window.aksrtData) {
return;
}
function restBase() {
return ((aksrtData.siteUrl || "").replace(/\/$/, "")) + "/wp-json/aksrt/v1";
}
function rest(path, method, body) {
var opts = {
method: method || "GET",
credentials: "same-origin",
headers: { "X-WP-Nonce": aksrtData.restNonce || "" }
};
if (body !== undefined) {
opts.headers["Content-Type"] = "application/json";
opts.body = JSON.stringify(body);
}
return fetch(restBase() + path, opts).then(function (r) { return r.json(); });
}
function ordersUrl() {
return aksrtData.ordersUrl || (aksrtData.routes && aksrtData.routes.orders) || "/";
}
function shopHomeUrl() {
return (aksrtData.routes && aksrtData.routes.home) || aksrtData.siteUrl || "/";
}
var cartItems = [];
var currencySymbol = page.getAttribute("data-currency-symbol") || "¥";
var itemsEl = page.querySelector("[data-aksrt-cart-items]");
var subtotalEl = page.querySelector("[data-aksrt-summary-subtotal]");
var shippingEl = page.querySelector("[data-aksrt-summary-shipping]");
var discountEl = page.querySelector("[data-aksrt-summary-discount]");
var totalEl = page.querySelector("[data-aksrt-summary-total]");
var previewMessageEl = page.querySelector("[data-aksrt-preview-message]");
var createBtn = page.querySelector("[data-aksrt-create-order]");
var previewBtn = page.querySelector("[data-aksrt-preview-checkout]");
var previewState = null;
var searchParams = new URLSearchParams(window.location.search);
function getCart() { return cartItems; }
function setCart(items) { cartItems = Array.isArray(items) ? items : []; }
function money(value) {
return currencySymbol + Number(value || 0).toFixed(2);
}
function selectedValue(name) {
var checked = page.querySelector('input[name="' + name + '"]:checked');
return checked ? checked.value : "";
}
function getPayload() {
var items = getCart().map(function (item) {
return {
product_id: Number(item.product_id || item.id || 0),
quantity: Number(item.qty || item.quantity || 1),
options_string: item.options_string || ""
};
}).filter(function (item) {
return item.product_id > 0;
});
return {
items: items,
coupon_code: (page.querySelector("[data-aksrt-coupon-code]") || {}).value || "",
shipping_method: selectedValue("aksrt_cart_shipping"),
address_id: Number(selectedValue("aksrt_cart_address") || 0),
payment_method: selectedValue("aksrt_cart_payment"),
customer_note: (page.querySelector("[data-aksrt-customer-note]") || {}).value || ""
};
}
function renderCart() {
var items = getCart();
if (!items.length) {
itemsEl.innerHTML = '' +
'<div class="aksrt-cart-page__empty">' +
'<i class="fas fa-shopping-cart" aria-hidden="true"></i>' +
"<p>购物车为空,去商品页添加想购买的内容。</p>" +
'<a href="' + shopHomeUrl() + '" class="btn-outline btn-sm">继续浏览</a>' +
"</div>";
subtotalEl.textContent = money(0);
shippingEl.textContent = money(0);
discountEl.textContent = "-" + money(0);
totalEl.textContent = money(0);
createBtn.disabled = true;
previewState = null;
return;
}
var total = 0;
var html = "";
items.forEach(function (item, index) {
var qty = Number(item.qty || item.quantity || 1);
var price = Number(item.unit_price != null ? item.unit_price : (item.price != null ? item.price : (item.product && item.product.price) || 0));
var lineTotal = Number(item.line_total != null ? item.line_total : qty * price);
total += lineTotal;
var title = item.title || (item.product && item.product.title) || "商品";
var image = item.image || (item.product && item.product.image) || "";
var opts = item.options_label || item.options_string || "";
html += '' +
'<article class="aksrt-cart-page__item" data-cart-index="' + index + '" data-product-id="' + Number(item.product_id || item.id || 0) + '" data-options-string="' + String(item.options_string || "").replace(/"/g, "&quot;") + '">' +
(image ? '<img class="aksrt-cart-page__item-image" src="' + image + '" alt="">' : '<div class="aksrt-cart-page__item-image aksrt-cart-page__item-image--placeholder"><i class="fas fa-box"></i></div>') +
'<div class="aksrt-cart-page__item-main">' +
'<h3>' + title + "</h3>" +
(opts ? "<small>" + opts + "</small>" : "") +
'<p>' + money(price) + "</p>" +
"</div>" +
'<div class="aksrt-cart-page__item-qty">' +
'<button type="button" data-qty-action="dec">-</button>' +
"<span>" + qty + "</span>" +
'<button type="button" data-qty-action="inc">+</button>' +
"</div>" +
'<strong class="aksrt-cart-page__item-total">' + money(lineTotal) + "</strong>" +
'<button type="button" class="aksrt-cart-page__item-remove" data-qty-action="remove"><i class="fas fa-trash"></i></button>' +
"</article>";
});
itemsEl.innerHTML = html;
subtotalEl.textContent = money(total);
if (!previewState) {
shippingEl.textContent = money(0);
discountEl.textContent = "-" + money(0);
totalEl.textContent = money(total);
}
}
function setSummary(data) {
previewState = data || null;
subtotalEl.textContent = money((data && data.subtotal) || 0);
shippingEl.textContent = money((data && data.shipping_fee) || 0);
discountEl.textContent = "-" + money((data && data.discount) || 0);
totalEl.textContent = money((data && data.total) || 0);
createBtn.disabled = !data;
}
function request(path, body) { return rest(path, "POST", body || {}); }
function previewCheckout() {
var payload = getPayload();
if (!payload.items.length) {
previewMessageEl.textContent = "请先添加商品后再试算。";
return;
}
previewBtn.disabled = true;
previewMessageEl.textContent = "正在试算订单...";
request("/shop/frontend/checkout/preview", payload)
.then(function (result) {
if (!result.success) {
setSummary(null);
previewMessageEl.textContent = result.message || "试算失败。";
return;
}
setSummary(result.data);
previewMessageEl.textContent = "已完成试算,可直接创建订单。";
})
.catch(function () {
setSummary(null);
previewMessageEl.textContent = "网络错误,请稍后重试。";
})
.finally(function () {
previewBtn.disabled = false;
});
}
function createOrder() {
var payload = getPayload();
if (!previewState) {
previewCheckout();
return;
}
createBtn.disabled = true;
request("/shop/frontend/orders", payload)
.then(function (result) {
if (!result.success) {
previewMessageEl.textContent = result.message || "订单创建失败。";
createBtn.disabled = false;
return;
}
var orderNumber = (result.data && result.data.order_number) || "";
var nextOrdersUrl = ordersUrl() + (String(ordersUrl()).indexOf("?") >= 0 ? "&" : "?") + "order_status=pending";
if (!orderNumber) {
window.location.href = nextOrdersUrl;
return;
}
// 立即发起支付:跳转型网关直接前往第三方,余额型同步完成。
request("/shop/frontend/orders/" + orderNumber + "/pay", {})
.then(function (pay) {
var data = (pay && pay.data) || {};
if (pay && pay.success && data.redirect && data.payment_url && /^https?:\/\//i.test(data.payment_url)) {
window.location.href = data.payment_url;
return;
}
// 二维码 / 余额 / 失败:统一回订单中心处理(含 ?payment 提示)。
window.location.href = nextOrdersUrl;
})
.catch(function () {
window.location.href = nextOrdersUrl;
});
})
.catch(function () {
previewMessageEl.textContent = "网络错误,请稍后重试。";
createBtn.disabled = false;
});
}
page.addEventListener("click", function (event) {
var actionButton = event.target.closest("[data-qty-action]");
if (actionButton) {
var itemEl = actionButton.closest("[data-cart-index]");
if (!itemEl) return;
var productId = Number(itemEl.getAttribute("data-product-id") || 0);
var optionsString = itemEl.getAttribute("data-options-string") || "";
var action = actionButton.getAttribute("data-qty-action");
var path = "/shop/frontend/cart/add";
var body = { product_id: productId, options_string: optionsString, count: 1 };
if (action === "dec") {
path = "/shop/frontend/cart/reduce";
} else if (action === "remove") {
path = "/shop/frontend/cart/remove";
body = { product_id: productId, options_string: optionsString };
} else if (action !== "inc") {
return;
}
rest(path, "POST", body).then(function (result) {
if (!result || !result.success) {
window.alert((result && result.message) || "操作失败");
return;
}
setSummary(null);
loadServerCart();
});
return;
}
if (event.target.closest("[data-aksrt-clear-cart]")) {
rest("/shop/frontend/cart/empty", "POST", {}).then(function () {
setSummary(null);
loadServerCart();
});
return;
}
if (event.target.closest("[data-aksrt-preview-checkout]")) {
previewCheckout();
return;
}
if (event.target.closest("[data-aksrt-create-order]")) {
createOrder();
return;
}
var resumeButton = event.target.closest("[data-aksrt-resume-order]");
if (resumeButton) {
window.location.href = ordersUrl() + (String(ordersUrl()).indexOf("?") >= 0 ? "&" : "?") + "order_status=pending";
}
});
function loadServerCart() {
return rest("/shop/frontend/cart", "GET").then(function (result) {
var items = (result && result.success && result.data && result.data.items) ? result.data.items : [];
items = items.map(function (it) {
it.qty = it.quantity || it.qty || 1;
it.price = it.unit_price != null ? it.unit_price : (it.product && it.product.price) || 0;
it.title = it.title || (it.product && it.product.title) || "商品";
it.image = it.image || (it.product && it.product.image) || "";
return it;
});
setCart(items);
renderCart();
}).catch(function () {
setCart([]);
renderCart();
});
}
var couponInput = page.querySelector("[data-aksrt-coupon-code]");
if (couponInput && searchParams.has("coupon")) {
couponInput.value = searchParams.get("coupon") || "";
}
/* ── Address Book Management ── */
var addressModal = page.querySelector("[data-aksrt-address-modal]");
var addressForm = page.querySelector("[data-aksrt-address-form]");
var addressList = page.querySelector("[data-aksrt-address-list]");
var addressTitle = page.querySelector("[data-aksrt-address-modal-title]");
function openAddressModal(mode, address) {
if (!addressModal || !addressForm) return;
addressForm.reset();
addressForm.querySelector('[name="address_id"]').value = "";
if (mode === "edit" && address) {
addressTitle.textContent = "编辑地址";
addressForm.querySelector('[name="address_id"]').value = address.id || "";
addressForm.querySelector('[name="name"]').value = address.name || "";
addressForm.querySelector('[name="phone"]').value = address.phone || "";
addressForm.querySelector('[name="province"]').value = address.province || "";
addressForm.querySelector('[name="city"]').value = address.city || "";
addressForm.querySelector('[name="district"]').value = address.district || "";
addressForm.querySelector('[name="address"]').value = address.address || "";
addressForm.querySelector('[name="is_default"]').checked = !!address.is_default;
} else {
addressTitle.textContent = "新增地址";
}
addressModal.hidden = false;
}
function closeAddressModal() {
if (addressModal) addressModal.hidden = true;
}
function refreshAddressList() {
fetch(restBase() + "/shop/frontend/address", {
headers: { "X-WP-Nonce": aksrtData.restNonce }
})
.then(function (r) { return r.json(); })
.then(function (result) {
if (!result.success || !addressList) return;
var addresses = (result.data && result.data.addresses) || [];
renderAddressList(addresses);
})
.catch(function () {});
}
function renderAddressList(addresses) {
if (!addressList) return;
if (!addresses.length) {
addressList.innerHTML =
'<div class="aksrt-cart-page__address-empty" data-aksrt-address-empty>' +
'<i class="fas fa-map-marker-alt" aria-hidden="true"></i>' +
"<p>暂无收货地址,请先新增。</p>" +
"</div>";
return;
}
var html = "";
addresses.forEach(function (addr, index) {
html +=
'<div class="aksrt-cart-page__option-card aksrt-cart-page__address-card" data-aksrt-address-card="' + addr.id + '">' +
'<label class="aksrt-cart-page__address-label">' +
'<input type="radio" name="aksrt_cart_address" value="' + addr.id + '"' + (index === 0 || addr.is_default ? " checked" : "") + ">" +
'<span class="aksrt-cart-page__option-body">' +
"<strong>" + escHtml(addr.name) + (addr.is_default ? ' <span class="aksrt-cart-page__default-tag">默认</span>' : "") + "</strong>" +
"<span>" + escHtml(addr.phone) + "</span>" +
"<span>" + escHtml(addr.full_text) + "</span>" +
"</span></label>" +
'<div class="aksrt-cart-page__address-actions">' +
'<button type="button" class="btn-ghost btn-xs" data-aksrt-address-edit="' + addr.id + '">编辑</button>' +
'<button type="button" class="btn-ghost btn-xs" data-aksrt-address-delete="' + addr.id + '">删除</button>' +
(addr.is_default ? "" : '<button type="button" class="btn-ghost btn-xs" data-aksrt-address-set-default="' + addr.id + '">设为默认</button>') +
"</div></div>";
});
addressList.innerHTML = html;
}
function escHtml(str) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(str || ""));
return div.innerHTML;
}
function getAddressById(id) {
var cards = addressList ? addressList.querySelectorAll("[data-aksrt-address-card]") : [];
var found = null;
cards.forEach(function (card) {
if (String(card.getAttribute("data-aksrt-address-card")) === String(id)) {
var body = card.querySelector(".aksrt-cart-page__option-body");
if (body) {
var spans = body.querySelectorAll("span");
var strong = body.querySelector("strong");
found = {
id: id,
name: strong ? strong.textContent.replace("默认", "").trim() : "",
phone: spans[0] ? spans[0].textContent : "",
full_text: spans[1] ? spans[1].textContent : ""
};
}
}
});
return found;
}
// Address event delegation
page.addEventListener("click", function (event) {
if (event.target.closest("[data-aksrt-address-add]")) {
openAddressModal("add");
return;
}
var editBtn = event.target.closest("[data-aksrt-address-edit]");
if (editBtn) {
var editId = editBtn.getAttribute("data-aksrt-address-edit");
var addr = getAddressById(editId);
openAddressModal("edit", addr);
return;
}
var deleteBtn = event.target.closest("[data-aksrt-address-delete]");
if (deleteBtn) {
var deleteId = deleteBtn.getAttribute("data-aksrt-address-delete");
if (!confirm("确定删除该地址吗?")) return;
rest("/shop/frontend/address/" + deleteId, "DELETE").then(function (result) {
if (!result || !result.success) {
alert((result && result.message) || "删除失败。");
return;
}
refreshAddressList();
}).catch(function () { alert("网络错误。"); });
return;
}
var defaultBtn = event.target.closest("[data-aksrt-address-set-default]");
if (defaultBtn) {
var defaultId = defaultBtn.getAttribute("data-aksrt-address-set-default");
request("/shop/frontend/address/" + defaultId + "/default", {}).then(function (result) {
if (!result.success) {
alert(result.message || "设置失败。");
return;
}
refreshAddressList();
}).catch(function () { alert("网络错误。"); });
return;
}
if (event.target.closest("[data-aksrt-address-modal-close]") || event.target.classList.contains("aksrt-modal__overlay")) {
closeAddressModal();
}
});
if (addressForm) {
addressForm.addEventListener("submit", function (event) {
event.preventDefault();
var formData = new FormData(addressForm);
var addressId = formData.get("address_id");
var payload = {
name: (formData.get("name") || "").trim(),
phone: (formData.get("phone") || "").trim(),
province: (formData.get("province") || "").trim(),
city: (formData.get("city") || "").trim(),
district: (formData.get("district") || "").trim(),
address: (formData.get("address") || "").trim(),
is_default: formData.get("is_default") === "1"
};
if (!payload.name || !payload.phone || !payload.address) {
alert("请填写必填项。");
return;
}
var url = addressId
? "/shop/frontend/address/" + addressId
: "/shop/frontend/address";
request(url, payload).then(function (result) {
if (!result.success) {
alert(result.message || "保存失败。");
return;
}
closeAddressModal();
refreshAddressList();
}).catch(function () { alert("网络错误。"); });
});
}
loadServerCart();
})();
+1 -226
View File
@@ -89,10 +89,6 @@
return suffix ? base + suffix : base;
}
function cartUrl() {
return aksrtData.cartUrl || (aksrtData.routes && aksrtData.routes.cart) || "/";
}
/* ── Order review modal (zibll 1:1) ── */
var STAR_SVG =
'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>';
@@ -434,7 +430,7 @@
badge.textContent = statusLabel || newStatus;
}
// Hide action buttons that are no longer relevant
var actions = card.querySelectorAll("[data-aksrt-order-pay], [data-aksrt-order-cancel], [data-aksrt-order-after-sale], [data-aksrt-order-receipt], [data-aksrt-order-rebuy]");
var actions = card.querySelectorAll("[data-aksrt-order-pay], [data-aksrt-order-cancel]");
for (var i = 0; i < actions.length; i++) {
actions[i].style.display = "none";
}
@@ -640,21 +636,9 @@
// Two-step cancel inside the modal — no window.confirm.
footer += '<button type="button" class="btn-ghost" data-aksrt-order-cancel="' + escapeHtml(order.order_number) + '" data-aksrt-cancel-step="1">关闭订单</button>';
}
if (actions.can_receipt) {
footer += '<button type="button" class="btn-primary" data-aksrt-order-receipt="' + escapeHtml(order.order_number) + '">确认收货</button>';
}
if (actions.can_review) {
footer += '<button type="button" class="btn-primary c-green" data-aksrt-order-review="' + escapeHtml(order.order_number) + '">评价</button>';
}
if (actions.can_pay) {
footer += '<button type="button" class="btn-primary" data-aksrt-order-pay="' + escapeHtml(order.order_number) + '" data-aksrt-order-method="' + escapeHtml((payment && payment.value) || "") + '">立即支付</button>';
}
if (actions.can_after_sale) {
footer += '<button type="button" class="btn-outline" data-aksrt-order-after-sale="' + escapeHtml(order.order_number) + '">申请售后</button>';
}
if (actions.can_rebuy) {
footer += '<button type="button" class="btn-outline" data-aksrt-order-rebuy="' + escapeHtml(order.order_number) + '">再次购买</button>';
}
if (actions.can_view_product && order.permalink) {
footer += '<a class="btn-ghost" href="' + escapeHtml(order.permalink) + '">查看商品</a>';
}
@@ -695,70 +679,6 @@
}
}
/* ── After-Sale Modal ── */
var afterSaleModal = page.querySelector("[data-aksrt-aftersale-modal]");
var afterSaleForm = page.querySelector("[data-aksrt-aftersale-form]");
var afterSaleOrderInput = afterSaleForm ? afterSaleForm.querySelector('[name="order_number"]') : null;
function openAfterSaleModal(orderNumber) {
if (!afterSaleModal || !afterSaleForm) {
showToast("售后表单加载失败,请刷新页面后重试。");
return;
}
afterSaleForm.reset();
if (afterSaleOrderInput) afterSaleOrderInput.value = orderNumber;
afterSaleModal.hidden = false;
}
function closeAfterSaleModal() {
if (afterSaleModal) afterSaleModal.hidden = true;
}
if (afterSaleForm) {
afterSaleForm.addEventListener("submit", function (event) {
event.preventDefault();
var formData = new FormData(afterSaleForm);
var orderNumber = formData.get("order_number");
var reason = (formData.get("reason") || "").trim();
if (!reason) {
showToast("请填写售后原因。");
return;
}
var submitBtn = afterSaleForm.querySelector('button[type="submit"]');
if (submitBtn) {
submitBtn.disabled = true;
submitBtn.textContent = "提交中...";
}
request(orderPath(orderNumber, "/after-sale"), {
type: formData.get("type") || "refund",
reason: reason,
note: (formData.get("note") || "").trim()
}).then(function (result) {
if (submitBtn) {
submitBtn.disabled = false;
submitBtn.textContent = "提交售后";
}
if (!result.success) {
showToast(result.message || "提交售后失败。");
return;
}
closeAfterSaleModal();
showToast("售后申请已提交。");
// Local refresh: update card status
var card = findOrderCard(orderNumber);
updateCardStatus(card, "refunded", "已退款");
}).catch(function () {
if (submitBtn) {
submitBtn.disabled = false;
submitBtn.textContent = "提交售后";
}
showToast("网络错误,请稍后重试。");
});
});
}
/* ── Countdown timer ── */
function updateCountdowns() {
var nodes = page.querySelectorAll("[data-aksrt-order-countdown]");
@@ -808,56 +728,6 @@
return;
}
// Confirm receipt
var receiptBtn = event.target.closest("[data-aksrt-order-receipt]");
if (receiptBtn) {
var receiptOrder = receiptBtn.getAttribute("data-aksrt-order-receipt");
if (!receiptOrder) return;
if (!window.confirm("确认已收到货物?")) return;
receiptBtn.disabled = true;
request(orderPath(receiptOrder, "/confirm-receipt"), {})
.then(function (result) {
receiptBtn.disabled = false;
if (!result || !result.success) {
showToast((result && result.message) || "确认收货失败");
return;
}
showToast("已确认收货");
updateCardStatus(findOrderCard(receiptOrder), "completed", "已完成");
if (detailOrderNumber === receiptOrder) {
closeOrderDetailModal();
}
})
.catch(function () {
receiptBtn.disabled = false;
showToast("网络错误");
});
return;
}
// Rebuy
var rebuyBtn = event.target.closest("[data-aksrt-order-rebuy]");
if (rebuyBtn) {
var rebuyOrder = rebuyBtn.getAttribute("data-aksrt-order-rebuy");
if (!rebuyOrder) return;
rebuyBtn.disabled = true;
request(orderPath(rebuyOrder, "/rebuy"), {})
.then(function (result) {
rebuyBtn.disabled = false;
if (!result || !result.success) {
showToast((result && result.message) || "再次购买失败");
return;
}
showToast("已加入购物车");
window.location.href = cartUrl();
})
.catch(function () {
rebuyBtn.disabled = false;
showToast("网络错误");
});
return;
}
// Review modal (zibll order_comment_modal 1:1 UX)
var reviewBtn = event.target.closest("[data-aksrt-order-review]");
if (reviewBtn) {
@@ -992,103 +862,8 @@
});
return;
}
// After-Sale
var afterSaleButton = event.target.closest("[data-aksrt-order-after-sale]");
if (afterSaleButton) {
var afterSaleOrderNumber = afterSaleButton.getAttribute("data-aksrt-order-after-sale");
closeOrderDetailModal();
openAfterSaleModal(afterSaleOrderNumber);
return;
}
// Return shipping
var returnShipBtn = event.target.closest("[data-aksrt-return-ship]");
if (returnShipBtn) {
openReturnShipModal(returnShipBtn.getAttribute("data-aksrt-return-ship"));
return;
}
// Cancel after-sale ticket
var asCancelBtn = event.target.closest("[data-aksrt-as-cancel]");
if (asCancelBtn) {
var tid = asCancelBtn.getAttribute("data-aksrt-as-cancel");
if (!tid || !window.confirm("确认取消该售后申请?")) return;
asCancelBtn.disabled = true;
request("/shop/frontend/after-sale/" + tid + "/cancel", { reason: "" })
.then(function (result) {
asCancelBtn.disabled = false;
if (!result || !result.success) {
showToast((result && result.message) || "取消失败");
return;
}
showToast(result.message || "已取消售后");
window.location.reload();
})
.catch(function () {
asCancelBtn.disabled = false;
showToast("网络错误");
});
return;
}
// Close after-sale modal
if (event.target.closest("[data-aksrt-aftersale-modal-close]") || (event.target.classList && event.target.classList.contains("aksrt-modal__overlay") && event.target.closest("[data-aksrt-aftersale-modal]"))) {
closeAfterSaleModal();
return;
}
// Close return-ship modal
if (event.target.closest("[data-aksrt-return-ship-close]") || (event.target.classList && event.target.classList.contains("aksrt-modal__overlay") && event.target.closest("[data-aksrt-return-ship-modal]"))) {
closeReturnShipModal();
}
});
/* ── Return shipping modal ── */
var returnShipModal = page.querySelector("[data-aksrt-return-ship-modal]");
var returnShipForm = page.querySelector("[data-aksrt-return-ship-form]");
function openReturnShipModal(ticketId) {
if (!returnShipModal || !returnShipForm) return;
returnShipForm.reset();
var idInput = returnShipForm.querySelector('[name="ticket_id"]');
if (idInput) idInput.value = ticketId || "";
returnShipModal.hidden = false;
}
function closeReturnShipModal() {
if (returnShipModal) returnShipModal.hidden = true;
}
if (returnShipForm) {
returnShipForm.addEventListener("submit", function (event) {
event.preventDefault();
var fd = new FormData(returnShipForm);
var tid = fd.get("ticket_id");
var carrier = (fd.get("carrier") || "").trim();
var tracking = (fd.get("tracking_no") || "").trim();
if (!carrier || !tracking) {
showToast("请填写快递公司与运单号");
return;
}
var btn = returnShipForm.querySelector('button[type="submit"]');
if (btn) { btn.disabled = true; }
request("/shop/frontend/after-sale/" + tid + "/return-shipping", {
carrier: carrier,
tracking_no: tracking
}).then(function (result) {
if (btn) btn.disabled = false;
if (!result || !result.success) {
showToast((result && result.message) || "提交失败");
return;
}
closeReturnShipModal();
showToast(result.message || "退货物流已提交");
window.location.reload();
}).catch(function () {
if (btn) btn.disabled = false;
showToast("网络错误");
});
});
}
/* ── Coupon wallet ── */
var couponRoot = page.querySelector("[data-aksrt-coupon-wallet-list]");
if (couponRoot) {
-295
View File
@@ -1,295 +0,0 @@
/**
* Product archive — cat filter + sort + AJAX load more (zibll ajax-next UX).
*
* Uses REST /shop/frontend/products/archive and optional AksrtAjaxList events.
*
* @package AKSRT
*/
(function () {
"use strict";
var root = document.querySelector("[data-aksrt-product-archive]");
if (!root) return;
function restBase() {
var site = window.aksrtData && aksrtData.siteUrl ? String(aksrtData.siteUrl).replace(/\/$/, "") : "";
return site + "/wp-json/aksrt/v1";
}
function toast(msg) {
if (typeof window.aksrtToast === "function") {
window.aksrtToast(msg);
return;
}
if (window.console) console.log(msg);
}
var grid = root.querySelector("[data-aksrt-product-grid], #aksrt-product-grid");
var pager = root.querySelector("[data-aksrt-ajaxpager], .ajaxpager");
var countEl = root.querySelector("[data-aksrt-archive-count]");
var headerHost = root.querySelector("[data-aksrt-ajax-header]");
var loadMoreBtn = root.querySelector("[data-aksrt-shop-load-more]");
var loader = root.querySelector("[data-aksrt-ajax-loader], .post_ajax_loader");
var state = {
taxonomy: root.getAttribute("data-taxonomy") || "",
termId: Number(root.getAttribute("data-term-id") || 0),
orderby: root.getAttribute("data-orderby") || "date",
order: (root.getAttribute("data-order") || "DESC").toUpperCase(),
page: Number(root.getAttribute("data-page") || 1),
maxPages: Number(root.getAttribute("data-max-pages") || 1),
paging: root.getAttribute("data-paging") || "number",
ias: root.getAttribute("data-ias") === "1",
iasMax: Number(root.getAttribute("data-ias-max") || 5),
loading: false,
autoLoads: 0,
};
function showLoader(on) {
if (loader) {
loader.hidden = !on;
loader.style.display = on ? "" : "none";
loader.classList.toggle("is-loading", !!on);
}
if (pager) pager.classList.toggle("is-ajax-loading", !!on);
}
function updateLoadMore(hasMore) {
var pag = root.querySelector(".ajax-pag");
if (loadMoreBtn) {
loadMoreBtn.style.display = hasMore ? "" : "none";
loadMoreBtn.disabled = false;
loadMoreBtn.textContent = hasMore ? "加载更多" : "没有更多了";
if (!hasMore) loadMoreBtn.classList.add("ajax-nomore");
else loadMoreBtn.classList.remove("ajax-nomore");
}
if (pag) pag.style.display = hasMore ? "" : "none";
}
function syncOrderbyActive() {
root.querySelectorAll("[data-aksrt-shop-orderby]").forEach(function (a) {
var key = a.getAttribute("data-aksrt-shop-orderby") || "";
var active = key === state.orderby;
a.classList.toggle("is-active", active);
a.classList.toggle("focus-color", active && key === "price");
});
}
function fetchArchive(page, orderby, order, replace, termId) {
if (state.loading) return Promise.resolve();
state.loading = true;
showLoader(true);
if (loadMoreBtn) {
loadMoreBtn.disabled = true;
loadMoreBtn.textContent = "加载中…";
}
var qs = new URLSearchParams();
qs.set("taxonomy", state.taxonomy);
qs.set("term_id", String(typeof termId === "number" ? termId : state.termId));
qs.set("page", String(page));
qs.set("orderby", orderby || state.orderby);
if ((orderby || state.orderby) === "price") {
qs.set("order", order || state.order || "ASC");
}
var container = pager || grid || root;
try {
container.dispatchEvent(
new CustomEvent("post_ajax.before", {
bubbles: true,
detail: { page: page, orderby: orderby || state.orderby, replace: !!replace },
})
);
} catch (e0) {}
return fetch(restBase() + "/shop/frontend/products/archive?" + qs.toString(), {
method: "GET",
credentials: "same-origin",
headers: {
Accept: "application/json",
"X-WP-Nonce": (window.aksrtData && aksrtData.restNonce) || "",
"X-AKSRT-Ajax": "list",
},
})
.then(function (r) {
return r.json();
})
.then(function (result) {
state.loading = false;
showLoader(false);
if (!result || !result.success || !result.data) {
toast((result && result.message) || "加载失败");
updateLoadMore(state.page < state.maxPages);
return;
}
var data = result.data;
state.page = Number(data.page || page);
state.maxPages = Number(data.max_pages || 1);
state.orderby = data.orderby || state.orderby;
state.order = String(data.order || state.order || "DESC").toUpperCase();
if (typeof termId === "number" && termId > 0) {
state.termId = termId;
}
if (data.term && data.term.id) {
state.termId = Number(data.term.id);
}
root.setAttribute("data-page", String(state.page));
root.setAttribute("data-max-pages", String(state.maxPages));
root.setAttribute("data-orderby", state.orderby);
root.setAttribute("data-order", state.order);
root.setAttribute("data-term-id", String(state.termId));
if (countEl && typeof data.total !== "undefined") {
countEl.textContent = "共 " + data.total + " 件商品";
}
var titleEl = root.querySelector("[data-aksrt-archive-title]");
if (titleEl && data.term && data.term.name) {
titleEl.textContent = data.term.name;
}
var descEl = root.querySelector("[data-aksrt-archive-desc]");
if (descEl && data.term) {
descEl.textContent = data.term.description || "";
descEl.style.display = data.term.description ? "" : "none";
}
if (headerHost && data.header_html) {
// Keep title/count; replace filter widget if present.
var existingFilter = headerHost.querySelector("[data-aksrt-shop-cat-filter], .shop-cat-filter");
var tmp = document.createElement("div");
tmp.innerHTML = data.header_html;
var nextFilter = tmp.querySelector("[data-aksrt-shop-cat-filter], .shop-cat-filter") || tmp.firstElementChild;
if (existingFilter && nextFilter) {
existingFilter.replaceWith(nextFilter);
} else if (!existingFilter && nextFilter) {
headerHost.appendChild(nextFilter);
}
}
var html = data.html || data.empty_html || "";
if (grid) {
if (replace) {
grid.innerHTML = html;
} else if (html) {
grid.insertAdjacentHTML("beforeend", html);
}
}
if (data.paginate_html) {
var oldPag = root.querySelector(".ajax-pag");
var wrap = document.createElement("div");
wrap.innerHTML = data.paginate_html;
var nextPag = wrap.firstElementChild;
if (oldPag && nextPag) oldPag.replaceWith(nextPag);
else if (!oldPag && nextPag && pager) pager.appendChild(nextPag);
loadMoreBtn = root.querySelector("[data-aksrt-shop-load-more]");
}
syncOrderbyActive();
updateLoadMore(!!data.has_more || state.page < state.maxPages);
try {
container.dispatchEvent(
new CustomEvent("post_ajax.ed", {
bubbles: true,
detail: { page: state.page, replace: !!replace, data: data },
})
);
document.dispatchEvent(
new CustomEvent("aksrt:posts:rendered", {
bubbles: true,
detail: { container: grid, replace: !!replace },
})
);
} catch (e1) {}
})
.catch(function () {
state.loading = false;
showLoader(false);
updateLoadMore(state.page < state.maxPages);
toast("网络错误");
});
}
function pushUrl(orderby, order, termUrl) {
try {
var u = termUrl ? new URL(termUrl, window.location.origin) : new URL(window.location.href);
if (orderby) u.searchParams.set("orderby", orderby);
else u.searchParams.delete("orderby");
u.searchParams.delete("shop_orderby");
if (orderby === "price" && order) u.searchParams.set("order", order);
else u.searchParams.delete("order");
u.searchParams.delete("paged");
window.history.replaceState({}, "", u.toString());
} catch (err) {}
}
root.addEventListener("click", function (e) {
// Category / sort links with ajax-next — intercept for REST (richer payload).
var termLink = e.target.closest("[data-aksrt-shop-term].ajax-next, a.ajax-next[data-aksrt-shop-term]");
if (termLink && root.contains(termLink)) {
e.preventDefault();
e.stopPropagation();
var tid = Number(termLink.getAttribute("data-aksrt-shop-term") || 0);
var href = termLink.getAttribute("href") || "";
state.autoLoads = 0;
if (tid > 0) state.termId = tid;
pushUrl(state.orderby, state.order, href);
var rt = termLink.getAttribute("route-title");
if (rt) {
try {
document.title = rt;
} catch (e2) {}
}
fetchArchive(1, state.orderby, state.order, true, tid);
return;
}
var sort = e.target.closest("[data-aksrt-shop-orderby]");
if (sort && root.contains(sort) && sort.tagName === "A") {
e.preventDefault();
e.stopPropagation();
var orderby = sort.getAttribute("data-aksrt-shop-orderby") || "date";
var nextOrder = sort.getAttribute("data-aksrt-shop-order") || "";
if (orderby === "price") {
if (state.orderby === "price" && nextOrder) {
state.order = nextOrder.toUpperCase();
} else if (state.orderby !== "price") {
state.order = "ASC";
} else {
state.order = state.order === "ASC" ? "DESC" : "ASC";
}
}
if (orderby === state.orderby && orderby !== "price" && state.paging === "ajax") return;
state.orderby = orderby;
state.autoLoads = 0;
pushUrl(orderby, state.order);
fetchArchive(1, orderby, state.order, true);
return;
}
var more = e.target.closest("[data-aksrt-shop-load-more]");
if (more && root.contains(more)) {
e.preventDefault();
e.stopPropagation();
if (state.page >= state.maxPages) return;
fetchArchive(state.page + 1, state.orderby, state.order, false);
}
});
if (state.paging === "ajax" && state.ias && "IntersectionObserver" in window && loadMoreBtn) {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
if (state.loading || state.page >= state.maxPages) return;
if (state.iasMax > 0 && state.autoLoads >= state.iasMax) return;
state.autoLoads += 1;
fetchArchive(state.page + 1, state.orderby, state.order, false);
});
},
{ rootMargin: "240px" }
);
io.observe(loadMoreBtn);
}
})();
-407
View File
@@ -1,407 +0,0 @@
/**
* Product purchase page — options selector + server cart.
*
* @package AKSRT
*/
(function () {
"use strict";
function restBase() {
var root = (window.aksrtData && aksrtData.siteUrl) ? String(aksrtData.siteUrl).replace(/\/$/, "") : "";
return root + "/wp-json/aksrt/v1";
}
function restNonce() {
return (window.aksrtData && aksrtData.restNonce) || "";
}
function toast(msg, type) {
if (typeof window.aksrtToast === "function") {
window.aksrtToast(msg, type || "info");
return;
}
if (window.aksrt && typeof aksrt.notyf === "function") {
aksrt.notyf(msg, { type: type || "info" });
return;
}
window.alert(msg);
}
function rest(path, method, body) {
var opts = {
method: method || "GET",
credentials: "same-origin",
headers: {
"X-WP-Nonce": restNonce(),
},
};
if (body !== undefined) {
opts.headers["Content-Type"] = "application/json";
opts.body = JSON.stringify(body);
}
return fetch(restBase() + path, opts).then(function (r) {
return r.json();
});
}
function money(value, payModo) {
var n = Number(value || 0).toFixed(2);
return payModo === "points" ? n : "¥" + n;
}
/* ── Product page ── */
var productPage = document.querySelector("[data-aksrt-product-page]");
if (productPage) {
var quantityInput = productPage.querySelector("[data-aksrt-quantity]");
var productId = Number(productPage.getAttribute("data-product-id") || 0);
var titleEl = productPage.querySelector(".aksrt-product-page__title");
var imageEl = productPage.querySelector(".aksrt-product-page__primary-image img");
var priceEl = productPage.querySelector("[data-aksrt-dynamic-price], .aksrt-product-page__price");
var stockEl = productPage.querySelector("[data-aksrt-stock-display]");
var couponEl = productPage.querySelector("[data-aksrt-product-coupon]");
var optionsRoot = productPage.querySelector("[data-aksrt-options-selector]");
var optionResult = productPage.querySelector("[data-aksrt-option-result]");
var selectedLabelsEl = productPage.querySelector("[data-aksrt-selected-labels]");
var resolvedPriceEl = productPage.querySelector("[data-aksrt-resolved-price]");
var resolvedStockEl = productPage.querySelector("[data-aksrt-resolved-stock]");
var payModo = productPage.getAttribute("data-pay-modo") || "0";
var basePrice = Number(productPage.getAttribute("data-base-price") || 0);
var baseStock = Number(productPage.getAttribute("data-base-stock") || 0);
var selectedByGroup = {};
var groupCount = optionsRoot
? optionsRoot.querySelectorAll(".aksrt-product-page__option-group").length
: 0;
function currentOptionsKey() {
if (!groupCount) return "";
var labels = [];
for (var i = 0; i < groupCount; i++) {
if (!selectedByGroup[i]) return null;
labels.push(selectedByGroup[i].label);
}
return labels.join("|");
}
function resolveSelection() {
if (!groupCount) {
return {
key: "",
labels: "",
price: basePrice,
stock: baseStock,
image: "",
};
}
var key = currentOptionsKey();
if (key === null) return null;
var price = basePrice;
var image = "";
var labels = [];
for (var i = 0; i < groupCount; i++) {
var sel = selectedByGroup[i];
labels.push(sel.label);
price += Number(sel.priceChange || 0);
if (sel.image) image = sel.image;
}
return {
key: key,
labels: labels.join(" / "),
price: Math.max(0, price),
stock: baseStock,
image: image,
};
}
function paintSelection() {
var resolved = resolveSelection();
if (!resolved) {
if (optionResult) optionResult.hidden = true;
return;
}
if (priceEl) {
if (groupCount && productPage.getAttribute("data-price-range") === "1" && currentOptionsKey() === null) {
/* keep range until complete selection */
} else {
priceEl.textContent = money(resolved.price, payModo) + (payModo === "points" ? "" : "");
if (payModo === "points" && priceEl.querySelector("small") === null) {
/* leave as-is */
}
}
}
if (stockEl && resolved.stock > -1) {
stockEl.textContent = String(resolved.stock);
}
if (quantityInput && resolved.stock > 0) {
quantityInput.setAttribute("max", String(resolved.stock));
if (Number(quantityInput.value) > resolved.stock) {
quantityInput.value = String(resolved.stock);
}
}
if (imageEl && resolved.image) {
imageEl.setAttribute("src", resolved.image);
}
if (optionResult) {
optionResult.hidden = false;
if (selectedLabelsEl) selectedLabelsEl.textContent = resolved.labels;
if (resolvedPriceEl) resolvedPriceEl.textContent = money(resolved.price, payModo);
if (resolvedStockEl) {
resolvedStockEl.textContent =
resolved.stock <= -1 ? "库存充足" : "库存 " + resolved.stock;
}
}
}
if (optionsRoot) {
optionsRoot.addEventListener("click", function (event) {
var btn = event.target.closest("[data-option-group]");
if (!btn || !optionsRoot.contains(btn)) return;
var group = btn.getAttribute("data-option-group");
var label = btn.getAttribute("data-option-label") || "";
var priceChange = Number(btn.getAttribute("data-price-change") || 0);
var image = btn.getAttribute("data-option-image") || "";
optionsRoot
.querySelectorAll('[data-option-group="' + group + '"]')
.forEach(function (el) {
el.classList.remove("is-active");
});
btn.classList.add("is-active");
selectedByGroup[group] = { label: label, priceChange: priceChange, image: image };
paintSelection();
});
}
function ensureOptionsSelected() {
if (!groupCount) return true;
if (currentOptionsKey() === null) {
toast("请先选择商品规格", "warning");
return false;
}
return true;
}
function addToServerCart(replaceQty) {
if (!window.aksrtData || !aksrtData.isLoggedIn) {
window.location.href = (aksrtData && aksrtData.routes && aksrtData.routes.login) || "/";
return;
}
if (!ensureOptionsSelected()) return;
var qty = Number(quantityInput ? quantityInput.value : 1) || 1;
var optionsString = currentOptionsKey() || "";
var body = {
product_id: productId,
options_string: optionsString,
count: qty,
};
rest("/shop/frontend/cart/add", "POST", body)
.then(function (result) {
if (!result || !result.success) {
toast((result && (result.message || result.error)) || "加入购物车失败", "error");
return;
}
toast("已加入购物车", "success");
if (replaceQty) {
var cartUrl = new URL(
(window.aksrtData && (aksrtData.cartUrl || (aksrtData.routes && aksrtData.routes.cart))) || "/",
window.location.origin
);
if (couponEl && couponEl.value) {
cartUrl.searchParams.set("coupon", couponEl.value);
}
window.location.href = cartUrl.toString();
}
})
.catch(function () {
toast("网络错误,请稍后重试", "error");
});
}
productPage.addEventListener("click", function (event) {
var qtyBtn = event.target.closest("[data-aksrt-qty-action]");
if (qtyBtn && quantityInput) {
var action = qtyBtn.getAttribute("data-aksrt-qty-action");
var current = Number(quantityInput.value || 1);
var max = Number(quantityInput.getAttribute("max") || 999);
quantityInput.value = action === "inc" ? Math.min(max, current + 1) : Math.max(1, current - 1);
return;
}
if (event.target.closest("[data-aksrt-add-cart]")) {
addToServerCart(false);
return;
}
if (event.target.closest("[data-aksrt-buy-now]")) {
addToServerCart(true);
return;
}
var thumb = event.target.closest("[data-aksrt-product-thumb]");
if (thumb && imageEl) {
imageEl.setAttribute("src", thumb.getAttribute("data-aksrt-product-thumb"));
return;
}
var videoBtn = event.target.closest("[data-aksrt-product-video]");
if (videoBtn) {
var url = videoBtn.getAttribute("data-aksrt-product-video");
if (url) window.open(url, "_blank", "noopener");
return;
}
var favBtn = event.target.closest("[data-aksrt-toggle-fav]");
if (favBtn) {
if (!window.aksrtData || !aksrtData.isLoggedIn) {
window.location.href = (aksrtData && aksrtData.routes && aksrtData.routes.login) || "/";
return;
}
var pid = Number(favBtn.getAttribute("data-aksrt-toggle-fav") || productId);
rest("/shop/frontend/products/" + pid + "/favorite", "POST", {})
.then(function (result) {
if (!result || !result.success) {
toast((result && result.message) || "操作失败", "error");
return;
}
var active = !!(result.data && result.data.is_favorite);
productPage.querySelectorAll("[data-aksrt-toggle-fav]").forEach(function (btn) {
btn.classList.toggle("is-active", active);
});
toast((result.message) || (active ? "已收藏" : "已取消收藏"), "success");
})
.catch(function () {
toast("网络错误", "error");
});
return;
}
var tabBtn = event.target.closest("[data-aksrt-product-tab]");
if (tabBtn) {
var tab = tabBtn.getAttribute("data-aksrt-product-tab");
productPage.querySelectorAll("[data-aksrt-product-tab]").forEach(function (b) {
b.classList.toggle("is-active", b === tabBtn);
});
productPage.querySelectorAll("[data-aksrt-product-panel]").forEach(function (panel) {
panel.hidden = panel.getAttribute("data-aksrt-product-panel") !== tab;
});
return;
}
if (event.target.closest("[data-aksrt-show-params]")) {
var paramsModal = productPage.querySelector("[data-aksrt-params-modal]");
if (paramsModal) paramsModal.hidden = false;
return;
}
if (event.target.closest("[data-aksrt-show-services]")) {
var servicesModal = productPage.querySelector("[data-aksrt-services-modal]");
if (servicesModal) servicesModal.hidden = false;
return;
}
if (event.target.closest("[data-aksrt-close-modal]")) {
var modal = event.target.closest("[data-aksrt-params-modal], [data-aksrt-services-modal], .aksrt-modal");
if (modal) modal.hidden = true;
}
});
}
/* ── Product editor (seller) ── */
var editor = document.querySelector("[data-aksrt-product-editor]");
if (!editor || !window.aksrtData) {
return;
}
var form = editor.querySelector("[data-aksrt-product-form]");
var messageEl = editor.querySelector("[data-aksrt-product-editor-message]");
if (!form) return;
function selectedMultiValues(select) {
if (!select) return [];
return Array.prototype.slice
.call(select.options)
.filter(function (option) { return option.selected; })
.map(function (option) { return Number(option.value || 0); })
.filter(Boolean);
}
function parseOptionsText(text) {
var groups = [];
String(text || "").split(String.fromCharCode(10)).forEach(function (line) {
line = line.replace(/\r/g, "").trim();
if (!line) return;
var parts = line.split("|");
if (parts.length < 2) return;
var name = parts[0].trim();
var values = [];
parts.slice(1).join("|").split(",").forEach(function (chunk) {
chunk = chunk.trim();
if (!chunk) return;
var segs = chunk.split(":");
var label = (segs[0] || "").trim();
if (!label) return;
values.push({ label: label, price_change: Number(segs[1] || 0), image: "" });
});
if (name && values.length) {
groups.push({ name: name, view_mode: "list", values: values });
}
});
return groups;
}
form.addEventListener("submit", function (event) {
event.preventDefault();
var formData = new FormData(form);
var productId = Number(editor.getAttribute("data-product-id") || 0);
var gallery = String(formData.get("gallery") || "")
.split(String.fromCharCode(10))
.map(function (line) { return line.replace(/\r/g, "").trim(); })
.filter(Boolean);
var payload = {
title: String(formData.get("title") || "").trim(),
price: Number(formData.get("price") || 0),
stock: Number(formData.get("stock") || 0),
excerpt: String(formData.get("excerpt") || ""),
content: String(formData.get("content") || ""),
status: String(formData.get("status") || "draft"),
categories: selectedMultiValues(form.querySelector('select[name="categories[]"]')),
tags: String(formData.get("tags") || "")
.split(",")
.map(function (tag) { return tag.trim(); })
.filter(Boolean),
image: String(formData.get("image") || "").trim(),
gallery: gallery,
shipping_mode: String(formData.get("shipping_mode") || "express"),
shipping_fee: Number(formData.get("shipping_fee") || 0),
after_sale_policy: String(formData.get("after_sale_policy") || ""),
support_refund: formData.get("support_refund") === "1",
options: parseOptionsText(formData.get("options_text") || ""),
start_price: Number(formData.get("start_price") || 0),
pay_modo: String(formData.get("pay_modo") || "0"),
product_params: String(formData.get("product_params") || ""),
product_video: String(formData.get("product_video") || "")
.split(String.fromCharCode(10))
.map(function (line) { return line.replace(/\r/g, "").trim(); })
.filter(Boolean)
};
var path = productId > 0 ? "/shop/frontend/products/" + productId : "/shop/frontend/products";
if (messageEl) messageEl.textContent = "正在保存商品...";
rest(path, "POST", payload)
.then(function (result) {
if (!result.success) {
if (messageEl) messageEl.textContent = result.message || "保存失败。";
return;
}
var centerUrl = aksrtData.userCenterUrl || "/";
if (messageEl) messageEl.textContent = "商品已保存,正在返回用户中心...";
window.location.href = centerUrl;
})
.catch(function () {
if (messageEl) messageEl.textContent = "网络错误,请稍后重试。";
});
});
})();