feat(pay): sales volume, paid order meta, pending resume, limit-over buy

Bump content sales on resource order paid; show order number/time in download
box; poll pending gateway payments; support download_limit_over_price overbuy.
This commit is contained in:
kate522 committed 2026-07-14 12:04:59 +08:00
1 parent 770205623d
commit 8f15d16d35
8 files changed
+397 -72

No files matched your search

+58 -13
View File
@@ -160,6 +160,12 @@
if (data && data.credits_url) {
extra = '<a class="btn-primary btn-sm" href="' + escapeAttr(data.credits_url) + '">' + tt('my_points', '我的积分') + '</a>';
}
} else if (code === 'aksrt_download_limit') {
title = tt('quota_over', '今日免费额度已用完');
msg = msg || tt('quota_hint', '您今日下载免费资源个数已超限,请明日再下载。');
if (data && data.allow_limit_over && data.post_id) {
extra = '<button type="button" class="btn-primary btn-sm" data-aksrt-open-cashier="' + escapeAttr(data.post_id) + '" data-price-type="download_limit_over">' + tt('buy_over', '立即购买') + '</button>';
}
} else if (code === 'aksrt_captcha_failed') {
title = tt('captcha_fail', '验证失败');
msg = msg || tt('captcha_retry', '人机验证失败,请重试。');
@@ -178,8 +184,9 @@
if (openCashierBtn) {
openCashierBtn.addEventListener('click', function () {
const pid = parseInt(openCashierBtn.getAttribute('data-aksrt-open-cashier'), 10) || 0;
const pt = openCashierBtn.getAttribute('data-price-type') || '';
close();
if (pid) openCashier(pid, returnFocusEl);
if (pid) openCashier(pid, returnFocusEl, pt);
});
}
}
@@ -321,6 +328,29 @@
});
}
function pollOrderPaid(orderNumber, returnFocusEl) {
if (!orderNumber) return;
let tries = 0;
const maxTries = 40;
const timer = setInterval(function () {
tries += 1;
fetch(REST_BASE + '/pay/content/order/' + encodeURIComponent(orderNumber), {
method: 'GET',
credentials: 'same-origin',
headers: restHeaders(),
})
.then(function (resp) { return resp.json().then(function (j) { return { ok: resp.ok, json: j }; }); })
.then(function (r) {
if (r.ok && r.json && r.json.paid) {
clearInterval(timer);
window.location.reload();
}
})
.catch(function () { /* ignore */ });
if (tries >= maxTries) clearInterval(timer);
}, 3000);
}
// ===== 积分不足按钮(前置拦截,不发请求) =====
function showLowCreditModal(button) {
const balance = parseInt(button.getAttribute('data-balance'), 10) || 0;
@@ -336,15 +366,18 @@
};
}
function openCashier(postId, returnFocusEl) {
function openCashier(postId, returnFocusEl, priceType) {
if (!postId) return;
priceType = priceType || '';
open(
'<h3 class="aksrt-dl-modal__title">' + tt('cashier_loading', '确认购买') + '</h3>' +
'<p class="aksrt-dl-modal__msg">' + tt('loading', '加载中…') + '</p>',
returnFocusEl
);
fetch(REST_BASE + '/pay/content/' + postId, {
var previewUrl = REST_BASE + '/pay/content/' + postId;
if (priceType) previewUrl += (previewUrl.indexOf('?') >= 0 ? '&' : '?') + 'price_type=' + encodeURIComponent(priceType);
fetch(previewUrl, {
method: 'GET',
credentials: 'same-origin',
headers: restHeaders(),
@@ -369,7 +402,9 @@
renderError((r.json && r.json.message) || tt('default_err', '请稍后重试'), data, returnFocusEl, code);
return;
}
renderCashier(r.json, returnFocusEl);
var prev = r.json || {};
if (priceType) prev._price_type = priceType;
renderCashier(prev, returnFocusEl);
})
.catch(function () {
renderError(tt('network_err', '网络错误,请稍后重试'), {}, returnFocusEl);
@@ -392,8 +427,15 @@
}
const isPoints = preview.pay_modo === 'points';
const amountLabel = escapeHtml(preview.amount_label || '');
const baseLabel = escapeHtml(preview.base_label || '');
const priceType = (preview._price_type || preview.price_type || '');
let amountLabel = escapeHtml(preview.amount_label || '');
let baseLabel = escapeHtml(preview.base_label || '');
if (priceType === 'download_limit_over' && preview.download_limit_over_label) {
amountLabel = escapeHtml(preview.download_limit_over_label);
baseLabel = amountLabel;
preview.amount = preview.download_limit_over_price;
preview.base = preview.download_limit_over_price;
}
const title = escapeHtml(preview.title || '');
const typeLabel = escapeHtml(preview.pay_type_label || '');
const balance = typeof preview.balance === 'number' ? preview.balance : 0;
@@ -425,7 +467,7 @@
return;
}
body += '<div class="aksrt-dl-modal__actions">';
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="points">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="points" data-price-type="' + escapeAttr(priceType) + '">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
body += '</div>';
} else {
let methodHtml = '';
@@ -438,7 +480,7 @@
body += '<div class="aksrt-cashier__methods"><div class="aksrt-cashier__methods-title">' + tt('pay_method', '支付方式') + '</div>' + methodHtml + '</div>';
}
body += '<div class="aksrt-dl-modal__actions">';
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="cash">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="cash" data-price-type="' + escapeAttr(priceType) + '">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
body += '</div>';
}
@@ -464,6 +506,8 @@
const payload = { mode: mode };
if (mode === 'cash') payload.payment_method = paymentMethod || 'balance';
const pt = button.getAttribute('data-price-type') || '';
if (pt) payload.price_type = pt;
fetch(REST_BASE + '/pay/content/' + postId, {
method: 'POST',
@@ -488,18 +532,18 @@
const data = (r.json && r.json.data) ? r.json.data : r.json;
if (data && data.redirect && (data.payment_url || data.qr_content)) {
if (data.payment_url) {
window.location.href = data.payment_url;
return;
window.open(data.payment_url, '_blank');
}
open(
'<h3 class="aksrt-dl-modal__title">' + tt('scan_pay', '扫码支付') + '</h3>' +
'<p class="aksrt-dl-modal__msg">' + escapeHtml(data.message || tt('scan_hint', '请使用手机扫码完成支付,支付后刷新页面。')) + '</p>' +
'<p class="aksrt-dl-modal__msg"><code>' + escapeHtml(data.qr_content || '') + '</code></p>' +
(data.qr_content ? ('<p class="aksrt-dl-modal__msg"><code>' + escapeHtml(data.qr_content || '') + '</code></p>') : '') +
'<div class="aksrt-dl-modal__actions"><button type="button" class="btn-primary btn-sm" data-aksrt-reload>' + tt('paid_refresh', '我已支付') + '</button></div>',
returnFocusEl
);
const reloadBtn = document.querySelector('[data-aksrt-reload]');
if (reloadBtn) reloadBtn.addEventListener('click', function () { window.location.reload(); });
if (data.order_number) pollOrderPaid(data.order_number, returnFocusEl);
return;
}
window.location.reload();
@@ -530,7 +574,8 @@
'0',
10
);
if (postId) openCashier(postId, buyBtn);
const priceType = buyBtn.getAttribute('data-price-type') || '';
if (postId) openCashier(postId, buyBtn, priceType);
return;
}
@@ -586,7 +631,7 @@
'.resource-download-box__attrs-item{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:#6b7280;}' +
'.resource-download-box__attrs-name{flex:0 0 auto;}' +
'.resource-download-box__attrs-value{color:#111827;text-align:right;}' +
'.resource-download-box__paid-badge{background:#ecfdf5!important;color:#047857!important;}' +
'.resource-download-box__paid-badge{background:#ecfdf5!important;color:#047857!important;}.resource-download-box__paid-meta{display:grid;gap:4px;margin:8px 0 12px;padding:10px 12px;background:#f0fdf4;border:1px solid #bbf7d0;border-radius:10px;font-size:12px;color:#166534;}' +
'@media(max-width:480px){.aksrt-dl-modal__panel{padding:24px 20px 22px;}.aksrt-dl-modal__row{grid-template-columns:1fr 72px;gap:8px 12px;}.aksrt-dl-modal__label{grid-column:1 / -1;}.aksrt-dl-modal__code{font-size:17px;}.aksrt-dl-modal__actions{align-items:flex-start;flex-direction:column;}.aksrt-dl-modal__download{width:100%;}.aksrt-dl-modal__balance{margin-left:0;}}' +
'body.aksrt-dl-modal-open{overflow:hidden;}';
document.head.appendChild(style);