Files
wordpress-theme-aksrt/assets/js/product-archive.js
T
kate522 f3db6c89cc feat(shop): complete storefront archive, seller edit, revenue
Wire product cat/tag archives to settings-driven sort and AJAX paging,
seller product options/video/params editing, revenue withdraw form and
order review submit — finishing remaining shop frontend gaps after buy-path.
2026-07-12 10:38:02 +08:00

153 lines
5.1 KiB
JavaScript

/**
* Product archive — sort + AJAX load more.
*
* @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 countEl = root.querySelector("[data-aksrt-archive-count]");
var loadMoreBtn = root.querySelector("[data-aksrt-shop-load-more]");
var state = {
taxonomy: root.getAttribute("data-taxonomy") || "",
termId: Number(root.getAttribute("data-term-id") || 0),
orderby: root.getAttribute("data-orderby") || "date",
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 fetchArchive(page, orderby, replace) {
if (state.loading) return Promise.resolve();
state.loading = true;
if (loadMoreBtn) {
loadMoreBtn.disabled = true;
loadMoreBtn.textContent = "加载中...";
}
var qs = new URLSearchParams();
qs.set("taxonomy", state.taxonomy);
qs.set("term_id", String(state.termId));
qs.set("page", String(page));
qs.set("orderby", orderby || state.orderby);
return fetch(restBase() + "/shop/frontend/products/archive?" + qs.toString(), {
method: "GET",
credentials: "same-origin",
headers: {
"X-WP-Nonce": (window.aksrtData && aksrtData.restNonce) || "",
},
})
.then(function (r) { return r.json(); })
.then(function (result) {
state.loading = false;
if (!result || !result.success || !result.data) {
toast((result && result.message) || "加载失败");
if (loadMoreBtn) {
loadMoreBtn.disabled = false;
loadMoreBtn.textContent = "加载更多";
}
return;
}
var data = result.data;
state.page = Number(data.page || page);
state.maxPages = Number(data.max_pages || 1);
state.orderby = data.orderby || state.orderby;
root.setAttribute("data-page", String(state.page));
root.setAttribute("data-max-pages", String(state.maxPages));
root.setAttribute("data-orderby", state.orderby);
if (countEl && typeof data.total !== "undefined") {
countEl.textContent = "共 " + data.total + " 件商品";
}
if (grid) {
if (replace) {
grid.innerHTML = data.html || "";
} else if (data.html) {
grid.insertAdjacentHTML("beforeend", data.html);
}
}
root.querySelectorAll("[data-aksrt-shop-orderby]").forEach(function (a) {
a.classList.toggle("is-active", a.getAttribute("data-aksrt-shop-orderby") === state.orderby);
});
if (loadMoreBtn) {
var hasMore = state.page < state.maxPages;
loadMoreBtn.style.display = hasMore ? "" : "none";
loadMoreBtn.disabled = false;
loadMoreBtn.textContent = "加载更多";
}
})
.catch(function () {
state.loading = false;
if (loadMoreBtn) {
loadMoreBtn.disabled = false;
loadMoreBtn.textContent = "加载更多";
}
toast("网络错误");
});
}
root.addEventListener("click", function (e) {
var sort = e.target.closest("[data-aksrt-shop-orderby]");
if (sort && root.contains(sort)) {
e.preventDefault();
var orderby = sort.getAttribute("data-aksrt-shop-orderby") || "date";
if (orderby === state.orderby && state.paging === "ajax") return;
state.orderby = orderby;
state.autoLoads = 0;
try {
var u = new URL(window.location.href);
u.searchParams.set("shop_orderby", orderby);
u.searchParams.delete("paged");
window.history.replaceState({}, "", u.toString());
} catch (err) {}
fetchArchive(1, orderby, true);
return;
}
var more = e.target.closest("[data-aksrt-shop-load-more]");
if (more && root.contains(more)) {
e.preventDefault();
if (state.page >= state.maxPages) return;
fetchArchive(state.page + 1, state.orderby, 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, false);
});
}, { rootMargin: "240px" });
io.observe(loadMoreBtn);
}
})();