(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 = '' + '
' + '' + "

购物车为空,去商品页添加想购买的内容。

" + '继续浏览' + "
"; 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 += '' + '
' + (image ? '' : '
') + '
' + '

' + title + "

" + (opts ? "" + opts + "" : "") + '

' + money(price) + "

" + "
" + '
' + '' + "" + qty + "" + '' + "
" + '' + money(lineTotal) + "" + '' + "
"; }); 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 = '
' + '' + "

暂无收货地址,请先新增。

" + "
"; return; } var html = ""; addresses.forEach(function (addr, index) { html += '
' + '" + '
' + '' + '' + (addr.is_default ? "" : '') + "
"; }); 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(); })();