Merge pull request 'fix(orders): load user center assets before panel navigation' (#1) from worktree-fix-user-center-orders-assets into main
Reviewed-on: #1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}());
|
||||
|
||||
@@ -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
@@ -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。
|
||||
|
||||
Reference in New Issue
Block a user