Files
wordpress-theme-aksrt/assets/js/credits.js
T
kate522 fa53a0f4f9 fix(revenue): align detail card, poster modal and copy feedback with reference
- detail-tab 累计佣金 row now shows 累计 + 已提现 (was 累计/可提现/已提现)
- rebuild poster canvas to match reference layout (768×1168, top banner,
  date overlay, blue title bar, bottom bordered box with QR + link)
- copy-link feedback moves from inline text to a toast (notyf), matching
  the reference; drop the now-unused data-affiliate-feedback element
2026-09-28 21:58:43 +08:00

1304 lines
52 KiB
JavaScript
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.
/**
* AKSRT Credits Frontend
*
* 功能:
* - 签到 panel:跳转至全局签到按钮
* - revenue panel:拉取 /revenue/me,复制推广链接
*
* 仅在 page-profile 页面 + 启用积分时加载。
*/
(function () {
'use strict';
var aksrt = window.aksrtData;
if (!aksrt) {
return;
}
var activePoll = null;
function operationKey(owner) {
if (!owner.dataset.aksrtOperationKey) {
owner.dataset.aksrtOperationKey = window.AksrtRequest.createIdempotencyKey();
}
return owner.dataset.aksrtOperationKey;
}
function resetOperationKey(owner) {
delete owner.dataset.aksrtOperationKey;
}
function resetOperationKeyOnChange(owner) {
owner.addEventListener('input', function () { resetOperationKey(owner); });
owner.addEventListener('change', function () { resetOperationKey(owner); });
}
function balanceMinor(value) {
var match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(String(value || '').trim());
if (!match) return null;
return (BigInt(match[1]) * 100n) + BigInt((match[2] || '').padEnd(2, '0') || '0');
}
function api(path, options) {
return window.AksrtRequest.request(path, options || {}).then(function (response) {
return {
ok: response.ok,
status: response.status,
json: response.json || {},
data: response.data,
};
}).catch(function (error) {
var response = error && error.response ? error.response : {};
return {
ok: false,
status: error && error.status ? error.status : (response.status || 0),
json: error && error.json ? error.json : (response.json || { message: error && error.message }),
};
});
}
function applyAssetBalances(data) {
data = data || {};
var wallet = data.wallet_balance !== undefined ? data.wallet_balance : data.wallet;
var points = data.credit_balance !== undefined ? data.credit_balance : data.points_balance;
if (wallet !== undefined && wallet !== null && wallet !== '') {
var walletNumber = Number(wallet);
var walletText = Number.isFinite(walletNumber) ? walletNumber.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : String(wallet);
document.querySelectorAll('[data-aksrt-wallet-value]').forEach(function (element) {
element.textContent = walletText;
element.title = walletText;
});
}
if (points !== undefined && points !== null && points !== '') {
var pointsNumber = Number(points);
var pointsText = Number.isFinite(pointsNumber) ? pointsNumber.toLocaleString() : String(points);
document.querySelectorAll('[data-aksrt-points-value]').forEach(function (element) {
element.textContent = pointsText;
element.title = pointsText;
});
}
}
function refreshAssetBalances(snapshot) {
if (snapshot && (snapshot.wallet_balance !== undefined || snapshot.wallet !== undefined)) {
applyAssetBalances(snapshot);
}
return api('/pay/assets').then(function (response) {
if (!response.ok) return null;
var data = response.data || (response.json && response.json.data) || response.json || {};
applyAssetBalances(data);
return data;
});
}
// Task-list "去签到" → scroll + click the real asset-card sign-in button.
function initSigninGoto() {
document.querySelectorAll('[data-aksrt-signin-goto]').forEach(function (el) {
if (el.dataset.aksrtSigninGotoInitialized === '1') return;
el.dataset.aksrtSigninGotoInitialized = '1';
el.addEventListener('click', function (e) {
e.preventDefault();
var root = document.querySelector('[data-aksrt-signin]');
var btn = root ? root.querySelector('[data-signin-btn]') : null;
if (!btn) return;
try {
if (root && typeof root.scrollIntoView === 'function') {
root.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
} catch (_) {}
if (!btn.disabled) {
btn.click();
} else {
btn.focus();
}
});
});
}
// ===== Forward-only affiliate revenue center =====
/* 推广链接由 PHP 直出,首屏即可见、可复制;这里只补异步才拿得到的
* 海报配置与佣金比例,取失败也不影响复制。 */
function initAffiliateRevenue() {
var root = document.querySelector('[data-aksrt-revenue-page]');
if (!root || root.dataset.affiliateBound) return;
root.dataset.affiliateBound = '1';
var input = root.querySelector('[data-affiliate-link]');
var copy = root.querySelector('[data-affiliate-copy]');
var url = input ? input.value : '';
if (copy) copy.disabled = !url;
api('/revenue/me').then(function (r) {
if (!r.ok) return;
var j = r.json || {};
var ratio = root.querySelector('[data-affiliate-ratio]'); if (ratio) ratio.textContent = String(j.current_ratio || 0) + '%';
initAffiliatePoster(root, url || j.url || '', j.poster || {}, j.site_name || document.title);
}).catch(function () { /* 海报与比例为增强项,静默失败即可。 */ });
if (copy) copy.addEventListener('click', function () {
if (!input || !input.value) return;
var done = function () { notyf('推广链接已复制', 'success', 3, 'aksrt-affiliate-copy-toast'); };
var fail = function () { input.focus(); input.select(); notyf('复制失败,请手动复制', 'danger', 3, 'aksrt-affiliate-copy-toast'); };
if (navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(input.value).then(done).catch(fail);
else { input.focus(); input.select(); try { document.execCommand('copy'); done(); } catch (e) { fail(); } }
});
}
// ===== Referral poster (canvas preview modal: hero image + copy + QR + link) =====
function initAffiliatePoster(root, url, poster, siteName) {
var button = root.querySelector('[data-affiliate-poster]');
var modal = document.querySelector('[data-aksrt-affiliate-poster-modal]');
var stage = document.querySelector('[data-affiliate-poster-stage]');
var download = document.querySelector('[data-affiliate-poster-download]');
if (!button || !modal) return;
if (!url || !poster || poster.enabled !== true) return;
button.hidden = false;
[].forEach.call(modal.querySelectorAll('[data-affiliate-poster-close]'), function (closer) {
closer.addEventListener('click', function () { closeModal(modal); });
});
var canvas = null;
if (download) {
download.addEventListener('click', function () {
if (!canvas) return;
try {
var link = document.createElement('a');
link.download = 'referral-poster.png';
link.href = canvas.toDataURL('image/png');
document.body.appendChild(link);
link.click();
link.remove();
} catch (err) {
/* Canvas is same-origin generated; download can only fail if the browser blocks it. */
}
});
}
button.addEventListener('click', function () {
if (typeof window.qrcode !== 'function') {
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '二维码组件未加载。' + '</p>'; }
openModal(modal);
return;
}
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '正在生成海报…' + '</p>'; }
if (download) download.hidden = true;
openModal(modal);
button.disabled = true;
buildPosterCanvas(url, poster, siteName).then(function (built) {
canvas = built;
if (stage) { stage.innerHTML = ''; stage.appendChild(built); }
if (download) download.hidden = false;
}).catch(function () {
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '海报生成失败,请重试。' + '</p>'; }
}).finally(function () {
button.disabled = false;
});
});
}
// 参考主题 poster-share.js 布局 1:1:768×1168,顶部主图占上半屏,
// 左上角日期,标题竖蓝线 + 标题,正文,底部带边框盒(logo/站名 + 二维码 + 链接)。
function buildPosterCanvas(url, poster, siteName) {
var width = 768, height = 1168;
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, width, height);
var loadImage = null;
if (poster.image) {
loadImage = new Promise(function (resolve) {
var image = new Image();
image.crossOrigin = 'anonymous';
image.onload = function () { resolve(image); };
image.onerror = function () { resolve(null); };
image.src = poster.image;
});
} else {
loadImage = Promise.resolve(null);
}
return loadImage.then(function (image) {
var imgHeight = height / 2; // 参考主题 rebate(非 product):顶部主图占上半屏。
// 顶部主图(cover 裁切)或纯色占位。
if (image && image.width && image.height) {
var rect = coverRect(width, imgHeight, image.width, image.height);
ctx.drawImage(image, rect.sx, rect.sy, rect.sWidth, rect.sHeight, 0, 0, width, imgHeight);
} else {
ctx.fillStyle = '#0f172a';
ctx.fillRect(0, 0, width, imgHeight);
}
// 左上角日期(白字,覆盖在主图上)。
var now = new Date();
var week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
ctx.fillStyle = 'rgba(255,255,255,0.95)';
ctx.font = 'bold 35px Arial, sans-serif';
ctx.fillText(week[now.getDay()], 40, 35);
ctx.font = '28px Arial, sans-serif';
ctx.fillText((now.getMonth() + 1) + ' / ' + now.getDate(), 40, 88);
// 标题竖蓝线。
ctx.strokeStyle = '#00a1ff';
ctx.lineWidth = 7;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(40, imgHeight + 38);
ctx.lineTo(40, imgHeight + 74);
ctx.stroke();
// 标题(粗体,最多 2 行)。
ctx.fillStyle = '#424242';
ctx.font = 'bold 35px Arial, sans-serif';
var titleLines = wrapText(ctx, String(poster.title || siteName || ''), width - 100).slice(0, 2);
var cursorY = imgHeight + 40;
for (var t = 0; t < titleLines.length; t++) {
ctx.fillText(titleLines[t], 60, cursorY);
cursorY += 52;
}
// 正文(简介,最多 3 行)。
var description = String(poster.description || '');
if (description) {
ctx.fillStyle = '#585858';
ctx.font = '25px Arial, sans-serif';
var lines = wrapText(ctx, description, width - 80).slice(0, 3);
var contentY = imgHeight + 160;
for (var i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], 40, contentY);
contentY += 38;
}
}
// 底部带边框盒。
ctx.strokeStyle = 'rgba(122,122,122,0.2)';
ctx.lineWidth = 2;
ctx.strokeRect(30, height - 230, width - 60, 200);
// 站点名(logo 位,左侧)。
ctx.fillStyle = '#424242';
ctx.font = 'bold 30px Arial, sans-serif';
ctx.fillText(String(siteName || ''), 80, height - 175);
ctx.fillStyle = '#94a3b8';
ctx.font = '20px Arial, sans-serif';
ctx.fillText('长按识别二维码访问', 80, height - 130);
// 二维码(右下)。
var qr = window.qrcode(0, 'M');
qr.addData(url);
qr.make();
var count = qr.getModuleCount();
var qrBox = 120;
var cell = qrBox / count;
var qrX = width - 200, qrY = height - 200;
ctx.fillStyle = '#0f172a';
for (var r = 0; r < count; r++) {
for (var c = 0; c < count; c++) {
if (qr.isDark(r, c)) {
ctx.fillRect(qrX + Math.floor(c * cell), qrY + Math.floor(r * cell), Math.ceil(cell), Math.ceil(cell));
}
}
}
// 底部链接(居中)。
ctx.textAlign = 'center';
ctx.fillStyle = '#b4b4b4';
ctx.font = '22px Arial, sans-serif';
ctx.fillText(String(url).slice(0, 46), width / 2, height - 46);
ctx.textAlign = 'left';
return canvas;
});
}
// cover 裁切:把源图按短边铺满目标框并居中裁切。
function coverRect(boxW, boxH, srcW, srcH) {
var sx = 0, sy = 0, sWidth = srcW, sHeight = srcH;
if (srcW / srcH > boxW / boxH) {
sWidth = (boxW * srcH) / boxH;
sx = (srcW - sWidth) / 2;
} else {
sHeight = (boxH * srcW) / boxW;
sy = (srcH - sHeight) / 2;
}
return { sx: sx, sy: sy, sWidth: sWidth, sHeight: sHeight };
}
function wrapText(ctx, text, maxWidth) {
var lines = [];
var current = '';
for (var i = 0; i < text.length; i++) {
if (ctx.measureText(current + text[i]).width > maxWidth && current) {
lines.push(current);
current = text[i];
} else {
current += text[i];
}
}
if (current) lines.push(current);
return lines;
}
window.AKSRTAffiliateRevenueInit = initAffiliateRevenue;
// ===== VIP 开通 =====
function initVipShop() {
var root = document.querySelector('[data-aksrt-vip-shop]');
if (!root) return;
var tip = root.querySelector('[data-aksrt-vip-tip]');
var busy = false;
var coordinator = window.AksrtVipPurchaseCoordinator;
function setTip(text, isError) {
if (!tip) return;
tip.textContent = text || '';
tip.classList.toggle('is-error', !!isError);
}
function selectedMethod() {
var fixed = root.querySelector('[data-aksrt-vip-method-fixed]');
if (fixed && fixed.value) return fixed.value;
var checked = root.querySelector('input[name="aksrt_vip_pay_method"]:checked');
if (checked) return checked.value;
var first = root.querySelector('input[name="aksrt_vip_pay_method"]');
return first ? first.value : 'balance';
}
root.addEventListener('click', function (e) {
var btn = e.target.closest('[data-aksrt-vip-buy]');
if (!btn || busy) return;
e.preventDefault();
var packageId = parseInt(btn.getAttribute('data-package-id') || '0', 10);
if (!packageId) return;
busy = true;
btn.disabled = true;
btn.classList.add('is-loading');
setTip('正在创建订单…');
coordinator.start({
packageId: packageId,
paymentMethod: selectedMethod(),
tags: ['vip', 'orders'],
onPending: function (data) {
busy = false;
btn.disabled = false;
btn.classList.remove('is-loading');
if (data.payment_url) window.open(data.payment_url, '_blank');
setTip(data.message || '请完成支付,支付成功后将自动刷新。');
},
onSuccess: function (result) {
busy = false;
btn.disabled = false;
btn.classList.remove('is-loading');
setTip((result.data && result.data.message) || '开通成功,正在刷新…');
window.location.reload();
},
onFailure: function () {
busy = false;
btn.disabled = false;
btn.classList.remove('is-loading');
setTip('支付未完成,请重试。', true);
},
onTimeout: function () {
busy = false;
btn.disabled = false;
btn.classList.remove('is-loading');
setTip('支付状态暂未确认,请稍后在订单中心查看。', true);
},
onError: function (response) {
busy = false;
btn.disabled = false;
btn.classList.remove('is-loading');
setTip((response.json && response.json.message) || '开通失败', true);
}
});
});
}
// ===== 卡密兑换(三个购买弹窗共用的卡密渠道提交) =====
function redeemCardPass(type, card, password, keyOwner, toastId) {
var body = { password: password, type: type };
if (card) body.card = card;
return api('/pay/card-pass/redeem', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(keyOwner) },
body: JSON.stringify(body)
}).then(function (r) {
if (!r.ok || (r.json && r.json.code && !r.json.success)) {
return { ok: false, message: (r.json && r.json.message) || '兑换失败' };
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(keyOwner);
if (type === 'vip' && window.AksrtModalRuntime && typeof window.AksrtModalRuntime.invalidate === 'function') {
window.AksrtModalRuntime.invalidate(['vip', 'orders']);
}
notyf((data && data.message) || '兑换成功,正在刷新…', 'success', 5, toastId);
window.setTimeout(function () { window.location.reload(); }, 800);
return { ok: true };
}).catch(function () {
return { ok: false, message: '网络错误,请重试' };
});
}
// ===== 余额充值 / 转账 / 余额兑积分 =====
function openModal(el) {
if (!el) return;
el.hidden = false;
el.classList.add('is-open');
document.body.classList.add('uc-modal-open');
}
function closeModal(el) {
if (!el) return;
if (activePoll && typeof activePoll.abort === 'function') {
activePoll.abort();
notyf('已停止查询支付状态', 'warning', 3, 'aksrt-balance-charge-payment-toast');
}
activePoll = null;
el.hidden = true;
el.classList.remove('is-open');
if (!document.querySelector('.uc-modal.is-open')) {
document.body.classList.remove('uc-modal-open');
}
}
function pollPaidOrder(orderNumber, tags) {
var coordinator = window.AksrtVipPurchaseCoordinator;
if (!orderNumber) return;
notyf('等待支付结果…', 'load', '', 'aksrt-balance-charge-payment-toast');
var handle = coordinator.poll(orderNumber, {
tags: tags || ['credits', 'orders'],
onTerminal: function (result) {
activePoll = null;
if (result.success) {
notyf('支付成功,正在刷新…', 'success', 5, 'aksrt-balance-charge-payment-toast');
refreshAssetBalances();
window.setTimeout(function () { window.location.reload(); }, 800);
return;
}
var message = result.data && result.data.message ? result.data.message : '支付未完成,请重试';
notyf(message, 'danger', 5, 'aksrt-balance-charge-payment-toast');
},
onTimeout: function () {
activePoll = null;
notyf('支付状态暂未确认,请稍后在订单中心查看', 'danger', 5, 'aksrt-balance-charge-payment-toast');
}
});
return handle;
}
function initBalanceCharge() {
var modal = document.querySelector('[data-aksrt-charge-modal]');
if (!modal || modal.dataset.aksrtChargeInitialized === '1') return;
modal.dataset.aksrtChargeInitialized = '1';
var form = modal.querySelector('[data-aksrt-charge-form]');
var busy = false;
var chargeBackdrop = null;
// 开关自包含:不复依赖 jQuery/Bootstrap modal 运行时,行为与视觉
// 复刻 Bootstrap 3(.in 显隐 + .modal-backdrop + body.modal-open + ESC)。
function openChargeModal() {
if (modal.classList.contains('in')) return;
// 兼容旧缓存标记(uc-modal 带 hidden 属性)
modal.removeAttribute('hidden');
// 打开态用 flex 而非 block:壳的 .flex.jc 负责双轴居中,
// .modal.flex .modal-dialog{margin:0} 在 block 下会把对话框顶到左上角。
modal.style.display = 'flex';
void modal.offsetWidth; // 强制 reflow,让 .fade 过渡从初始态开始
modal.classList.add('in');
if (!chargeBackdrop) {
chargeBackdrop = document.createElement('div');
chargeBackdrop.className = 'modal-backdrop fade in';
chargeBackdrop.setAttribute('data-aksrt-charge-backdrop', '1');
document.body.appendChild(chargeBackdrop);
}
document.body.classList.add('modal-open');
}
function closeChargeModal() {
if (!modal.classList.contains('in')) return;
if (activePoll && typeof activePoll.abort === 'function') {
activePoll.abort();
notyf('已停止查询支付状态', 'warning', 3, 'aksrt-balance-charge-payment-toast');
}
activePoll = null;
modal.classList.remove('in');
document.body.classList.remove('modal-open');
if (chargeBackdrop && chargeBackdrop.parentNode) {
chargeBackdrop.parentNode.removeChild(chargeBackdrop);
}
chargeBackdrop = null;
// 等过渡结束再撤 display,复刻 Bootstrap 的 fade-out 收尾
window.setTimeout(function () {
if (!modal.classList.contains('in')) {
modal.style.display = '';
}
}, 300);
}
document.querySelectorAll('[data-aksrt-charge-open]').forEach(function (btn) {
btn.addEventListener('click', openChargeModal);
});
modal.addEventListener('click', function (e) {
// 点遮罩层(.modal 自身)或关闭按钮(data-dismiss="modal")
if (e.target === modal || (e.target.closest && e.target.closest('[data-dismiss="modal"]'))) {
closeChargeModal();
}
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && modal.classList.contains('in')) {
closeChargeModal();
}
});
// Zibll data-for/data-value 选中模型:余额档位(.vip-product.product-box)
// 选中变化不产生 change 事件(隐藏 input 由程序赋值),需显式重置幂等键。
var customInput = modal.querySelector('input[name="custom_price"]');
function selectProduct(value) {
modal.querySelectorAll('[data-for="balance_product"]').forEach(function (el) {
el.classList.toggle('active', el.getAttribute('data-value') === value);
});
var hidden = modal.querySelector('input[name="balance_product"]');
if (hidden) hidden.value = value;
// 选中预设档位即代表放弃自定义金额:清空输入框,否则框里残留的数字会在
// 提交时按「合法自定义金额」把 package 顶回 custom,静默覆盖刚点的档位。
if (value !== 'custom' && customInput) {
customInput.value = '';
}
if (form) resetOperationKey(form);
}
modal.querySelectorAll('[data-for="balance_product"]').forEach(function (el) {
el.addEventListener('click', function () {
selectProduct(el.getAttribute('data-value'));
});
});
if (customInput) {
customInput.addEventListener('input', function () {
if (String(customInput.value || '').trim() !== '') {
selectProduct('custom');
}
});
}
// 支付方式(.payment-method-radio);卡密渠道选中时隐藏金额选择、
// 显示卡密输入盒(data-controller="payment_method" 契约与参考主题一致)。
function cardPassBox() {
return modal.querySelector('[data-controller="payment_method"][data-value="card_pass"]');
}
function applyMethodVisibility(value) {
var cardBox = cardPassBox();
if (cardBox) cardBox.style.display = value === 'card_pass' ? '' : 'none';
var chargeBoxes = modal.querySelectorAll('.charge-box');
chargeBoxes.forEach(function (el) { el.style.display = value === 'card_pass' ? 'none' : ''; });
}
function selectMethod(value) {
modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) {
el.classList.toggle('active', el.getAttribute('data-value') === value);
});
var hidden = modal.querySelector('input[name="payment_method"]');
if (hidden) hidden.value = value;
applyMethodVisibility(value);
if (form) resetOperationKey(form);
}
modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) {
el.addEventListener('click', function () {
selectMethod(el.getAttribute('data-value'));
});
});
applyMethodVisibility((modal.querySelector('input[name="payment_method"]') || {}).value || '');
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var methodEl = form.querySelector('input[name="payment_method"]');
var method = methodEl ? methodEl.value : '';
if (!method) {
notyf('暂无可用支付方式', 'danger');
return;
}
if (method === 'card_pass') {
var cardEl = form.querySelector('input[name="card_pass[card]"]');
var pwEl = form.querySelector('input[name="card_pass[password]"]');
var password = pwEl ? String(pwEl.value || '').trim() : '';
if (!password) {
notyf('请输入卡密', 'danger');
if (pwEl) pwEl.focus();
return;
}
busy = true;
notyf('正在兑换…', 'load', '', 'aksrt-balance-charge-toast');
redeemCardPass('balance', cardEl ? String(cardEl.value || '').trim() : '', password, form, 'aksrt-balance-charge-toast')
.then(function (result) {
busy = false;
if (!result.ok) notyf(result.message, 'danger', 5, 'aksrt-balance-charge-toast');
});
return;
}
var pkgInput = form.querySelector('input[name="balance_product"]');
var pkg = pkgInput ? pkgInput.value : 'custom';
var customEl = form.querySelector('input[name="custom_price"]');
var custom = customEl ? String(customEl.value || '').trim() : '';
var validCustom = /^(0|[1-9]\d*)(?:\.\d{1,2})?$/.test(custom) && custom !== '0' && custom !== '0.0' && custom !== '0.00';
if (validCustom) {
pkg = 'custom';
selectProduct('custom');
}
if ((!pkg || pkg === 'custom') && !validCustom) {
notyf('请选择或输入充值金额', 'danger');
return;
}
busy = true;
notyf('正在创建充值订单…', 'load', '', 'aksrt-balance-charge-toast');
api('/pay/balance/charge', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({
package: pkg,
// 预设档位下该字段为空串:服务端仅在 package=custom 时消费它,
// 空串表示「未使用自定义金额」,不是非法值。
custom_price: custom,
payment_method: method
})
}).then(function (r) {
busy = false;
if (!r.ok || (r.json && r.json.code && !r.json.success)) {
notyf((r.json && r.json.message) || '充值失败', 'danger', 5, 'aksrt-balance-charge-toast');
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(form);
if (data && data.redirect && (data.payment_url || data.qr_content)) {
if (data.payment_url) window.open(data.payment_url, '_blank');
notyf(data.message || '请完成支付,支付成功后将自动刷新。', 'info', 5, 'aksrt-balance-charge-toast');
if (data.order_number) activePoll = pollPaidOrder(data.order_number, ['credits', 'orders']);
return;
}
notyf((data && data.message) || '充值成功,正在刷新…', 'success', 5, 'aksrt-balance-charge-toast');
refreshAssetBalances(data);
window.setTimeout(function () { window.location.reload(); }, 800);
}).catch(function () {
busy = false;
notyf('网络错误,请重试', 'danger', 5, 'aksrt-balance-charge-toast');
});
});
}
function initTransfer() {
var modal = document.querySelector('[data-aksrt-transfer-modal]');
if (!modal || modal.dataset.aksrtTransferInitialized === '1') return;
modal.dataset.aksrtTransferInitialized = '1';
var form = modal.querySelector('[data-aksrt-transfer-form]');
var results = modal.querySelector('[data-aksrt-transfer-results]');
var selected = modal.querySelector('[data-aksrt-transfer-selected]');
var recipientInput = modal.querySelector('[data-aksrt-transfer-recipient]');
var typeInput = modal.querySelector('[data-aksrt-transfer-type]');
var title = modal.querySelector('[data-aksrt-transfer-title]');
var amountLabel = modal.querySelector('[data-aksrt-transfer-amount-label]');
var balanceInfo = modal.querySelector('[data-aksrt-transfer-balance-info]');
var pointsInfo = modal.querySelector('[data-aksrt-transfer-points-info]');
var pointsTransferMin = 1;
var searchTimer = null;
var busy = false;
document.querySelectorAll('[data-aksrt-transfer-open]').forEach(function (btn) {
btn.addEventListener('click', function () {
var type = btn.getAttribute('data-aksrt-transfer-open') || 'balance';
pointsTransferMin = type === 'points'
? Math.max(1, parseInt(btn.getAttribute('data-aksrt-transfer-min') || '1', 10) || 1)
: 1;
if (typeInput) typeInput.value = type;
if (title) title.textContent = type === 'points' ? '积分转账' : '余额转账';
var amountEl = form ? form.querySelector('[data-aksrt-transfer-amount]') : null;
if (amountEl) {
amountEl.min = type === 'points' ? String(pointsTransferMin) : '0.01';
amountEl.step = type === 'points' ? '1' : '0.01';
amountEl.inputMode = type === 'points' ? 'numeric' : 'decimal';
amountEl.value = '';
}
if (amountLabel) amountLabel.textContent = type === 'points' ? '积分' : '金额';
if (balanceInfo) balanceInfo.hidden = type === 'points';
if (pointsInfo) pointsInfo.hidden = type !== 'points';
if (results) results.innerHTML = '';
if (selected) selected.textContent = '';
if (recipientInput) recipientInput.value = '';
openModal(modal);
});
});
modal.querySelectorAll('[data-aksrt-transfer-close]').forEach(function (btn) {
btn.addEventListener('click', function () { closeModal(modal); });
});
var searchEl = modal.querySelector('[data-aksrt-transfer-search]');
if (searchEl) {
searchEl.addEventListener('input', function () {
var q = String(searchEl.value || '').trim();
if (searchTimer) clearTimeout(searchTimer);
if (q.length < 1) {
if (results) results.innerHTML = '';
return;
}
searchTimer = setTimeout(function () {
api('/pay/transfer/search?s=' + encodeURIComponent(q)).then(function (r) {
if (!results) return;
results.innerHTML = '';
if (!r.ok) {
notyf((r.json && r.json.message) || '用户搜索失败', 'danger');
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
var users = (data && data.users) || [];
if (!users.length) {
results.innerHTML = '<div class="muted-2-color em09">未找到相关用户</div>';
return;
}
users.forEach(function (u) {
var item = document.createElement('button');
item.type = 'button';
item.className = 'uc-transfer-user';
var avatar = document.createElement('img');
avatar.className = 'uc-transfer-user__avatar';
avatar.alt = '';
avatar.src = String(u.avatar || '');
item.appendChild(avatar);
var displayName = document.createElement('span');
displayName.textContent = String(u.display_name || u.user_login || '');
item.appendChild(displayName);
var login = document.createElement('span');
login.className = 'muted-2-color em09';
login.textContent = '@' + String(u.user_login || '');
item.appendChild(login);
item.addEventListener('click', function () {
if (recipientInput) recipientInput.value = String(u.id);
if (selected) selected.textContent = '已选择:' + (u.display_name || u.user_login);
results.innerHTML = '';
});
results.appendChild(item);
});
});
}, 280);
});
}
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var type = typeInput ? typeInput.value : 'balance';
var recipient = recipientInput ? parseInt(recipientInput.value || '0', 10) : 0;
var amountEl = form.querySelector('[data-aksrt-transfer-amount]');
var amount = amountEl ? amountEl.value : 0;
if (!recipient) {
notyf('请选择收款用户', 'danger');
return;
}
var pointsAmount = /^[1-9]\d*$/.test(String(amount)) ? BigInt(String(amount)) : 0n;
var cashAmount = balanceMinor(amount);
var validAmount = type === 'points'
? pointsAmount >= BigInt(pointsTransferMin) && pointsAmount <= BigInt(Number.MAX_SAFE_INTEGER)
: cashAmount !== null && cashAmount > 0n;
if (!validAmount) {
notyf('请输入有效金额', 'danger');
return;
}
busy = true;
notyf('正在转账…', 'load', '', 'aksrt-balance-transfer-toast');
api('/pay/transfer', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({
type: type,
recipient: recipient,
amount: type === 'points' ? Number(pointsAmount) : String(amount)
})
}).then(function (r) {
busy = false;
if (!r.ok || (r.json && r.json.code && !r.json.success)) {
notyf((r.json && r.json.message) || '转账失败', 'danger', 5, 'aksrt-balance-transfer-toast');
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(form);
notyf((data && data.message) || '转账成功,正在刷新…', 'success', 5, 'aksrt-balance-transfer-toast');
refreshAssetBalances();
window.setTimeout(function () { window.location.reload(); }, 800);
}).catch(function () {
busy = false;
notyf('网络错误,请重试', 'danger', 5, 'aksrt-balance-transfer-toast');
});
});
}
// ===== 购买积分(Zibll points-pay modal 1:1:商品/自定义 + 余额/卡密支付) =====
function initPointsPay() {
var modal = document.querySelector('[data-aksrt-points-pay-modal]');
if (!modal || modal.dataset.aksrtPointsPayInitialized === '1') return;
modal.dataset.aksrtPointsPayInitialized = '1';
var form = modal.querySelector('[data-aksrt-points-pay-form]');
var busy = false;
var backdrop = null;
function openPointsModal() {
if (modal.classList.contains('in')) return;
modal.style.display = 'flex';
void modal.offsetWidth;
modal.classList.add('in');
if (!backdrop) {
backdrop = document.createElement('div');
backdrop.className = 'modal-backdrop fade in';
backdrop.setAttribute('data-aksrt-points-backdrop', '1');
document.body.appendChild(backdrop);
}
document.body.classList.add('modal-open');
}
function closePointsModal() {
if (!modal.classList.contains('in')) return;
modal.classList.remove('in');
document.body.classList.remove('modal-open');
if (backdrop && backdrop.parentNode) backdrop.parentNode.removeChild(backdrop);
backdrop = null;
window.setTimeout(function () {
if (!modal.classList.contains('in')) modal.style.display = '';
}, 300);
}
document.querySelectorAll('[data-aksrt-points-pay-open]').forEach(function (btn) {
btn.addEventListener('click', openPointsModal);
});
modal.addEventListener('click', function (e) {
if (e.target === modal || (e.target.closest && e.target.closest('[data-dismiss="modal"]'))) {
closePointsModal();
}
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && modal.classList.contains('in')) closePointsModal();
});
// Zibll data-for/data-value 选中模型:积分商品档位。
function selectProduct(value) {
modal.querySelectorAll('[data-for="points_product"]').forEach(function (el) {
el.classList.toggle('active', el.getAttribute('data-value') === value);
});
var hidden = modal.querySelector('input[name="points_product"]');
if (hidden) hidden.value = value;
if (form) resetOperationKey(form);
}
modal.querySelectorAll('[data-for="points_product"]').forEach(function (el) {
el.addEventListener('click', function () {
selectProduct(el.getAttribute('data-value'));
});
});
var customInput = modal.querySelector('input[name="points_custom"]');
if (customInput) {
customInput.addEventListener('input', function () {
if (String(customInput.value || '').trim() !== '') selectProduct('custom');
});
}
// 支付方式(余额/卡密);选中卡密时隐藏商品选择、显示卡密输入盒。
function cardPassBox() {
return modal.querySelector('[data-controller="payment_method"][data-value="card_pass"]');
}
function applyMethodVisibility(value) {
var cardBox = cardPassBox();
if (cardBox) cardBox.style.display = value === 'card_pass' ? '' : 'none';
modal.querySelectorAll('.charge-box').forEach(function (el) {
el.style.display = value === 'card_pass' ? 'none' : '';
});
}
function selectMethod(value) {
modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) {
el.classList.toggle('active', el.getAttribute('data-value') === value);
});
var hidden = modal.querySelector('input[name="payment_method"]');
if (hidden) hidden.value = value;
applyMethodVisibility(value);
if (form) resetOperationKey(form);
}
modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) {
el.addEventListener('click', function () {
selectMethod(el.getAttribute('data-value'));
});
});
applyMethodVisibility((modal.querySelector('input[name="payment_method"]') || {}).value || '');
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var methodEl = form.querySelector('input[name="payment_method"]');
var method = methodEl ? methodEl.value : '';
if (!method) {
notyf('暂无可用支付方式', 'danger');
return;
}
if (method === 'card_pass') {
var cardEl = form.querySelector('input[name="card_pass[card]"]');
var pwEl = form.querySelector('input[name="card_pass[password]"]');
var password = pwEl ? String(pwEl.value || '').trim() : '';
if (!password) {
notyf('请输入卡密', 'danger');
if (pwEl) pwEl.focus();
return;
}
busy = true;
notyf('正在兑换…', 'load', '', 'aksrt-balance-points-toast');
redeemCardPass('credits', cardEl ? String(cardEl.value || '').trim() : '', password, form, 'aksrt-balance-points-toast')
.then(function (result) {
busy = false;
if (!result.ok) notyf(result.message, 'danger', 5, 'aksrt-balance-points-toast');
});
return;
}
var pkgInput = form.querySelector('input[name="points_product"]');
var pkg = pkgInput ? pkgInput.value : 'custom';
var customEl = form.querySelector('input[name="points_custom"]');
var custom = customEl ? String(customEl.value || '').trim() : '';
var validCustom = /^[1-9]\d{0,8}$/.test(custom);
if (validCustom) {
pkg = 'custom';
selectProduct('custom');
}
if ((!pkg || pkg === 'custom') && !validCustom) {
notyf('请选择或输入需购买的积分', 'danger');
return;
}
busy = true;
notyf('正在购买积分…', 'load', '', 'aksrt-balance-points-toast');
api('/pay/balance/points-exchange', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({ product: pkg, custom: validCustom ? custom : '0' })
}).then(function (r) {
busy = false;
if (!r.ok || (r.json && r.json.code && !r.json.success)) {
notyf((r.json && r.json.message) || '购买失败', 'danger', 5, 'aksrt-balance-points-toast');
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(form);
notyf((data && data.message) || '购买成功,正在刷新…', 'success', 5, 'aksrt-balance-points-toast');
refreshAssetBalances(data);
window.setTimeout(function () { window.location.reload(); }, 800);
}).catch(function () {
busy = false;
notyf('网络错误,请重试', 'danger', 5, 'aksrt-balance-points-toast');
});
});
}
function initWithdraw() {
var modal = document.querySelector('[data-aksrt-withdraw-modal]');
if (!modal || modal.dataset.aksrtWithdrawInitialized === '1') return;
modal.dataset.aksrtWithdrawInitialized = '1';
var form = modal.querySelector('[data-aksrt-withdraw-form]');
var busy = false;
// 提现来源随打开按钮传入:commission 走佣金池,其余走余额钱包。
// 每个来源的每日次数/额度不同,按钮上带了各自的 min/remaining,
// 打开时覆盖到金额输入框,提交时把 source 一并回传。
document.querySelectorAll('[data-aksrt-withdraw-open]').forEach(function (btn) {
btn.addEventListener('click', function () {
var src = btn.getAttribute('data-aksrt-withdraw-source') || 'balance';
modal.dataset.aksrtWithdrawSource = src === 'commission' ? 'commission' : 'balance';
var amountEl = form ? form.querySelector('[data-aksrt-withdraw-amount]') : null;
if (amountEl) {
var min = btn.getAttribute('data-withdraw-min');
var remAmt = btn.getAttribute('data-withdraw-remaining-amount');
var remCnt = btn.getAttribute('data-withdraw-remaining-count');
if (min !== null) amountEl.setAttribute('data-withdraw-min', min);
if (remAmt !== null) amountEl.setAttribute('data-withdraw-remaining-amount', remAmt);
if (remCnt !== null) amountEl.setAttribute('data-withdraw-remaining-count', remCnt);
}
openModal(modal);
});
});
modal.querySelectorAll('[data-aksrt-withdraw-close]').forEach(function (btn) {
btn.addEventListener('click', function () { closeModal(modal); });
});
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var amountEl = form.querySelector('[data-aksrt-withdraw-amount]');
var methodEl = form.querySelector('[data-aksrt-withdraw-method]');
var accountEl = form.querySelector('[data-aksrt-withdraw-account]');
var rawAmount = amountEl ? String(amountEl.value || '').trim() : '';
var amount = rawAmount;
var amountMinor = balanceMinor(amount);
var minAmount = amountEl ? balanceMinor(amountEl.getAttribute('data-withdraw-min') || '0') : 0n;
var remainingAmount = amountEl ? balanceMinor(amountEl.getAttribute('data-withdraw-remaining-amount') || '0') : 0n;
var remainingCount = amountEl ? Number(amountEl.getAttribute('data-withdraw-remaining-count') || '0') : 0;
var method = methodEl ? methodEl.value : 'alipay';
var account = accountEl ? String(accountEl.value || '').trim() : '';
if (amountMinor === null || amountMinor <= 0n) {
notyf('提现金额必须为最多两位小数的正数', 'danger');
return;
}
if (minAmount === null || amountMinor < minAmount) {
notyf('提现金额低于最低提现门槛', 'danger');
return;
}
if (remainingCount <= 0) {
notyf('当日提现次数已用尽', 'danger');
return;
}
if (remainingAmount === null || amountMinor > remainingAmount) {
notyf('本次提现后将超出单日提现总额上限', 'danger');
return;
}
if (!account) {
notyf('请填写收款账号信息', 'danger');
return;
}
busy = true;
notyf('正在提交提现申请…', 'load', '', 'aksrt-balance-withdraw-toast');
var source = modal.dataset.aksrtWithdrawSource === 'commission' ? 'commission' : 'balance';
api('/earnings/withdrawals', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({ amount: amount, method: method, account: account, source: source })
}).then(function (r) {
busy = false;
if (!r.ok || (r.json && r.json.code && !r.json.success)) {
notyf((r.json && r.json.message) || '提现失败', 'danger', 5, 'aksrt-balance-withdraw-toast');
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(form);
var successMessage = (data && data.message) || '申请已提交';
if (data && data.withdrawal_number) successMessage += '(' + data.withdrawal_number + ')';
notyf(successMessage, 'success', 5, 'aksrt-balance-withdraw-toast');
closeModal(modal);
// 佣金提现刷新推广收益面板,余额提现刷新余额面板;各自拉取对应片段。
var panelName = source === 'commission' ? 'revenue' : 'credits';
var panel = document.getElementById('panel-' + panelName) || (modal.closest ? modal.closest('.dashboard-panel') : null);
var rest = (window.aksrtData && (window.aksrtData.restUrl || window.aksrtData.apiUrl)) || (window.aksrtUserCenter && window.aksrtUserCenter.restUrl) || '';
if (panel && rest) {
fetch(rest.replace(/\/$/, '') + '/user-center/panel/' + panelName, { credentials: 'same-origin', headers: { 'X-WP-Nonce': (window.aksrtData && (window.aksrtData.restNonce || window.aksrtData.nonce)) || '' } })
.then(function (response) { return response.json(); })
.then(function (payload) {
if (!payload || !payload.success || !payload.data || typeof payload.data.html !== 'string') return;
panel.innerHTML = payload.data.html;
if (window.jQuery) jQuery(document).trigger('post_ajax.ed', [panel]);
if (typeof window.auto_fun === 'function') window.auto_fun();
});
}
}).catch(function () {
busy = false;
notyf('网络错误,请重试', 'danger', 5, 'aksrt-balance-withdraw-toast');
});
});
}
function initAssetTabs() {
if (document.documentElement.dataset.aksrtAssetTabsBound === 'true') return;
document.documentElement.dataset.aksrtAssetTabsBound = 'true';
function select(key) {
document.querySelectorAll('.uc-asset-tabs__nav [data-aksrt-asset-tab]').forEach(function (link) {
var li = link.closest('li');
if (!li) return;
var linkKey = link.getAttribute('data-aksrt-asset-tab');
li.classList.toggle('active', linkKey === key || (key === 'points_date' && linkKey === 'points_free'));
});
document.querySelectorAll('[data-aksrt-asset-pane]').forEach(function (pane) {
var active = pane.getAttribute('data-aksrt-asset-pane') === key;
pane.classList.toggle('is-active', active);
pane.hidden = !active;
});
}
function loadPage(key, page) {
var panel = document.querySelector('#panel-credits');
var rest = (window.aksrtData && (window.aksrtData.restUrl || window.aksrtData.apiUrl)) || '';
if (!panel || !rest) return;
panel.classList.add('is-loading');
var url = rest.replace(/\/$/, '') + '/user-center/panel/credits?asset=' + encodeURIComponent(key) + '&page=' + encodeURIComponent(page);
fetch(url, {
credentials: 'same-origin',
headers: { 'X-WP-Nonce': (window.aksrtData && (window.aksrtData.restNonce || window.aksrtData.nonce)) || '' }
}).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('asset-page-load-failed');
panel.innerHTML = payload.data.html;
if (window.jQuery) jQuery(document).trigger('post_ajax.ed', [panel]);
if (typeof window.auto_fun === 'function') window.auto_fun();
select(key);
});
}).catch(function () {
notyf('记录加载失败,请重试', 'danger');
}).finally(function () {
panel.classList.remove('is-loading');
});
}
document.addEventListener('click', function (e) {
var pageButton = e.target.closest('[data-aksrt-asset-page]');
if (pageButton) {
e.preventDefault();
loadPage(pageButton.getAttribute('data-aksrt-asset-key') || 'points', parseInt(pageButton.getAttribute('data-aksrt-asset-page') || '1', 10) || 1);
return;
}
var link = e.target.closest('[data-aksrt-asset-tab]');
if (!link) return;
e.preventDefault();
select(link.getAttribute('data-aksrt-asset-tab'));
});
}
function initWithdrawHistory() {
var modal = document.querySelector('[data-aksrt-withdraw-history-modal]');
if (!modal || modal.dataset.aksrtWithdrawHistoryInitialized === '1') return;
modal.dataset.aksrtWithdrawHistoryInitialized = '1';
var list = modal.querySelector('[data-aksrt-withdraw-history-list]');
var pagination = modal.querySelector('[data-aksrt-withdraw-history-pagination]');
var statusLabels = {
pending: '待处理',
processing: '处理中',
completed: '已完成',
rejected: '已拒绝'
};
var currentPage = 1;
var loading = false;
function text(value) {
return value === null || value === undefined ? '' : String(value);
}
function appendText(parent, value, className) {
var node = document.createElement('span');
if (className) node.className = className;
node.textContent = text(value);
parent.appendChild(node);
return node;
}
function formatGrossAmount(value) {
return text(value).replace(/\.00$/, '');
}
function formatNetAmount(value) {
return text(value);
}
function renderItems(items) {
if (!list) return;
list.textContent = '';
if (!Array.isArray(items) || !items.length) {
var empty = document.createElement('div');
empty.className = 'uc-transactions__empty';
var emptyText = document.createElement('p');
emptyText.textContent = '暂无提现记录';
empty.appendChild(emptyText);
list.appendChild(empty);
return;
}
items.forEach(function (item) {
var status = text(item && item.status).toLowerCase();
var row = document.createElement('div');
row.className = 'uc-withdraw-history__item';
var badge = appendText(row, statusLabels[status] || status, 'badg badg-sm uc-withdraw-history__status');
badge.classList.add(status === 'rejected' ? 'c-red' : (status === 'completed' ? 'c-green' : 'c-blue'));
var gross = text(item && (item.gross_amount || item.amount));
var net = text(item && item.amount);
var amount = document.createElement('span');
amount.className = 'uc-withdraw-history__amount em12';
amount.appendChild(document.createTextNode(formatGrossAmount(gross)));
if (net !== '') {
var netText = document.createElement('span');
netText.className = 'uc-withdraw-history__net';
netText.textContent = '(实际到账:' + formatNetAmount(net) + '元)';
amount.appendChild(netText);
}
row.appendChild(amount);
var number = document.createElement('span');
number.className = 'uc-withdraw-history__number muted-2-color em09';
var numberLabel = document.createElement('span');
numberLabel.textContent = '流水号:';
number.appendChild(numberLabel);
var code = document.createElement('code');
code.textContent = text(item && item.withdrawal_number);
number.appendChild(code);
row.appendChild(number);
appendText(row, text(item && item.created_at), 'uc-withdraw-history__meta muted-2-color em09');
list.appendChild(row);
});
}
function renderPagination(page, maxPages) {
if (!pagination) return;
pagination.textContent = '';
if (maxPages <= 1) return;
function addButton(label, target, disabled, current) {
var button = document.createElement('button');
button.type = 'button';
button.className = 'uc-withdraw-history__page' + (current ? ' is-current' : '');
button.textContent = label;
button.disabled = !!disabled;
if (current) button.setAttribute('aria-current', 'page');
button.dataset.aksrtWithdrawHistoryPage = String(target);
pagination.appendChild(button);
}
addButton('上一页', page - 1, page <= 1, false);
for (var index = 1; index <= maxPages; index += 1) addButton(String(index), index, false, index === page);
addButton('下一页', page + 1, page >= maxPages, false);
}
function loadPage(page) {
if (loading || !list) return;
loading = true;
list.textContent = '加载中…';
var rest = (window.aksrtData && (window.aksrtData.restUrl || window.aksrtData.apiUrl)) || '';
if (!rest) {
list.textContent = '记录加载失败,请重试';
loading = false;
return;
}
var url = rest.replace(/\/$/, '') + '/earnings/withdrawals?page=' + encodeURIComponent(Math.max(1, page)) + '&per_page=10';
fetch(url, {
credentials: 'same-origin',
headers: { 'X-WP-Nonce': (window.aksrtData && (window.aksrtData.restNonce || window.aksrtData.nonce)) || '' }
}).then(function (response) {
return response.json().then(function (payload) {
if (!response.ok || !payload || !Array.isArray(payload.items)) throw new Error('withdraw-history-load-failed');
currentPage = Math.max(1, parseInt(payload.page, 10) || 1);
var maxPages = Math.max(1, parseInt(payload.max_pages, 10) || 1);
renderItems(payload.items);
renderPagination(currentPage, maxPages);
});
}).catch(function () {
list.textContent = '记录加载失败,请重试';
if (pagination) pagination.textContent = '';
}).finally(function () {
loading = false;
});
}
function open() {
modal.hidden = false;
document.body.classList.add('uc-modal-open');
loadPage(1);
}
function close() {
modal.hidden = true;
document.body.classList.remove('uc-modal-open');
}
document.querySelectorAll('[data-aksrt-withdraw-history-open]').forEach(function (btn) {
btn.addEventListener('click', function (e) { e.preventDefault(); open(); });
});
modal.querySelectorAll('[data-aksrt-withdraw-history-close]').forEach(function (btn) {
btn.addEventListener('click', function (e) { e.preventDefault(); close(); });
});
if (pagination) {
pagination.addEventListener('click', function (e) {
var button = e.target.closest('[data-aksrt-withdraw-history-page]');
if (!button || button.disabled) return;
e.preventDefault();
loadPage(parseInt(button.dataset.aksrtWithdrawHistoryPage || '1', 10) || 1);
});
}
}
window.AKSRTWithdrawInit = initWithdraw;
window.AKSRTAssetBalances = {
apply: applyAssetBalances,
refresh: refreshAssetBalances
};
function bootAssets() {
refreshAssetBalances();
initSigninGoto();
initAffiliateRevenue();
initVipShop();
initBalanceCharge();
initTransfer();
initPointsPay();
initWithdraw();
initWithdrawHistory();
initAssetTabs();
}
jQuery(document).off('auto_fun.aksrt-credits').on('auto_fun.aksrt-credits', function () {
bootAssets();
});
})();