CaiWuXiTong/resources/assets/js/views/business/marketing-account-bills.js
WuYongJie 28a62434d2 整合并修正京东钱包账单 (#26)
接入京东充值与消耗账单,修复快照冷启动、刷新依赖、日期边界与标签局部切换。
2026-08-11 12:22:41 +08:00

207 lines
6.6 KiB
JavaScript
Vendored
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 营销账户账单页面的服务端局部导航。
*
* 链接始终保留完整 href 作为渐进增强回退;普通左键操作只替换当前
* 工作区并同步 History,避免平台标签、京东账单类型、筛选和分页触发整页刷新。
*/
(function () {
const workspaceSelector = '[data-marketing-account-bills-workspace]';
const pagePathMarker = '/workspace/billing-transactions/marketing-account-bills';
let activeRequest = null;
function currentWorkspace() {
return document.querySelector(workspaceSelector);
}
function isSupportedUrl(url) {
const target = new URL(url, window.location.origin);
return target.origin === window.location.origin
&& target.pathname.indexOf(pagePathMarker) !== -1;
}
function updateHeader(nextDocument) {
const currentHeader = document.querySelector('[data-page-title-first]');
const nextHeader = nextDocument.querySelector('[data-page-title-first]');
if (currentHeader && nextHeader) {
currentHeader.innerHTML = nextHeader.innerHTML;
}
if (nextDocument.title) {
document.title = nextDocument.title;
}
}
function setLoading(workspace, loading) {
const status = workspace.querySelector('[data-marketing-account-bills-status]');
if (loading) {
workspace.setAttribute('aria-busy', 'true');
if (status) {
status.textContent = '正在加载账单数据';
}
} else {
workspace.removeAttribute('aria-busy');
}
}
function showError(workspace, url) {
const error = workspace.querySelector('[data-marketing-account-bills-navigation-error]');
const status = workspace.querySelector('[data-marketing-account-bills-status]');
setLoading(workspace, false);
if (status) {
status.textContent = '账单内容加载失败';
}
if (error) {
const retry = error.querySelector('[data-marketing-account-bills-retry]');
error.hidden = false;
if (retry) {
retry.href = url;
}
}
}
function initialiseInsertedContent(workspace) {
if (window.Alpine && typeof window.Alpine.initTree === 'function') {
window.Alpine.initTree(workspace);
}
}
async function navigate(url, options) {
const settings = Object.assign({ pushState: true, focus: null }, options || {});
const workspace = currentWorkspace();
if (!workspace || !isSupportedUrl(url)) {
return false;
}
if (activeRequest) {
activeRequest.abort();
}
const request = new AbortController();
activeRequest = request;
setLoading(workspace, true);
try {
const response = await window.fetch(url, {
credentials: 'same-origin',
headers: {
Accept: 'text/html',
'X-Requested-With': 'XMLHttpRequest',
},
signal: request.signal,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const html = await response.text();
const nextDocument = new DOMParser().parseFromString(html, 'text/html');
const nextWorkspace = nextDocument.querySelector(workspaceSelector);
if (!nextWorkspace) {
throw new Error('目标页面缺少营销账单工作区');
}
const importedWorkspace = document.importNode(nextWorkspace, true);
workspace.replaceWith(importedWorkspace);
initialiseInsertedContent(importedWorkspace);
updateHeader(nextDocument);
const target = new URL(url, window.location.origin);
const relativeUrl = `${target.pathname}${target.search}${target.hash}`;
if (settings.pushState && relativeUrl !== `${window.location.pathname}${window.location.search}${window.location.hash}`) {
window.history.pushState({ marketingAccountBills: true }, '', relativeUrl);
}
if (settings.focus) {
const focusTarget = importedWorkspace.querySelector(settings.focus);
if (focusTarget) {
window.requestAnimationFrame(() => focusTarget.focus({ preventScroll: true }));
}
}
return true;
} catch (error) {
if (error.name !== 'AbortError') {
showError(workspace, url);
}
return false;
} finally {
if (activeRequest === request) {
activeRequest = null;
}
}
}
document.addEventListener('click', (event) => {
const link = event.target.closest(
`${workspaceSelector} .business-tab-link, `
+ `${workspaceSelector} [data-jd-wallet-navigation], `
+ `${workspaceSelector} .jd-wallet-pagination a`
);
if (!link
|| link.hasAttribute('data-marketing-account-bills-full-page')
|| event.button !== 0
|| event.metaKey
|| event.ctrlKey
|| event.shiftKey
|| event.altKey
|| link.target === '_blank'
) {
return;
}
if (!isSupportedUrl(link.href)) {
return;
}
event.preventDefault();
event.stopPropagation();
const focusSelector = link.classList.contains('marketing-bills-subtab')
? '.marketing-bills-subtab.is-active'
: '.business-tab-link.is-active';
navigate(link.href, { focus: focusSelector });
}, true);
document.addEventListener('submit', (event) => {
const form = event.target.closest(`${workspaceSelector} [data-jd-wallet-filter]`);
if (!form) {
return;
}
event.preventDefault();
const target = new URL(form.action, window.location.origin);
new FormData(form).forEach((value, key) => {
const normalized = String(value).trim();
if (normalized === '') {
target.searchParams.delete(key);
} else {
target.searchParams.set(key, normalized);
}
});
target.searchParams.delete('page');
navigate(target.href, { focus: '#jd-filter-store' });
}, true);
window.addEventListener('popstate', () => {
if (currentWorkspace() && isSupportedUrl(window.location.href)) {
navigate(window.location.href, { pushState: false });
}
});
}());