fix(orders): load user center assets before panel navigation

This commit is contained in:
2026-08-12 16:48:40 +08:00
parent 01e9a0f4ca
commit 651c5f28f8
5 changed files with 265 additions and 254 deletions
+8 -100
View File
@@ -1,5 +1,5 @@
/**
* Commerce center shared shell (cart / orders / revenue).
* Commerce center shared shell (cart / revenue).
*
* @package AKSRT
*/
@@ -32,8 +32,8 @@
display: inline-flex;
align-items: center;
padding: 6px 12px;
border-radius: 999px;
border: 1px solid var(--color-line, rgba(0, 0, 0, 0.08));
border-radius: 999px;
background: var(--surface-1, #fff);
color: var(--color-ink-2, #4b5563);
font-size: 13px;
@@ -42,14 +42,14 @@
}
.aksrt-commerce-header__nav-item:hover {
color: var(--color-primary, #f04494);
border-color: color-mix(in srgb, var(--color-primary, #f04494) 45%, transparent);
color: var(--color-primary, #f04494);
}
.aksrt-commerce-header__nav-item.is-active {
color: var(--color-on-primary, #fff);
background: var(--color-primary, #f04494);
border-color: transparent;
background: var(--color-primary, #f04494);
color: var(--color-on-primary, #fff);
}
/* Soften revenue dashboard cards — task-first, not ops console */
@@ -60,18 +60,18 @@
.aksrt-revenue-page__stat-card {
padding: 14px 16px !important;
border-radius: 12px !important;
box-shadow: none !important;
border: 1px solid var(--color-line-soft, rgba(0, 0, 0, 0.06)) !important;
border-radius: 12px !important;
background: var(--surface-1, #fff) !important;
box-shadow: none !important;
}
.aksrt-revenue-page__stat-icon {
width: 36px !important;
height: 36px !important;
font-size: 15px !important;
background: var(--body-bg-color, #f5f6f7) !important;
color: var(--color-ink-2, #4b5563) !important;
font-size: 15px !important;
}
.aksrt-revenue-page__stat-value {
@@ -83,98 +83,6 @@
font-size: 12px !important;
}
/* Orders / cart title rhythm when using shared header */
.aksrt-orders-page__header,
.aksrt-cart-page__header > div:first-child {
margin-bottom: 0;
}
.aksrt-orders-page__tabs {
margin-top: 4px;
}
/* After-sale multi-step + coupon wallet */
.aksrt-orders-page__extra-nav {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 0 0 12px;
}
.aksrt-orders-page__extra-link {
padding: 6px 12px;
border-radius: 999px;
background: var(--surface-2, #f3f4f6);
color: inherit;
text-decoration: none;
font-size: 13px;
}
.aksrt-orders-page__extra-link.is-active {
background: var(--focus-color, var(--color-primary));
color: #fff;
}
.aksrt-as-list { display: grid; gap: 12px; }
.aksrt-as-card {
border: 1px solid var(--main-border-color, #eee);
border-radius: 10px;
padding: 14px;
background: var(--main-bg-color, #fff);
}
.aksrt-as-card__head {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin-bottom: 6px;
}
.aksrt-as-card__status {
margin-left: auto;
color: var(--focus-color, #2f6df6);
font-weight: 600;
}
.aksrt-as-timeline {
margin: 10px 0 0;
padding-left: 18px;
color: var(--muted-2-color, #888);
font-size: 12px;
}
.aksrt-as-card__actions {
display: flex;
gap: 8px;
margin-top: 10px;
}
.aksrt-coupon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 12px;
}
.aksrt-coupon-card {
border: 1px dashed var(--focus-color, #2f6df6);
border-radius: 10px;
padding: 12px;
background: color-mix(in srgb, var(--focus-color, #2f6df6) 6%, #fff);
}
.aksrt-coupon-card__value {
font-size: 20px;
font-weight: 700;
color: var(--focus-color, #2f6df6);
}
.aksrt-coupon-card__code {
font-family: ui-monospace, monospace;
margin: 6px 0;
}
.aksrt-coupon-card__meta {
font-size: 12px;
color: var(--muted-2-color, #888);
margin-bottom: 4px;
}
.aksrt-orders-page__field { margin-bottom: 12px; }
.aksrt-orders-page__input,
.aksrt-orders-page__select,
.aksrt-orders-page__textarea {
width: 100%;
box-sizing: border-box;
padding: 8px 10px;
border: 1px solid var(--main-border-color, #ddd);
border-radius: 6px;
}
+25 -9
View File
@@ -47,10 +47,10 @@
.aksrt-orders-page__search { display: flex; gap: 8px; align-items: center; margin: 20px 0 12px; padding: 7px; border: 1px solid var(--orders-line); border-radius: 12px; background: var(--surface-1, #fff); }
.aksrt-orders-page__search > i { margin-left: 7px; color: var(--orders-muted); font-size: 13px; }
.aksrt-orders-page__search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--orders-ink); font-size: 13px; }
.aksrt-orders-page__search button, .aksrt-orders-page__card-actions .btn-primary, .aksrt-orders-page__card-actions .btn-outline, .aksrt-orders-page__card-actions .btn-ghost, .aksrt-orders-page__empty .btn-outline, .aksrt-modal__footer .btn-primary, .aksrt-modal__footer .btn-outline, .aksrt-modal__footer .btn-ghost { display: inline-flex; align-items: center; justify-content: center; min-height: 34px; padding: 0 13px; border-radius: 8px; border: 1px solid transparent; font-size: 12px; font-weight: 650; text-decoration: none; cursor: pointer; }
.aksrt-orders-page .btn-primary, .aksrt-modal__footer .btn-primary { background: var(--color-primary, #3b82f6); color: var(--color-on-primary, #fff); }
.aksrt-orders-page .btn-outline, .aksrt-modal__footer .btn-outline { border-color: var(--orders-line); background: var(--surface-1, #fff); color: var(--orders-ink); }
.aksrt-orders-page .btn-ghost, .aksrt-modal__footer .btn-ghost { background: transparent; color: var(--orders-muted); }
.aksrt-orders-page__search button, .aksrt-orders-page__card-actions .btn-primary, .aksrt-orders-page__card-actions .btn-outline, .aksrt-orders-page__card-actions .btn-ghost, .aksrt-orders-page__empty .btn-outline, .aksrt-order-detail__actions .btn-primary, .aksrt-order-detail__actions .btn-outline, .aksrt-order-detail__actions .btn-ghost { display: inline-flex; align-items: center; justify-content: center; min-height: 34px; padding: 0 13px; border-radius: 8px; border: 1px solid transparent; font-size: 12px; font-weight: 650; text-decoration: none; cursor: pointer; }
.aksrt-orders-page .btn-primary, .aksrt-order-detail__actions .btn-primary { background: var(--color-primary, #3b82f6); color: var(--color-on-primary, #fff); }
.aksrt-orders-page .btn-outline, .aksrt-order-detail__actions .btn-outline { border-color: var(--orders-line); background: var(--surface-1, #fff); color: var(--orders-ink); }
.aksrt-orders-page .btn-ghost, .aksrt-order-detail__actions .btn-ghost { background: transparent; color: var(--orders-muted); }
.aksrt-orders-page__filter-toggle { background: var(--surface-2, #f4f6f9); color: var(--orders-ink); white-space: nowrap; }
.aksrt-orders-page__filter-panel { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: -2px 0 14px; padding: 12px; border-radius: 10px; background: var(--surface-2, #f4f6f9); }
@@ -60,7 +60,7 @@
.aksrt-orders-page__filter-chip.is-active { border-color: var(--color-primary, #3b82f6); background: color-mix(in srgb, var(--color-primary, #3b82f6) 10%, var(--surface-1, #fff)); color: var(--color-primary, #3b82f6); font-weight: 700; }
.aksrt-orders-page__clear { margin-left: auto; color: var(--color-primary, #3b82f6); font-size: 12px; text-decoration: none; }
.aksrt-orders-page__tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin: 0 0 14px; border-bottom: 1px solid var(--orders-line); }
.aksrt-orders-page__tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin: 4px 0 14px; border-bottom: 1px solid var(--orders-line); }
.aksrt-orders-page__tab { position: relative; padding: 11px 8px; color: var(--orders-muted); text-align: center; font-size: 13px; font-weight: 650; text-decoration: none; }
.aksrt-orders-page__tab.is-active { color: var(--orders-ink); }
.aksrt-orders-page__tab.is-active::after { position: absolute; right: 28%; bottom: -1px; left: 28%; height: 2px; border-radius: 2px; background: var(--color-primary, #3b82f6); content: ""; }
@@ -94,9 +94,25 @@
.aksrt-orders-page__empty i { display: block; margin-bottom: 12px; color: var(--color-primary, #3b82f6); font-size: 30px; }
.aksrt-orders-page__empty h3 { margin: 0 0 7px; font-size: 15px; }.aksrt-orders-page__empty p { margin: 0 0 16px; color: var(--orders-muted); font-size: 13px; }
.aksrt-modal__footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; padding: 12px 16px; border-top: 1px solid var(--orders-line); background: var(--surface-2, #f7f8fb); }
.aksrt-order-detail__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; padding: 12px 16px; border-top: 1px solid var(--orders-line); background: var(--surface-2, #f7f8fb); }
.aksrt-order-detail__hero { display: flex; align-items: center; justify-content: space-between; padding: 15px; border-radius: 11px; background: color-mix(in srgb, var(--color-primary, #3b82f6) 9%, var(--surface-2, #f7f8fb)); }.aksrt-order-detail__hero.is-pending { background: color-mix(in srgb, var(--color-warning, #c87819) 11%, var(--surface-2, #f7f8fb)); }.aksrt-order-detail__hero.is-completed { background: color-mix(in srgb, var(--color-success, #168560) 10%, var(--surface-2, #f7f8fb)); }.aksrt-order-detail__status-pill { font-size: 12px; font-weight: 700; }.aksrt-order-detail__hero-amount { font-size: 23px; font-variant-numeric: tabular-nums; }.aksrt-order-detail__product { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 11px; align-items: center; }.aksrt-order-detail__thumb { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; }.aksrt-order-detail__thumb--empty { display: grid; place-items: center; background: var(--surface-2, #f4f6f9); color: var(--color-primary, #3b82f6); }.aksrt-order-detail__product-title { display: block; line-height: 1.4; }.aksrt-order-detail__product-meta { display: block; margin-top: 5px; color: var(--orders-muted); font-size: 12px; }.aksrt-order-detail__list { margin: 0; border: 1px solid var(--orders-line); border-radius: 10px; overflow: hidden; }.aksrt-order-detail__list > div { display: grid; grid-template-columns: 86px minmax(0, 1fr); padding: 10px 12px; border-bottom: 1px solid var(--orders-line); font-size: 12px; }.aksrt-order-detail__list > div:last-child { border-bottom: 0; }.aksrt-order-detail__list dt { color: var(--orders-muted); }.aksrt-order-detail__list dd { margin: 0; overflow-wrap: anywhere; text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 767px) { .uc-orders-panel__head { grid-template-columns: 1fr; gap: 17px; }.aksrt-orders-page__stats { max-width: none; }.aksrt-orders-page__search { flex-wrap: wrap; }.aksrt-orders-page__search input { min-width: 150px; }.aksrt-orders-page__search .btn-primary { margin-left: auto; }.aksrt-orders-page__filter-toggle { margin-left: auto; }.aksrt-orders-page__card-rail time { width: 100%; margin-left: 0; order: 3; }.aksrt-orders-page__card-main { grid-template-columns: 48px minmax(0, 1fr); }.aksrt-orders-page__card-img, .aksrt-orders-page__card-art { width: 48px; height: 48px; }.aksrt-orders-page__card-value { grid-column: 2; text-align: left; }.aksrt-orders-page__card-actions > :not(.aksrt-orders-page__countdown) { flex: 1 1 auto; }.aksrt-orders-page__countdown { width: 100%; }.aksrt-modal__footer > * { flex: 1; } }
@media (prefers-reduced-motion: reduce) { .aksrt-orders-page__card { transition: none; } }
html.dark .aksrt-orders-page__stat, html.dark .aksrt-orders-page__card { background: var(--surface-1, #1a1d24); } html.dark .aksrt-orders-page__card-rail, html.dark .aksrt-orders-page__filter-panel, html.dark .aksrt-modal__footer { background: var(--surface-2, #12151b); }
/* Orders extensions */
.aksrt-orders-page__extra-nav { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.aksrt-orders-page__extra-link { padding: 6px 12px; border-radius: 999px; background: var(--surface-2, #f3f4f6); color: inherit; text-decoration: none; font-size: 13px; }
.aksrt-orders-page__extra-link.is-active { background: var(--focus-color, var(--color-primary)); color: #fff; }
.aksrt-as-list { display: grid; gap: 12px; }
.aksrt-as-card { padding: 14px; border: 1px solid var(--main-border-color, #eee); border-radius: 10px; background: var(--main-bg-color, #fff); }
.aksrt-as-card__head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
.aksrt-as-card__status { margin-left: auto; color: var(--focus-color, #2f6df6); font-weight: 600; }
.aksrt-as-timeline { margin: 10px 0 0; padding-left: 18px; color: var(--muted-2-color, #888); font-size: 12px; }
.aksrt-as-card__actions { display: flex; gap: 8px; margin-top: 10px; }
.aksrt-coupon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.aksrt-coupon-card { padding: 12px; border: 1px dashed var(--focus-color, #2f6df6); border-radius: 10px; background: color-mix(in srgb, var(--focus-color, #2f6df6) 6%, #fff); }
.aksrt-coupon-card__value { color: var(--focus-color, #2f6df6); font-size: 20px; font-weight: 700; }
.aksrt-coupon-card__code { margin: 6px 0; font-family: ui-monospace, monospace; }
.aksrt-coupon-card__meta { margin-bottom: 4px; color: var(--muted-2-color, #888); font-size: 12px; }
.aksrt-orders-page__field { margin-bottom: 12px; }
.aksrt-orders-page__input, .aksrt-orders-page__select, .aksrt-orders-page__textarea { box-sizing: border-box; width: 100%; padding: 8px 10px; border: 1px solid var(--main-border-color, #ddd); border-radius: 6px; }
@media (max-width: 767px) { .uc-orders-panel__head { grid-template-columns: 1fr; gap: 17px; }.aksrt-orders-page__stats { max-width: none; }.aksrt-orders-page__search { flex-wrap: wrap; }.aksrt-orders-page__search input { min-width: 150px; }.aksrt-orders-page__search .btn-primary { margin-left: auto; }.aksrt-orders-page__filter-toggle { margin-left: auto; }.aksrt-orders-page__card-rail time { width: 100%; margin-left: 0; order: 3; }.aksrt-orders-page__card-main { grid-template-columns: 48px minmax(0, 1fr); }.aksrt-orders-page__card-img, .aksrt-orders-page__card-art { width: 48px; height: 48px; }.aksrt-orders-page__card-value { grid-column: 2; text-align: left; }.aksrt-orders-page__card-actions > :not(.aksrt-orders-page__countdown) { flex: 1 1 auto; }.aksrt-orders-page__countdown { width: 100%; }.aksrt-order-detail__actions > * { flex: 1; } }
html.dark .aksrt-orders-page__stat, html.dark .aksrt-orders-page__card { background: var(--surface-1, #1a1d24); } html.dark .aksrt-orders-page__card-rail, html.dark .aksrt-orders-page__filter-panel, html.dark .aksrt-order-detail__actions { background: var(--surface-2, #12151b); }
+164 -122
View File
@@ -3,19 +3,10 @@
*
* @package AKSRT
*/
(function () {
"use strict";
var page = document.querySelector("[data-aksrt-order-center]");
if (!page) return;
if (!window.AksrtModalRuntime.isRolloutEnabled("order")) return;
var detailOrderNumber = "";
var detailAutoRefreshStarted = false;
var detailSession = null;
var detailReplacement = false;
var detailReplacementSession = null;
var instances = new WeakMap();
function toast(message, type) {
window.AksrtToast(message, type || "info");
@@ -50,15 +41,6 @@
: "¥" + amount.toFixed(2);
}
function activeDetail(number) {
return detailOrderNumber === number
&& !!detailSession
&& !detailSession.closed
&& detailSession.options
&& detailSession.options.kind === "orders"
&& window.AksrtModalRuntime.getActive() === detailSession.shell;
}
function orderTag(orderNumber) {
return "order:" + String(orderNumber || "").toLowerCase();
}
@@ -71,6 +53,15 @@
window.AksrtModalRuntime.invalidate(tags);
}
function activeDetail(state, number) {
return state.detailOrderNumber === number
&& !!state.detailSession
&& !state.detailSession.closed
&& state.detailSession.options
&& state.detailSession.options.kind === "orders"
&& window.AksrtModalRuntime.getActive() === state.detailSession.shell;
}
function detailSkeleton() {
return '<div class="aksrt-order-detail__skeleton" aria-live="polite" aria-busy="true">' +
'<span class="aksrt-modal-runtime__skeleton-line is-wide"></span>' +
@@ -79,7 +70,7 @@
'</div>';
}
function renderDetail(order, session) {
function renderDetail(state, order, session) {
var allowedActions = order.allowed_actions || {};
var reconciliation = order.reconciliation || {};
var image = order.image || "";
@@ -112,7 +103,7 @@
session.content.innerHTML = html;
}
function detailOptions(orderNumber, refresh) {
function detailOptions(state, orderNumber, refresh) {
return {
url: orderPath(orderNumber, refresh ? "/refresh" : ""),
method: refresh ? "POST" : "GET",
@@ -124,20 +115,20 @@
cacheTags: ["orders", orderTag(orderNumber)],
skeleton: detailSkeleton(),
onState: function (_, session) {
if (orderNumber === detailOrderNumber) detailSession = session;
if (orderNumber === state.detailOrderNumber) state.detailSession = session;
},
renderData: function (data, session) {
if (orderNumber !== detailOrderNumber) return false;
detailSession = session;
if (orderNumber !== state.detailOrderNumber || !instances.has(state.root)) return false;
state.detailSession = session;
if (!data || typeof data !== "object") {
session.content.innerHTML = '<p class="c-red">订单不存在</p>';
return;
}
renderDetail(data, session);
if (!refresh && !detailAutoRefreshStarted && data.reconciliation && data.reconciliation.state === "refresh_available") {
detailAutoRefreshStarted = true;
renderDetail(state, data, session);
if (!refresh && !state.detailAutoRefreshStarted && data.reconciliation && data.reconciliation.state === "refresh_available") {
state.detailAutoRefreshStarted = true;
window.setTimeout(function () {
if (activeDetail(orderNumber)) refreshDetail(orderNumber);
if (activeDetail(state, orderNumber)) refreshDetail(state, orderNumber);
}, 0);
}
},
@@ -147,27 +138,27 @@
};
}
function openDetail(orderNumber) {
function openDetail(state, orderNumber) {
if (!orderNumber) return;
detailSession = null;
detailReplacement = false;
detailReplacementSession = null;
detailOrderNumber = orderNumber;
detailAutoRefreshStarted = false;
window.AksrtModalRuntime.openRemote(detailOptions(orderNumber, false));
state.detailSession = null;
state.detailReplacement = false;
state.detailReplacementSession = null;
state.detailOrderNumber = orderNumber;
state.detailAutoRefreshStarted = false;
window.AksrtModalRuntime.openRemote(detailOptions(state, orderNumber, false));
}
function refreshDetail(orderNumber) {
if (!orderNumber || !activeDetail(orderNumber)) return;
detailReplacement = true;
detailReplacementSession = detailSession;
var refreshPromise = window.AksrtModalRuntime.openRemote(detailOptions(orderNumber, true));
function refreshDetail(state, orderNumber) {
if (!orderNumber || !activeDetail(state, orderNumber)) return;
state.detailReplacement = true;
state.detailReplacementSession = state.detailSession;
var refreshPromise = window.AksrtModalRuntime.openRemote(detailOptions(state, orderNumber, true));
refreshPromise.then(function () {
detailReplacement = false;
detailReplacementSession = null;
state.detailReplacement = false;
state.detailReplacementSession = null;
}, function () {
detailReplacement = false;
detailReplacementSession = null;
state.detailReplacement = false;
state.detailReplacementSession = null;
});
}
@@ -196,21 +187,21 @@
? '<span class="aksrt-orders-page__countdown" data-aksrt-order-countdown="' + Number(order.time_left) + '"></span>'
: "";
return '<article class="aksrt-orders-page__card" data-aksrt-order-card="' + escapeHtml(order.order_number) + '" data-order-status="' + escapeHtml(order.status_group || "") + '">' +
'<div class="aksrt-orders-page__card-rail"><span>' + escapeHtml(order.product_type_label || "") + '</span><time>' + escapeHtml(order.created_at || "") + '</time><span class="aksrt-orders-page__card-status is-' + escapeHtml(order.status_group || "") + '">' + escapeHtml(order.status_label || "") + '</span></div>' +
'<div class="aksrt-orders-page__card-main">' + image + '<div class="aksrt-orders-page__card-copy"><h3>' + escapeHtml(order.product_name || "订单") + '</h3><p>订单号 ' + escapeHtml(order.order_number) + '</p></div><div class="aksrt-orders-page__card-value"><strong>' + formatMoney(order) + '</strong><span>实付</span></div></div>' +
'<footer class="aksrt-orders-page__card-actions">' + countdown + actionHtml(order) + '</footer></article>';
'<div class="aksrt-orders-page__card-rail"><span>' + escapeHtml(order.product_type_label || "") + '</span><time>' + escapeHtml(order.created_at || "") + '</time><span class="aksrt-orders-page__card-status is-' + escapeHtml(order.status_group || "") + '">' + escapeHtml(order.status_label || "") + "</span></div>" +
'<div class="aksrt-orders-page__card-main">' + image + '<div class="aksrt-orders-page__card-copy"><h3>' + escapeHtml(order.product_name || "订单") + "</h3><p>订单号 " + escapeHtml(order.order_number) + "</p></div><div class=\"aksrt-orders-page__card-value\"><strong>" + formatMoney(order) + "</strong><span>实付</span></div></div>" +
'<footer class="aksrt-orders-page__card-actions">' + countdown + actionHtml(order) + "</footer></article>";
}
function renderStats(stats) {
var root = page.querySelector("[data-aksrt-order-stats]");
function renderStats(state, stats) {
var root = state.root.querySelector("[data-aksrt-order-stats]");
if (!root) return;
root.innerHTML = '<div class="aksrt-orders-page__stat"><span>全部</span><strong>' + Number(stats.total || 0) + '</strong></div>' +
'<div class="aksrt-orders-page__stat"><span>待支付</span><strong class="is-pending">' + Number(stats.pending || 0) + '</strong></div>' +
'<div class="aksrt-orders-page__stat"><span>已生效</span><strong class="is-completed">' + Number(stats.completed || 0) + '</strong></div>';
root.innerHTML = '<div class="aksrt-orders-page__stat"><span>全部</span><strong>' + Number(stats.total || 0) + "</strong></div>" +
'<div class="aksrt-orders-page__stat"><span>待支付</span><strong class="is-pending">' + Number(stats.pending || 0) + "</strong></div>" +
'<div class="aksrt-orders-page__stat"><span>已生效</span><strong class="is-completed">' + Number(stats.completed || 0) + "</strong></div>";
}
function renderPagination(view) {
var existing = page.querySelector(".aksrt-orders-page__pagination");
function renderPagination(state, view) {
var existing = state.root.querySelector(".aksrt-orders-page__pagination");
if (existing) existing.remove();
if (Number(view.total_pages || 1) <= 1) return;
var root = document.createElement("nav");
@@ -225,13 +216,21 @@
link.textContent = String(i);
root.appendChild(link);
}
var list = page.querySelector("[data-aksrt-order-list]");
var list = state.root.querySelector("[data-aksrt-order-list]");
if (list) list.after(root);
}
function renderView(view) {
renderStats(view.stats || {});
var list = page.querySelector("[data-aksrt-order-list]");
function updateCountdowns(state) {
state.root.querySelectorAll("[data-aksrt-order-countdown]").forEach(function (node) {
var value = Math.max(0, Number(node.getAttribute("data-aksrt-order-countdown") || 0) - 1);
node.setAttribute("data-aksrt-order-countdown", String(value));
node.textContent = value ? "剩余支付时间 " + value + " 秒" : "订单即将关闭";
});
}
function renderView(state, view) {
renderStats(state, view.stats || {});
var list = state.root.querySelector("[data-aksrt-order-list]");
if (!list) return;
var items = Array.isArray(view.items) ? view.items : [];
if (!items.length) {
@@ -241,14 +240,14 @@
list.classList.remove("is-empty");
list.innerHTML = items.map(cardHtml).join("");
}
renderPagination(view);
updateCountdowns();
renderPagination(state, view);
updateCountdowns(state);
}
function refreshView() {
function refreshView(state) {
return request(currentViewPath(), undefined, "GET").then(function (result) {
if (!result || !result.data) throw new Error("刷新失败");
renderView(result.data);
renderView(state, result.data);
return result.data;
}).catch(function (error) {
toast(errorMessage(error, "订单状态已变更,请刷新后查看"));
@@ -256,7 +255,7 @@
});
}
function startPayment(button) {
function startPayment(state, button) {
var number = button.getAttribute("data-aksrt-order-pay") || "";
var method = button.getAttribute("data-aksrt-order-method") || "";
if (!number || button.disabled) return;
@@ -269,15 +268,15 @@
return;
}
toast(data.message || "支付成功", "success");
refreshView();
if (activeDetail(number)) openDetail(number);
refreshView(state);
if (activeDetail(state, number)) openDetail(state, number);
}).catch(function (error) {
button.disabled = false;
toast(errorMessage(error, "网络错误,请稍后重试"), "error");
});
}
function closeOrder(button) {
function closeOrder(state, button) {
var number = button.getAttribute("data-aksrt-order-cancel") || "";
if (!number || button.disabled) return;
if (button.getAttribute("data-aksrt-confirm") !== "true") {
@@ -290,8 +289,8 @@
var data = result.data || {};
invalidateOrder(number, data.order);
toast("订单已关闭", "success");
refreshView();
if (activeDetail(number)) openDetail(number);
refreshView(state);
if (activeDetail(state, number)) openDetail(state, number);
}).catch(function (error) {
button.disabled = false;
button.removeAttribute("data-aksrt-confirm");
@@ -300,61 +299,104 @@
});
}
function updateCountdowns() {
page.querySelectorAll("[data-aksrt-order-countdown]").forEach(function (node) {
var value = Math.max(0, Number(node.getAttribute("data-aksrt-order-countdown") || 0) - 1);
node.setAttribute("data-aksrt-order-countdown", String(value));
node.textContent = value ? "剩余支付时间 " + value + " 秒" : "订单即将关闭";
function closest(target, selector) {
return target && target.closest ? target.closest(selector) : null;
}
function initRoot(root) {
if (instances.has(root) || !window.AksrtModalRuntime.isRolloutEnabled("order")) return;
var state = {
root: root,
detailOrderNumber: "",
detailAutoRefreshStarted: false,
detailSession: null,
detailReplacement: false,
detailReplacementSession: null,
countdownTimer: null,
};
state.onRootClick = function (event) {
var filterToggle = closest(event.target, "[data-aksrt-orders-filter-toggle]");
if (filterToggle && root.contains(filterToggle)) {
var panel = root.querySelector("[data-aksrt-orders-filter-panel]");
var expanded = filterToggle.getAttribute("aria-expanded") === "true";
filterToggle.setAttribute("aria-expanded", String(!expanded));
if (panel) panel.hidden = expanded;
return;
}
var detail = closest(event.target, "[data-aksrt-order-detail]");
if (detail && root.contains(detail)) { openDetail(state, detail.getAttribute("data-aksrt-order-detail")); return; }
var pay = closest(event.target, "[data-aksrt-order-pay]");
if (pay && root.contains(pay)) { event.preventDefault(); startPayment(state, pay); return; }
var cancel = closest(event.target, "[data-aksrt-order-cancel]");
if (cancel && root.contains(cancel)) { event.preventDefault(); closeOrder(state, cancel); }
};
state.onModalClose = function (event) {
var detail = event && event.detail ? event.detail : {};
if (!state.detailSession || detail.session !== state.detailSession) return;
if (detail.reason === "replace" && state.detailReplacement && detail.session === state.detailReplacementSession) return;
state.detailSession = null;
state.detailOrderNumber = "";
state.detailAutoRefreshStarted = false;
state.detailReplacement = false;
state.detailReplacementSession = null;
};
state.onDocumentClick = function (event) {
if (!state.detailSession || window.AksrtModalRuntime.getActive() !== state.detailSession.shell) return;
var refresh = closest(event.target, "[data-aksrt-order-refresh]");
if (refresh) {
event.preventDefault();
refreshDetail(state, refresh.getAttribute("data-aksrt-order-refresh") || "");
return;
}
var pay = closest(event.target, "[data-aksrt-order-pay]");
if (pay && !root.contains(pay)) {
event.preventDefault();
startPayment(state, pay);
return;
}
var cancel = closest(event.target, "[data-aksrt-order-cancel]");
if (cancel && !root.contains(cancel)) {
event.preventDefault();
closeOrder(state, cancel);
}
};
root.addEventListener("click", state.onRootClick);
document.addEventListener("aksrt:modal:close", state.onModalClose);
document.addEventListener("click", state.onDocumentClick);
state.countdownTimer = window.setInterval(function () { updateCountdowns(state); }, 1000);
instances.set(root, state);
}
function rootsIn(root) {
if (!root) return [];
var roots = [];
if (root.matches && root.matches("[data-aksrt-order-center]")) roots.push(root);
if (root.querySelectorAll) root.querySelectorAll("[data-aksrt-order-center]").forEach(function (item) { roots.push(item); });
return roots;
}
function init(root) {
rootsIn(root || document).forEach(initRoot);
}
function destroy(root) {
rootsIn(root).forEach(function (item) {
var state = instances.get(item);
if (!state) return;
if (activeDetail(state, state.detailOrderNumber)) window.AksrtModalRuntime.close("replace");
item.removeEventListener("click", state.onRootClick);
document.removeEventListener("aksrt:modal:close", state.onModalClose);
document.removeEventListener("click", state.onDocumentClick);
window.clearInterval(state.countdownTimer);
instances.delete(item);
});
}
page.addEventListener("click", function (event) {
var filterToggle = event.target.closest("[data-aksrt-orders-filter-toggle]");
if (filterToggle) {
var panel = page.querySelector("[data-aksrt-orders-filter-panel]");
var expanded = filterToggle.getAttribute("aria-expanded") === "true";
filterToggle.setAttribute("aria-expanded", String(!expanded));
if (panel) panel.hidden = expanded;
return;
}
var detail = event.target.closest("[data-aksrt-order-detail]");
if (detail) { openDetail(detail.getAttribute("data-aksrt-order-detail")); return; }
var pay = event.target.closest("[data-aksrt-order-pay]");
if (pay) { event.preventDefault(); startPayment(pay); return; }
var cancel = event.target.closest("[data-aksrt-order-cancel]");
if (cancel) { event.preventDefault(); closeOrder(cancel); }
});
document.addEventListener("aksrt:modal:close", function (event) {
var detail = event && event.detail ? event.detail : {};
if (!detailSession || detail.session !== detailSession) return;
if (detail.reason === "replace" && detailReplacement && detail.session === detailReplacementSession) return;
detailSession = null;
detailOrderNumber = "";
detailAutoRefreshStarted = false;
detailReplacement = false;
detailReplacementSession = null;
});
document.addEventListener("click", function (event) {
var refresh = event.target.closest("[data-aksrt-order-refresh]");
if (refresh) {
event.preventDefault();
refreshDetail(refresh.getAttribute("data-aksrt-order-refresh") || "");
return;
}
var pay = event.target.closest("[data-aksrt-order-pay]");
if (pay && !page.contains(pay)) {
event.preventDefault();
startPayment(pay);
return;
}
var cancel = event.target.closest("[data-aksrt-order-cancel]");
if (cancel && !page.contains(cancel)) {
event.preventDefault();
closeOrder(cancel);
}
});
window.setInterval(updateCountdowns, 1000);
window.AKSRTOrderCenter = { init: init, destroy: destroy };
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
window.AksrtFrontend.register("aksrt-order-center", init);
}
init(document);
}());
+9
View File
@@ -77,6 +77,9 @@
if (target._aksrtPanelRequest) return target._aksrtPanelRequest;
var restUrl = (window.aksrtData && (window.aksrtData.restUrl || window.aksrtData.apiUrl)) || cfg.restUrl || '';
if (!restUrl) return Promise.reject(new Error('rest-unavailable'));
if (name === 'orders' && (!window.AKSRTOrderCenter || typeof window.AKSRTOrderCenter.init !== 'function')) {
return Promise.reject(new Error('orders-initializer-unavailable'));
}
target.classList.add('is-loading');
var url = restUrl.replace(/\/$/, '') + '/user-center/panel/' + encodeURIComponent(name);
if (name === 'creator') {
@@ -91,7 +94,13 @@
}).then(function(response) {
return response.json().then(function(payload) {
if (!response.ok || !payload || !payload.success || !payload.data || typeof payload.data.html !== 'string') throw new Error('panel-load-failed');
if (name === 'orders' && window.AKSRTOrderCenter && typeof window.AKSRTOrderCenter.destroy === 'function') {
window.AKSRTOrderCenter.destroy(target);
}
target.innerHTML = payload.data.html;
if (window.AksrtFrontend && typeof window.AksrtFrontend.rehydrate === 'function') {
window.AksrtFrontend.rehydrate(target, 'ajax');
}
target.dataset.panelLoaded = 'true';
});
}).finally(function() {
+59 -23
View File
@@ -462,6 +462,36 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js';
['aksrt-route-profile'],
file_exists($user_center_css_path) ? (string) filemtime($user_center_css_path) : $version
);
// Orders is a lazy user-center panel, so its independent assets must
// be ready before client-side panel replacement can insert its markup.
$has_orders_panel = false;
if (class_exists('\AKSRT\User\Center')) {
$dashboard_tabs = \AKSRT\User\Center::get_instance()->get_dashboard_tabs();
$has_orders_panel = isset($dashboard_tabs['orders']);
}
if ($has_orders_panel) {
$orders_css = get_template_directory() . '/assets/css/routes/orders.css';
if (file_exists($orders_css)) {
wp_enqueue_style(
'aksrt-orders',
$base_uri . '/assets/css/routes/orders.css',
['aksrt-tokens'],
(string) filemtime($orders_css)
);
}
$order_center_js = get_template_directory() . '/assets/js/order-center.js';
if (file_exists($order_center_js)) {
wp_enqueue_script(
'aksrt-order-center',
$base_uri . '/assets/js/order-center.js',
['aksrt-script', 'aksrt-rehydrate', 'aksrt-core-request', 'aksrt-core-modal-runtime'],
(string) filemtime($order_center_js),
true
);
}
}
$identity_js = get_template_directory() . '/assets/js/routes/user-center-auth.js';
if (file_exists($identity_js)) {
wp_enqueue_script(
@@ -472,10 +502,16 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js';
true
);
}
$user_center_deps = file_exists($identity_js)
? ['aksrt-script', 'aksrt-route-user-center-auth']
: ['aksrt-script'];
if ($has_orders_panel && wp_script_is('aksrt-order-center', 'registered')) {
$user_center_deps[] = 'aksrt-order-center';
}
wp_enqueue_script(
'aksrt-route-user-center',
$base_uri . '/assets/js/routes/user-center.js',
file_exists($identity_js) ? ['aksrt-script', 'aksrt-route-user-center-auth'] : ['aksrt-script'],
$user_center_deps,
file_exists(get_template_directory() . '/assets/js/routes/user-center.js')
? (string) filemtime(get_template_directory() . '/assets/js/routes/user-center.js')
: $version,
@@ -671,30 +707,30 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js';
}
}
// 订单中心:独立页 / 虚拟 rewrite / 用户中心 tab=orders
// 订单中心:独立页 / 虚拟 rewrite;用户中心在上方按可用 tab 预载。
$is_orders_surface = is_page_template('templates/pages/page-orders.php')
|| (bool) get_query_var('aksrt_orders')
|| (
(function_exists('aksrt_is_user_center_page') && aksrt_is_user_center_page())
&& isset($_GET['tab'])
&& sanitize_key((string) wp_unslash($_GET['tab'])) === 'orders'
);
|| (bool) get_query_var('aksrt_orders');
if ($is_orders_surface) {
wp_enqueue_style(
'aksrt-orders',
$base_uri . '/assets/css/routes/orders.css',
['aksrt-tokens'],
$version
);
wp_enqueue_script(
'aksrt-order-center',
$base_uri . '/assets/js/order-center.js',
['aksrt-script', 'aksrt-core-request', 'aksrt-core-modal-runtime'],
file_exists(get_template_directory() . '/assets/js/order-center.js')
? (string) filemtime(get_template_directory() . '/assets/js/order-center.js')
: $version,
true
);
$orders_css = get_template_directory() . '/assets/css/routes/orders.css';
if (file_exists($orders_css)) {
wp_enqueue_style(
'aksrt-orders',
$base_uri . '/assets/css/routes/orders.css',
['aksrt-tokens'],
(string) filemtime($orders_css)
);
}
$order_center_js = get_template_directory() . '/assets/js/order-center.js';
if (file_exists($order_center_js)) {
wp_enqueue_script(
'aksrt-order-center',
$base_uri . '/assets/js/order-center.js',
['aksrt-script', 'aksrt-rehydrate', 'aksrt-core-request', 'aksrt-core-modal-runtime'],
(string) filemtime($order_center_js),
true
);
}
}
// 收益中心:旧路由重定向页 / 用户中心 tab=revenue。