积分与余额账务系统硬切重构

This commit is contained in:
kate522 committed 2026-08-24 15:59:11 +08:00
1 parent ca12226b39
commit 5cae5b5c93
159 files changed
+7275 -4718

No files matched your search

+16 -10
View File
@@ -150,7 +150,7 @@
if (data && data.vip_url) {
extra = '<a class="btn-primary btn-sm" href="' + escapeAttr(data.vip_url) + '">' + tt('go_vip', '开通会员') + '</a>';
}
} else if (code === 'aksrt_credits_insufficient' || code === 'aksrt_balance_insufficient') {
} else if (code === 'aksrt_points_insufficient' || code === 'aksrt_balance_insufficient') {
title = tt('credit_low', '积分不够');
const balance = typeof (data && data.balance) === 'number' ? data.balance : 0;
const cost = typeof (data && data.cost) === 'number' ? data.cost : 0;
@@ -355,15 +355,17 @@
function showLowCreditModal(button) {
const balance = parseInt(button.getAttribute('data-balance'), 10) || 0;
const cost = parseInt(button.getAttribute('data-cost'), 10) || 0;
renderError('', { balance: balance, cost: cost }, button, 'aksrt_credits_insufficient');
renderError('', { balance: balance, cost: cost }, button, 'aksrt_points_insufficient');
}
// ===== 收银台(内容购买) =====
function restHeaders() {
return {
function restHeaders(idempotencyKey) {
const headers = {
'Content-Type': 'application/json',
'X-WP-Nonce': window.aksrtData.restNonce || '',
};
if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;
return headers;
}
function payApiBase(apiKind) {
@@ -467,7 +469,7 @@
}
const title = escapeHtml(preview.title || '');
const typeLabel = escapeHtml(preview.pay_type_label || '');
const balance = typeof preview.balance === 'number' ? preview.balance : 0;
const balance = isPoints && Number.isSafeInteger(preview.balance) ? preview.balance : 0;
const methods = Array.isArray(preview.payment_methods) ? preview.payment_methods : [];
const couponAllowed = !isPoints && !!preview.coupon_allowed;
const couponCodeVal = escapeAttr(preview.coupon_code || preview._coupon_code || '');
@@ -477,7 +479,7 @@
priceRows += '<div class="aksrt-cashier__row"><span>' + tt('price', '价格') + '</span><b>' + baseLabel + '</b></div>';
}
// VIP list price row when VIP reduced list amount.
if (typeof preview.list_amount === 'number' && typeof preview.base === 'number' && preview.list_amount !== preview.base) {
if (preview.list_amount !== preview.base) {
priceRows += '<div class="aksrt-cashier__row"><span>' + tt('vip_price', '会员价') + '</span><b class="is-sale">' + listLabel + '</b></div>';
} else if (preview.amount !== preview.base && !preview.rebate_discount && !preview.coupon_discount) {
priceRows += '<div class="aksrt-cashier__row"><span>' + tt('vip_price', '会员价') + '</span><b class="is-sale">' + amountLabel + '</b></div>';
@@ -527,12 +529,12 @@
}
body += '</div>';
}
const walletBal = typeof preview.wallet_balance === 'number'
const walletBal = typeof preview.wallet_balance === 'string'
? preview.wallet_balance
: (typeof preview.balance === 'number' ? preview.balance : 0);
: (typeof preview.balance === 'string' ? preview.balance : '0.00');
const hasBalanceMethod = methods.some(function (m) { return (m && m.id) === 'balance'; });
if (hasBalanceMethod) {
body += '<div class="aksrt-cashier__box"><div class="aksrt-cashier__row"><span>' + tt('my_wallet', '我的余额') + '</span><b class="is-ok">¥' + Number(walletBal).toFixed(2) + '</b></div></div>';
body += '<div class="aksrt-cashier__box"><div class="aksrt-cashier__row"><span>' + tt('my_wallet', '我的余额') + '</span><b class="is-ok">¥' + escapeHtml(walletBal) + '</b></div></div>';
if (preview.balance_enough === false) {
body += '<div class="aksrt-cashier__warn">' + tt('wallet_short', '余额不足,请先充值或选择其他支付方式') + '</div>';
if (preview.credits_url) {
@@ -621,10 +623,13 @@
if (pt) payload.price_type = pt;
if (mode === 'cash' && couponCode) payload.coupon_code = couponCode;
if (!button.dataset.aksrtOperationKey) {
button.dataset.aksrtOperationKey = window.AksrtRequest.createIdempotencyKey();
}
fetch(REST_BASE + payApiBase(apiKind) + postId, {
method: 'POST',
credentials: 'same-origin',
headers: restHeaders(),
headers: restHeaders(button.dataset.aksrtOperationKey),
body: JSON.stringify(payload),
})
.then(function (resp) { return resp.json().then(function (j) { return { ok: resp.ok, status: resp.status, json: j }; }); })
@@ -642,6 +647,7 @@
return;
}
const data = (r.json && r.json.data) ? r.json.data : r.json;
delete button.dataset.aksrtOperationKey;
if (data && data.redirect && (data.payment_url || data.qr_content)) {
if (data.payment_url) {
window.open(data.payment_url, '_blank');
+18
View File
@@ -13,6 +13,23 @@
return window.aksrtData || window.aksrt || {};
}
function createIdempotencyKey() {
if (window.crypto && typeof window.crypto.randomUUID === "function") {
return window.crypto.randomUUID();
}
if (!window.crypto || typeof window.crypto.getRandomValues !== "function") {
throw new Error("当前浏览器无法生成安全的操作标识");
}
var bytes = new Uint8Array(16);
window.crypto.getRandomValues(bytes);
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
var hex = Array.prototype.map.call(bytes, function (value) {
return value.toString(16).padStart(2, "0");
}).join("");
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
}
function restBase() {
var config = data();
var raw = config.restUrl || config.apiUrl || config.rest_url || "";
@@ -144,6 +161,7 @@
window.AksrtRequest = {
url: url,
request: request,
createIdempotencyKey: createIdempotencyKey,
get: function (path, options) {
return request(path, Object.assign({}, options || {}, { method: "GET" }));
},
+71 -21
View File
@@ -16,6 +16,28 @@
}
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 {
@@ -218,6 +240,7 @@
Array.prototype.forEach.call(roots, function (root) {
var tip = root.querySelector('[data-aksrt-card-tip]');
var busy = false;
resetOperationKeyOnChange(root);
function setTip(text, isError) {
if (!tip) return;
@@ -255,6 +278,7 @@
api('/pay/card-pass/redeem', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(root) },
body: JSON.stringify(body)
}).then(function (r) {
busy = false;
@@ -264,6 +288,7 @@
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(root);
if (type === 'vip' && window.AksrtModalRuntime && typeof window.AksrtModalRuntime.invalidate === 'function') {
window.AksrtModalRuntime.invalidate(['vip', 'orders']);
}
@@ -278,7 +303,7 @@
});
}
// ===== 余额充值 / 转账 / 积分兑余额(legacy 资产中心) =====
// ===== 余额充值 / 转账 / 余额兑积分 =====
function openModal(el) {
if (!el) return;
el.hidden = false;
@@ -344,21 +369,23 @@
});
});
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var pkgInput = form.querySelector('input[name="balance_package"]:checked') || form.querySelector('input[name="balance_package"]');
var pkg = pkgInput ? pkgInput.value : 'custom';
var customEl = form.querySelector('input[name="custom_price"]');
var custom = customEl ? parseFloat(customEl.value || '0') : 0;
if (custom > 0) {
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';
}
if ((!pkg || pkg === 'custom') && !(custom > 0) && !pkgInput) {
if ((!pkg || pkg === 'custom') && !validCustom && !pkgInput) {
notyf('请选择或输入充值金额', 'danger');
return;
}
if (pkg === 'custom' && !(custom > 0)) {
if (pkg === 'custom' && !validCustom) {
notyf('请输入有效充值金额', 'danger');
return;
}
@@ -368,6 +395,7 @@
notyf('正在创建充值订单…', 'load', '', 'aksrt-balance-charge-toast');
api('/pay/balance/charge', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({
package: pkg,
custom_price: custom,
@@ -380,6 +408,7 @@
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');
@@ -478,6 +507,7 @@
});
}
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
@@ -489,7 +519,12 @@
notyf('请选择收款用户', 'danger');
return;
}
if (!(parseFloat(amount) > 0) || (type === 'points' && (!Number.isInteger(Number(amount)) || Number(amount) < pointsTransferMin))) {
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;
}
@@ -497,7 +532,12 @@
notyf('正在转账…', 'load', '', 'aksrt-balance-transfer-toast');
api('/pay/transfer', {
method: 'POST',
body: JSON.stringify({ type: type, recipient: recipient, amount: amount })
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)) {
@@ -505,6 +545,7 @@
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');
window.setTimeout(function () { window.location.reload(); }, 800);
}).catch(function () {
@@ -529,12 +570,15 @@
btn.addEventListener('click', function () { closeModal(modal); });
});
if (!form) return;
resetOperationKeyOnChange(form);
function updatePreview() {
if (!preview || !amountEl) return;
var amount = Number(amountEl.value || '0');
var rate = Number(amountEl.getAttribute('data-aksrt-points-exchange-rate') || '0');
preview.textContent = Number.isInteger(amount) && amount > 0 && rate > 0
? '预计获得 ' + (amount * rate) + ' 积分'
var amount = balanceMinor(amountEl.value);
var rateRaw = amountEl.getAttribute('data-aksrt-points-exchange-rate') || '';
var rate = /^[1-9]\d*$/.test(rateRaw) ? BigInt(rateRaw) : 0n;
var scaled = amount !== null ? amount * rate : 0n;
preview.textContent = amount !== null && amount > 0n && rate > 0n && scaled % 100n === 0n
? '预计获得 ' + String(scaled / 100n) + ' 积分'
: '';
}
amountEl.addEventListener('input', updatePreview);
@@ -542,15 +586,16 @@
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
var amount = amountEl ? Number(amountEl.value || '0') : 0;
if (!Number.isInteger(amount) || !(amount > 0)) {
notyf('请输入正整数余额', 'danger');
var amount = amountEl ? String(amountEl.value || '').trim() : '';
if (!/^(0|[1-9]\d*)(?:\.\d{1,2})?$/.test(amount) || /^0(?:\.0{1,2})?$/.test(amount)) {
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({ amount: amount })
}).then(function (r) {
busy = false;
@@ -559,6 +604,7 @@
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');
window.setTimeout(function () { window.location.reload(); }, 800);
}).catch(function () {
@@ -581,6 +627,7 @@
btn.addEventListener('click', function () { closeModal(modal); });
});
if (!form) return;
resetOperationKeyOnChange(form);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (busy) return;
@@ -588,17 +635,18 @@
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 ? Number(rawAmount) : 0;
var minAmount = amountEl ? Number(amountEl.getAttribute('data-withdraw-min') || '0') : 0;
var remainingAmount = amountEl ? Number(amountEl.getAttribute('data-withdraw-remaining-amount') || '0') : 0;
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 (!Number.isInteger(amount) || !(amount > 0)) {
notyf('提现金额必须为正整数', 'danger');
if (amountMinor === null || amountMinor <= 0n) {
notyf('提现金额必须为最多两位小数的正数', 'danger');
return;
}
if (amount < minAmount) {
if (minAmount === null || amountMinor < minAmount) {
notyf('提现金额低于最低提现门槛', 'danger');
return;
}
@@ -606,7 +654,7 @@
notyf('当日提现次数已用尽', 'danger');
return;
}
if (amount > remainingAmount) {
if (remainingAmount === null || amountMinor > remainingAmount) {
notyf('本次提现后将超出单日提现总额上限', 'danger');
return;
}
@@ -618,6 +666,7 @@
notyf('正在提交提现申请…', 'load', '', 'aksrt-balance-withdraw-toast');
api('/earnings/withdrawals', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
body: JSON.stringify({ amount: amount, method: method, account: account })
}).then(function (r) {
busy = false;
@@ -626,6 +675,7 @@
return;
}
var data = (r.json && r.json.data) ? r.json.data : r.json;
resetOperationKey(form);
notyf((data && data.message) || '申请已提交', 'success', 5, 'aksrt-balance-withdraw-toast');
closeModal(modal);
var panel = modal.closest ? modal.closest('.dashboard-panel') : null;
+33 -16
View File
@@ -8,9 +8,10 @@
var instances = new WeakMap();
function request(path, body, method) {
function request(path, body, method, operationKey) {
var options = { method: method || "POST" };
if (body !== undefined) options.body = JSON.stringify(body || {});
if (operationKey) options.headers = { "Idempotency-Key": operationKey };
return window.AksrtRequest.request(path, options);
}
@@ -30,12 +31,15 @@
.replace(/'/g, "&#39;");
}
function formatMoney(order) {
var amount = Number(order && order.amount || 0);
return order && order.is_points
? escapeHtml(order.currency_symbol || "积分") + " " + Math.round(amount)
: "¥" + amount.toFixed(2);
}
function formatMoney(order) {
var raw = String(order && order.amount != null ? order.amount : "0");
if (order && order.is_points) {
return escapeHtml(order.currency_symbol || "积分") + " " + (/^\d+$/.test(raw) ? raw : "0");
}
var match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(raw);
var amount = match ? match[1] + "." + (match[2] || "").padEnd(2, "0") : "0.00";
return "¥" + amount;
}
function orderTag(orderNumber) {
return "order:" + String(orderNumber || "").toLowerCase();
@@ -100,9 +104,12 @@
}
function detailOptions(state, orderNumber, refresh) {
var actionKey = refresh ? "refresh:" + orderNumber : "";
if (actionKey && !state.operationKeys[actionKey]) state.operationKeys[actionKey] = window.AksrtRequest.createIdempotencyKey();
return {
url: orderPath(orderNumber, refresh ? "/refresh" : ""),
method: refresh ? "POST" : "GET",
headers: actionKey ? { "Idempotency-Key": state.operationKeys[actionKey] } : {},
kind: "orders",
title: "订单详情",
responseType: "json",
@@ -123,7 +130,10 @@
renderDetail(state, data, session);
},
onData: function (data) {
if (refresh) invalidateOrder(orderNumber, data);
if (refresh) {
delete state.operationKeys[actionKey];
invalidateOrder(orderNumber, data);
}
},
};
}
@@ -244,12 +254,15 @@
});
}
function startPayment(state, 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;
button.disabled = true;
request(orderPath(number, "/pay"), method ? { payment_method: method } : {}, "POST").then(function (result) {
if (!number || button.disabled) return;
var actionKey = "pay:" + number;
if (!state.operationKeys[actionKey]) state.operationKeys[actionKey] = window.AksrtRequest.createIdempotencyKey();
button.disabled = true;
request(orderPath(number, "/pay"), method ? { payment_method: method } : {}, "POST", state.operationKeys[actionKey]).then(function (result) {
delete state.operationKeys[actionKey];
var data = result.data || {};
invalidateOrder(number, data.order);
if (data.redirect && data.payment_url) {
@@ -273,8 +286,11 @@
button.textContent = "确认关闭";
return;
}
button.disabled = true;
request(orderPath(number, "/cancel"), {}, "POST").then(function (result) {
button.disabled = true;
var actionKey = "cancel:" + number;
if (!state.operationKeys[actionKey]) state.operationKeys[actionKey] = window.AksrtRequest.createIdempotencyKey();
request(orderPath(number, "/cancel"), {}, "POST", state.operationKeys[actionKey]).then(function (result) {
delete state.operationKeys[actionKey];
var data = result.data || {};
invalidateOrder(number, data.order);
notyf("订单已关闭", "success");
@@ -294,13 +310,14 @@
function initRoot(root) {
if (instances.has(root)) return;
var state = {
var state = {
root: root,
detailOrderNumber: "",
detailSession: null,
detailReplacement: false,
detailReplacementSession: null,
countdownTimer: null,
countdownTimer: null,
operationKeys: {},
};
state.onRootClick = function (event) {
+17 -1
View File
@@ -11,6 +11,13 @@
function initReward() {
var activeTrigger = null;
function operationKey(modal) {
if (!modal.dataset.aksrtOperationKey) {
modal.dataset.aksrtOperationKey = window.AksrtRequest.createIdempotencyKey();
}
return modal.dataset.aksrtOperationKey;
}
function closeAll() {
document.querySelectorAll('.reward-modal.is-open').forEach(function (modal) {
modal.classList.remove('is-open');
@@ -52,6 +59,7 @@
var amountButton = event.target.closest('[data-reward-amount]');
if (amountButton) {
var modal = amountButton.closest('.reward-modal');
delete modal.dataset.aksrtOperationKey;
modal.querySelectorAll('[data-reward-amount]').forEach(function (button) {
button.classList.toggle('is-active', button === amountButton);
});
@@ -67,6 +75,10 @@
var customInput = tipModal.querySelector('[data-aksrt-reward-custom]');
var selected = tipModal.querySelector('[data-reward-amount].is-active');
var amount = customInput && customInput.value ? customInput.value : (selected ? selected.dataset.rewardAmount : '');
if (customInput && customInput.dataset.aksrtIdempotencyBound !== '1') {
customInput.dataset.aksrtIdempotencyBound = '1';
customInput.addEventListener('input', function () { delete tipModal.dataset.aksrtOperationKey; });
}
submit.disabled = true;
submit.textContent = '赞赏中…';
@@ -82,13 +94,17 @@
fetch(cfg.ajaxUrl || '/wp-admin/admin-ajax.php', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Idempotency-Key': operationKey(tipModal)
},
body: body.toString()
}).then(function (response) {
return response.json();
}).then(function (response) {
var text = response && response.data && response.data.message ? response.data.message : '赞赏失败';
if (response && response.success) {
delete tipModal.dataset.aksrtOperationKey;
if (message) message.textContent = text;
setTimeout(closeAll, 900);
} else if (message) {
+26 -2
View File
@@ -75,6 +75,11 @@
var refreshTimeout = null;
var refreshInFlight = false;
var openSequence = 0;
var pendingCreateKey = '';
var pendingCreateSignature = '';
var pendingRefreshKey = '';
var pendingManualKey = '';
var pendingManualSignature = '';
function isOpen(shell) {
return !!shell && shell.classList.contains('is-open') && document.contains(shell);
@@ -176,6 +181,7 @@
var timedOut = false;
var shell = activeShell;
var timeoutMs = Math.max(5000, Number(config.refreshTimeout || 15000));
if (!pendingRefreshKey) pendingRefreshKey = uuid();
refreshTimeout = window.setTimeout(function () {
timedOut = true;
if (refreshController) {
@@ -185,8 +191,10 @@
return request(config.restBase + '/' + encodeURIComponent(currentUuid) + '/refresh', config, {
method: 'POST',
headers: { 'Idempotency-Key': pendingRefreshKey },
signal: refreshController ? refreshController.signal : undefined,
}).then(function (data) {
pendingRefreshKey = '';
if (shell !== activeShell || !isOpen(shell)) return data;
pollBackoff = explicit ? 0 : Math.min(4, pollBackoff + 1);
render(data, shell);
@@ -270,17 +278,23 @@
var payload = {};
form.forEach(function (value, key) { payload[key] = value; });
payload.consent = payload.consent === '1';
payload.client_request_id = uuid();
var signature = JSON.stringify(payload);
if (!pendingCreateKey || pendingCreateSignature !== signature) {
pendingCreateKey = uuid();
pendingCreateSignature = signature;
}
if (button) button.disabled = true;
if (message) message.textContent = '';
aliyunMetaInfo(config).then(function (metaInfo) {
if (metaInfo) payload.meta_info = metaInfo;
return request(config.restBase, config, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
headers: { 'Content-Type': 'application/json', 'Idempotency-Key': pendingCreateKey },
body: JSON.stringify(payload),
});
}).then(function (data) {
pendingCreateKey = '';
pendingCreateSignature = '';
render(data, shell);
}).catch(function (error) {
if (message) message.textContent = errorMessage(error, '创建认证会话失败,请重试。');
@@ -300,11 +314,21 @@
var button = manualForm.querySelector('[type="submit"]');
var body = new FormData();
Array.prototype.forEach.call((files && files.files) || [], function (file) { body.append('evidence[]', file); });
var signature = Array.prototype.map.call((files && files.files) || [], function (file) {
return [file.name, file.size, file.lastModified].join(':');
}).join('|');
if (!pendingManualKey || pendingManualSignature !== signature) {
pendingManualKey = uuid();
pendingManualSignature = signature;
}
if (button) button.disabled = true;
request(config.restBase + '/' + encodeURIComponent(currentUuid) + '/manual', config, {
method: 'POST',
headers: { 'Idempotency-Key': pendingManualKey },
body: body,
}).then(function (data) {
pendingManualKey = '';
pendingManualSignature = '';
manualForm.hidden = true;
render(data, shell);
}).catch(function (error) {
+1 -5
View File
@@ -89,10 +89,6 @@
$(this).text(aksrt__('admin_menu_title_income'));
}
if (url.endsWith('aksrtpay_rebate_page')) {
$(this).text(aksrt__('admin_menu_title_card'));
}
if (url.endsWith('aksrtpay_product_page')) {
$(this).text(aksrt__('admin_menu_title_product'));
}
@@ -448,6 +444,6 @@
$('.permalink-structure [name="permalink_structure"]').val('/%post_id%.html').click();
});
console.log('\n' + ' %c legacy Theme %c https://legacy.com ' + '\n', 'color: #fadfa3; background: #030307; padding:3px; font-size:12px;', 'color: #2abd4e;background: #16171a; padding: 3px; font-size: 12px;');
console.log('%c legacy Theme %c https://legacy.com', 'color: #fadfa3; background: #030307; padding:3px; font-size:12px;', 'color: #2abd4e;background: #16171a; padding: 3px; font-size: 12px;');
});
})(jQuery, document);
+1 -1
View File
@@ -1 +1 @@
(function(t,e){function i(t){var e=window.aksrt_admin_main_var&&window.aksrt_admin_main_var.i18n;return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:t}function n(t){var e=Array.prototype.slice.call(arguments,1),n=i(t),a=0;return n.replace(/%(\d+\$)?s/g,function(t,i){var n=i?parseInt(i,10)-1:a++;return void 0!==e[n]&&null!==e[n]?e[n]:t})}function a(t,e,i,n,a){var s,r,d;n&&(e+="px",i+="px",s="translate3D("+e+","+i+" , 0)",r={},d=o(),r[d+"transform"]=s,r[d+"transition"]=d+"transform 0s linear",r.cursor=a,"null"==n&&(r[d+"transform"]="",r[d+"transition"]=""),t.css(r))}function o(){var t=e.body||e.documentElement;return t=t.style,""==t.WebkitTransition?"-webkit-":""==t.MozTransition?"-moz-":""==t.OTransition?"-o-":""==t.transition?"":void 0}t.fn.minitouch=function(e){e=t.extend({direction:"bottom",selector:"",depreciation:50,onStart:!1,onEnd:!1},e);var i=t(this),n=(t("body"),e.depreciation),o=0,s=0,r=0,d=0,l=0,c=0,p=0,m=!1;i.on("touchstart pointerdown MSPointerDown",e.selector,function(t){o=0,s=0,r=0,d=0,l=0,c=0,p=0,o=t.originalEvent.pageX||t.originalEvent.touches[0].pageX,s=t.originalEvent.pageY||t.originalEvent.touches[0].pageY,m=!0}).on("touchmove pointermove MSPointerMove",e.selector,function(i){r=i.originalEvent.pageX||i.originalEvent.touches[0].pageX,d=i.originalEvent.pageY||i.originalEvent.touches[0].pageY,c=r-o,p=d-s,l=180*Math.atan2(p,c)/Math.PI,"right"==e.direction&&(p=0,c=l>-40&&l<40&&c>0?c:0),"left"==e.direction&&(p=0,c=(l>150||l<-150)&&0>c?c:0),"top"==e.direction&&(c=0,p=l>-130&&l<-50&&0>p?p:0),"bottom"==e.direction&&(c=0,p=l>50&&l<130&&p>0?p:0),0===c&&0===p||(i.preventDefault(),a(t(this),c,p,m,"grab"))}).on("touchend touchcancel pointerup MSPointerUp",e.selector,function(){(Math.abs(c)>n||Math.abs(p)>n)&&0!=e.onEnd&&e.onEnd(i),a(t(this),0,0,"null",""),m=!1,o=0,s=0,r=0,d=0,l=0,c=0,p=0})},t(e).ready(function(t){function a(e,i,n,a){t(".notyn").length||l.append('<div class="notyn"></div>'),i=i||"success",n=n||5e3,n=n<100?1e3*n:n;var s=a?' id="'+a+'"':"",r=t('<div class="noty1"'+s+'><div class="notyf '+i+'">'+e+"</div></div>"),d=!a;a&&t("#"+a).length?(t("#"+a).find(".notyf").removeClass().addClass("notyf "+i).html(e),r=t("#"+a),d=!0):t(".notyn").append(r),d&&setTimeout(function(){o(r)},n)}function o(t){t.addClass("notyn-out"),setTimeout(function(){t.remove()},1e3)}function s(i,n,a,o){function s(t,e,i){if(t.createTextRange){var n=t.createTextRange();n.collapse(!0),n.moveStart("character",e),n.moveEnd("character",i-e),n.select()}else t.setSelectionRange(e,i),t.select()}var r=i.toString(),d=e.querySelector("#copy-input");d||(d=e.createElement("input"),d.id="copy-input",d.readOnly="readOnly",d.style.position="fixed",d.style.left="-2000px",d.style.zIndex="-1000",o.parentNode.appendChild(d)),d.value=r,s(d,0,r.length),e.execCommand("copy")?t.isFunction(n)&&n():t.isFunction(a)&&a(),d.blur()}var r=t("#toplevel_page_aksrtpay_page");if(r.length&&"zh-Hans"!==t("html").attr("lang")){r.find(".toplevel_page_aksrtpay_page .wp-menu-name").text(i("admin_menu_title_shop_center"));var d=r.find(".wp-submenu");d.find("a.wp-first-item").text(i("admin_menu_title_shop_center")),d.find("a").each(function(){var e=t(this).attr("href");e.endsWith("aksrtpay_page")&&t(this).text(i("admin_menu_title_shop_center")),e.endsWith("aksrtpay_page#/order")&&t(this).text(i("admin_menu_title_order")),e.endsWith("aksrtpay_page#/shipping")&&t(this).text(i("admin_menu_title_shipping")),e.endsWith("aksrtpay_page#/after-sale")&&t(this).text(i("admin_menu_title_after_sale")),e.endsWith("aksrtpay_income_page")&&t(this).text(i("admin_menu_title_income")),e.endsWith("aksrtpay_rebate_page")&&t(this).text(i("admin_menu_title_card")),e.endsWith("aksrtpay_product_page")&&t(this).text(i("admin_menu_title_product")),e.endsWith("aksrtpay_charge_card_page")&&t(this).text(i("admin_menu_title_card")),e.endsWith("aksrtpay_coupon_page")&&t(this).text(i("admin_menu_title_coupon")),e.endsWith("aksrtpay_withdraw")&&t(this).text(i("admin_menu_title_withdraw")),e.endsWith("users.php")&&t(this).text(i("admin_menu_title_vip")),e.endsWith("aksrtpay_order_page")&&t(this).text(i("admin_menu_title_order_old"))})}var l=t("body");"function"!=typeof t.fn.serializeObject&&(t.fn.serializeObject=function(){var e={},i=this.serializeArray();return t.each(i,function(){void 0!==e[this.name]?(e[this.name].push||(e[this.name]=[e[this.name]]),e[this.name].push(this.value||"")):e[this.name]=this.value||""}),e}),l.width()<783&&t("#adminmenuwrap").minitouch({direction:"left",onEnd:function(){t("#wpwrap").removeClass("wp-responsive-open")}}),l.on("click",".noty1",function(){o(t(this))}),l.on("click","[data-clipboard-text]",function(){var e=t(this),o=e.attr("data-clipboard-text"),r=e.attr("data-clipboard-tag")||i("admin_content");s(o,function(){a(n("admin_copied",r))},function(){a(n("admin_copy_failed",r),"danger")},this)}),l.on("click",'[data-toggle="RefreshModal"]',function(){var e=t(this),i=e.attr("data-class")||"modal-mini",n=e.attr("data-remote"),a=e.attr("data-height")||200,o=e.attLine truncated
(function(k,w){function e(t){var c=window.aksrt_admin_main_var&&window.aksrt_admin_main_var.i18n;return c&&Object.prototype.hasOwnProperty.call(c,t)?c[t]:t}function M(t){var c=Array.prototype.slice.call(arguments,1),g=e(t),n=0;return g.replace(/%(\d+\$)?s/g,function(v,h){var d=h?parseInt(h,10)-1:n++;return c[d]!==void 0&&c[d]!==null?c[d]:v})}function W(t,c,g,n,v){var h,d,r;n&&(c+="px",g+="px",h="translate3D("+c+","+g+" , 0)",d={},r=P(),d[r+"transform"]=h,d[r+"transition"]=r+"transform 0s linear",d.cursor=v,n=="null"&&(d[r+"transform"]="",d[r+"transition"]=""),t.css(d))}function P(){var t=w.body||w.documentElement;return t=t.style,t.WebkitTransition==""?"-webkit-":t.MozTransition==""?"-moz-":t.OTransition==""?"-o-":t.transition==""?"":void 0}k.fn.minitouch=function(t){t=k.extend({direction:"bottom",selector:"",depreciation:50,onStart:!1,onEnd:!1},t);var c=k(this),g=(k("body"),t.depreciation),n=0,v=0,h=0,d=0,r=0,p=0,l=0,x=!1;c.on("touchstart pointerdown MSPointerDown",t.selector,function(_){n=0,v=0,h=0,d=0,r=0,p=0,l=0,n=_.originalEvent.pageX||_.originalEvent.touches[0].pageX,v=_.originalEvent.pageY||_.originalEvent.touches[0].pageY,x=!0}).on("touchmove pointermove MSPointerMove",t.selector,function(_){h=_.originalEvent.pageX||_.originalEvent.touches[0].pageX,d=_.originalEvent.pageY||_.originalEvent.touches[0].pageY,p=h-n,l=d-v,r=180*Math.atan2(l,p)/Math.PI,t.direction=="right"&&(l=0,p=r>-40&&r<40&&p>0?p:0),t.direction=="left"&&(l=0,p=(r>150||r<-150)&&0>p?p:0),t.direction=="top"&&(p=0,l=r>-130&&r<-50&&0>l?l:0),t.direction=="bottom"&&(p=0,l=r>50&&r<130&&l>0?l:0),p===0&&l===0||(_.preventDefault(),W(k(this),p,l,x,"grab"))}).on("touchend touchcancel pointerup MSPointerUp",t.selector,function(){(Math.abs(p)>g||Math.abs(l)>g)&&t.onEnd!=0&&t.onEnd(c),W(k(this),0,0,"null",""),x=!1,n=0,v=0,h=0,d=0,r=0,p=0,l=0})},k(w).ready(function(t){var c=t("#toplevel_page_aksrtpay_page");if(c.length&&t("html").attr("lang")!=="zh-Hans"){c.find(".toplevel_page_aksrtpay_page .wp-menu-name").text(e("admin_menu_title_shop_center"));var g=c.find(".wp-submenu");g.find("a.wp-first-item").text(e("admin_menu_title_shop_center")),g.find("a").each(function(){var a=t(this).attr("href");a.endsWith("aksrtpay_page")&&t(this).text(e("admin_menu_title_shop_center")),a.endsWith("aksrtpay_page#/order")&&t(this).text(e("admin_menu_title_order")),a.endsWith("aksrtpay_page#/shipping")&&t(this).text(e("admin_menu_title_shipping")),a.endsWith("aksrtpay_page#/after-sale")&&t(this).text(e("admin_menu_title_after_sale")),a.endsWith("aksrtpay_income_page")&&t(this).text(e("admin_menu_title_income")),a.endsWith("aksrtpay_product_page")&&t(this).text(e("admin_menu_title_product")),a.endsWith("aksrtpay_charge_card_page")&&t(this).text(e("admin_menu_title_card")),a.endsWith("aksrtpay_coupon_page")&&t(this).text(e("admin_menu_title_coupon")),a.endsWith("aksrtpay_withdraw")&&t(this).text(e("admin_menu_title_withdraw")),a.endsWith("users.php")&&t(this).text(e("admin_menu_title_vip")),a.endsWith("aksrtpay_order_page")&&t(this).text(e("admin_menu_title_order_old"))})}var n=t("body");typeof t.fn.serializeObject!="function"&&(t.fn.serializeObject=function(){var a={},s=this.serializeArray();return t.each(s,function(){a[this.name]!==void 0?(a[this.name].push||(a[this.name]=[a[this.name]]),a[this.name].push(this.value||"")):a[this.name]=this.value||""}),a}),n.width()<783&&t("#adminmenuwrap").minitouch({direction:"left",onEnd:function(){t("#wpwrap").removeClass("wp-responsive-open")}});function v(a,s,i,m){t(".notyn").length||n.append('<div class="notyn"></div>'),s=s||"success",i=i||5e3,i=i<100?i*1e3:i;var f=m?' id="'+m+'"':"",o=t('<div class="noty1"'+f+'><div class="notyf '+s+'">'+a+"</div></div>"),b=!m;m&&t("#"+m).length?(t("#"+m).find(".notyf").removeClass().addClass("notyf "+s).html(a),o=t("#"+m),b=!0):t(".notyn").append(o),b&&setTimeout(function(){h(o)},i)}function h(a){a.addClass("notyn-out"),setTimeout(function(){a.remove()},1e3)}n.on("click",".noty1",function(){h(t(this))});function d(a,s,i,m){var f=a.toString(),o=w.querySelector("#copy-input");o||(o=w.createElement("input"),o.id="copy-input",o.readOnly="readOnly",o.style.position="fixed",o.style.left="-2000px",o.style.zIndex="-1000",m.parentNode.appendChild(o)),o.value=f,b(o,0,f.length),w.execCommand("copy")?t.isFunction(s)&&s():t.isFunction(i)&&i(),o.blur();function b(y,C,E){if(y.createTextRange){var T=y.createTextRange();T.collapse(!0),T.moveStart("character",C),T.moveEnd("character",E-C),T.select()}else y.setSelectionRange(C,E),y.select()}}n.on("click","[data-clipboard-text]",function(){var a=t(this),s=a.attr("data-clipboard-text"),i=a.attr("data-clipboard-tag")||e("admin_content");d(s,function(){v(M("admin_copied",i))},function(){v(M("admin_copy_failed",i),"danger")},this)}),n.on("click",'[data-toggle="RefreshModal"]',function(){var a=t(this),s=a.attr("data-class")||"modal-mini",i=a.attr("data-remote"),m=a.attr("data-height")||200,f=a.attr("mobile-bottom")&&t(window).width()<769?" bottom":"",o="aksrt-modal flex jLine truncated
+15 -2
View File
@@ -15,6 +15,7 @@
var DEFAULT_MAX_ELAPSED = 120000;
var MAX_DELAY = 15000;
var createFlights = Object.create(null);
var operationKeys = Object.create(null);
var polls = Object.create(null);
var lastScope = "";
var scopeGeneration = 0;
@@ -47,6 +48,7 @@
if (flight && typeof flight.cancel === "function") flight.cancel();
});
createFlights = Object.create(null);
operationKeys = Object.create(null);
Object.keys(polls).forEach(function (pollKey) {
var active = polls[pollKey];
if (active && active.handle && typeof active.handle.abort === "function") active.handle.abort();
@@ -115,6 +117,7 @@
var key = userScope() + ":" + String(packageId) + ":" + method;
if (createFlights[key]) return createFlights[key].promise;
if (!operationKeys[key]) operationKeys[key] = window.AksrtRequest.createIdempotencyKey();
var requestController = !options.signal && window.AbortController
? new window.AbortController()
@@ -122,6 +125,7 @@
var flight = {
promise: request("/pay/vip", {
method: "POST",
headers: { "Idempotency-Key": operationKeys[key] },
body: JSON.stringify({
package_id: packageId,
payment_method: method,
@@ -143,22 +147,31 @@
}, function () {
if (createFlights[key] === flight) delete createFlights[key];
});
flight.promise.then(function (response) {
if (response.ok) delete operationKeys[key];
});
return flight.promise;
}
function exchange(options) {
options = options || {};
userScope();
var scope = userScope();
var packageId = parseInt(options.packageId || options.package_id || 0, 10);
if (!packageId) {
return Promise.resolve({ ok: false, status: 400, json: { message: "兑换套餐无效" } });
}
var key = scope + ":points-exchange:" + String(packageId);
if (!operationKeys[key]) operationKeys[key] = window.AksrtRequest.createIdempotencyKey();
return request("/pay/vip/points-exchange", {
method: "POST",
headers: { "Idempotency-Key": operationKeys[key] },
body: JSON.stringify({ package_id: packageId }),
signal: options.signal,
}).then(function (response) {
if (response.ok) invalidate(options.tags || ["vip", "orders"]);
if (response.ok) {
delete operationKeys[key];
invalidate(options.tags || ["vip", "orders"]);
}
return response;
});
}