fix(frontend): route every user-center points label through the custom currency name

后台「积分配置 → 自定义货币名称」改名后,用户中心仍有大量硬编码
「积分」:做任务赚积分 / 购买积分 / 签到领积分、积分记录 / 积分任务、
每日可免费获取 XX 积分、我的积分、积分+1、创作中心积分收益等。

get_currency_name() 早已存在且可用,问题只是这些文案没有走它。
本PR 全部替换,无双路、无迁移:

服务端渲染(用户中心 renderers)
- credits-balance.php:购买/做任务赚/签到领 + 整个购买弹窗
- profile-credits.php:积分记录 / 积分任务 页签
- credits-points-tasks.php:每日上限三态与空态
- sidebar-creator.php / profile-creator.php:积分收益
- transfer-modal.php:积分转账提示
- Signin.php:签到详情弹窗(我的积分 / 奖励 tooltip / 积分+N)
- VipServiceModal.php:我的积分 / 积分兑换会员
- download-permission-card.php:购买价格

客户端渲染(JS 无法调用 PHP,注入 currencyName 到 aksrtData)
- signin.js:签到状态行「已签到 N 天 +1」
- credits.js:转账标题/金额标签 + 购买提示 toast
- cms-download.js:积分不足视图、我的积分 入口、余额不足文案
- pay-vip.js:积分兑换会员入口(优先 catalog.currency_name)
- order-center.js:订单行单位回退

契约测试同步改为断言模板构造而非死字符串,并新增两例:
改名后跟随、未注入时回退「积分」。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-01 15:09:49 +08:00
1 parent 1c95f94bca
commit 5c6b422866
19 files changed
+170 -59

No files matched your search

+18 -6
View File
@@ -20,6 +20,12 @@
const REST_BASE = window.aksrtData.siteUrl ? window.aksrtData.siteUrl.replace(/\/$/, '') + '/wp-json/aksrt/v1' : '/wp-json/aksrt/v1';
const PAY_CONTENT_PATH = '/pay/content/';
// 自定义货币名称(后台「积分配置 → 自定义货币名称」)由服务端注入。
// 余额不足提示在客户端拼装,必须跟随它。
function currencyName() {
return (window.aksrtData && window.aksrtData.currencyName) || '积分';
}
function escapeHtml(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&amp;')
@@ -192,6 +198,8 @@
let viewKey = 'error';
let subtitle = '';
let action = null;
// credits 视图标题跟随自定义货币名称;其余视图沿用静态文案。
let unit = '';
data = data || {};
msg = msg || '';
@@ -215,8 +223,9 @@
viewKey = 'credits';
const balance = typeof data.balance === 'number' ? data.balance : 0;
const cost = typeof data.cost === 'number' ? data.cost : 0;
msg = '当前余额 ' + balance + ' 积分,需要 ' + cost + ' 积分。可通过签到、阅读、邀请好友等方式获取积分。';
if (data.credits_url) action = { kind: 'link', url: data.credits_url, label: '我的积分', icon: 'fa-coins' };
unit = currencyName();
msg = '当前余额 ' + balance + ' ' + unit + ',需要 ' + cost + ' ' + unit + '。可通过签到、阅读、邀请好友等方式获取' + unit + '。';
if (data.credits_url) action = { kind: 'link', url: data.credits_url, label: '我的' + unit, icon: 'fa-coins' };
} else if (code === 'aksrt_download_limit') {
viewKey = 'quota';
msg = msg || '您今日下载免费资源个数已超限,请明日再下载。';
@@ -232,6 +241,7 @@
open(
dlView(viewKey, {
title: viewKey === 'credits' && unit ? unit + '不足' : undefined,
subtitle: subtitle,
body: msg ? '<p class="aksrt-dl-modal__msg">' + escapeHtml(msg) + '</p>' : '',
actions: action ? [action] : [],
@@ -368,7 +378,8 @@
}
function formatAssetLabel(preview, value) {
const currency = escapeHtml(preview.currency || (preview.pay_modo === 'points' ? '积分' : '¥'));
// preview.currency 由服务端解析(积分价走自定义货币名称),缺省时回退同一来源。
const currency = escapeHtml(preview.currency || (preview.pay_modo === 'points' ? currencyName() : '¥'));
const amount = escapeHtml(value == null ? '' : value);
return preview.pay_modo === 'points' ? amount + currency : currency + amount;
}
@@ -483,15 +494,16 @@
body += '<div class="mb10 muted-box padding-h6 line-16">' + priceRows + '</div>';
if (isPoints) {
const unit = currencyName();
body += '<div class="mb10 muted-box padding-h10">' +
'<div class="flex jsb ac"><span class="muted-2-color">' +
'<i class="fa fas fa-database aksrt-cashier__asset-icon" aria-hidden="true"></i>我的积分' +
'<i class="fa fas fa-database aksrt-cashier__asset-icon" aria-hidden="true"></i>我的' + unit +
'</span><div class="c-green"><span class="em14">' + balance + '</span></div></div></div>';
if (!preview.balance_enough) {
body += '<div class="badg c-red btn-block mb20 aksrt-cashier__warn">抱歉,您的积分不足,暂时无法支付</div>';
body += '<div class="badg c-red btn-block mb20 aksrt-cashier__warn">抱歉,您的' + unit + '不足,暂时无法支付</div>';
body += '<div class="modal-buts but-average">';
if (preview.credits_url) {
body += '<a class="but padding-lg" href="' + escapeAttr(preview.credits_url) + '">我的积分</a>';
body += '<a class="but padding-lg" href="' + escapeAttr(preview.credits_url) + '">我的' + unit + '</a>';
}
body += '</div>';
openCashierContent(body, returnFocusEl);
+10 -4
View File
@@ -16,6 +16,12 @@
}
var activePoll = null;
// 自定义货币名称(后台「积分配置 → 自定义货币名称」)由服务端注入。
// 转账标题/金额标签与购买提示都在客户端拼装,必须跟随它。
function currencyName() {
return (aksrt && aksrt.currencyName) || '积分';
}
function operationKey(owner) {
if (!owner.dataset.aksrtOperationKey) {
owner.dataset.aksrtOperationKey = window.AksrtRequest.createIdempotencyKey();
@@ -495,7 +501,7 @@
? 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' ? '积分转账' : '余额转账';
if (title) title.textContent = type === 'points' ? currencyName() + '转账' : '余额转账';
var amountEl = form ? form.querySelector('[data-aksrt-transfer-amount]') : null;
if (amountEl) {
amountEl.min = type === 'points' ? String(pointsTransferMin) : '0.01';
@@ -503,7 +509,7 @@
amountEl.inputMode = type === 'points' ? 'numeric' : 'decimal';
amountEl.value = '';
}
if (amountLabel) amountLabel.textContent = type === 'points' ? '积分' : '金额';
if (amountLabel) amountLabel.textContent = type === 'points' ? currencyName() : '金额';
if (balanceInfo) balanceInfo.hidden = type === 'points';
if (pointsInfo) pointsInfo.hidden = type !== 'points';
if (results) results.innerHTML = '';
@@ -744,11 +750,11 @@
selectProduct('custom');
}
if ((!pkg || pkg === 'custom') && !validCustom) {
notyf('请选择或输入需购买的积分', 'danger');
notyf('请选择或输入需购买的' + currencyName(), 'danger');
return;
}
busy = true;
notyf('正在购买积分…', 'load', '', 'aksrt-balance-points-toast');
notyf('正在购买' + currencyName() + '…', 'load', '', 'aksrt-balance-points-toast');
api('/pay/balance/points-exchange', {
method: 'POST',
headers: { 'Idempotency-Key': operationKey(form) },
+9 -1
View File
@@ -35,13 +35,21 @@
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");
// 单位名由服务端随订单下发(UserOrders::currency_symbol),
// 缺省时回退到自定义货币名称,避免改名后残留「积分」。
var unit = order.currency_symbol || currencyName();
return escapeHtml(unit) + " " + (/^\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 currencyName() {
return (window.aksrtData && window.aksrtData.currencyName) || "积分";
}
function orderTag(orderNumber) {
return "order:" + String(orderNumber || "").toLowerCase();
}
+4 -1
View File
@@ -493,8 +493,11 @@
var pointsLink = node("a", "btn-block but mb10 padding-lg c-green mini-radius");
pointsLink.href = "javascript:;";
pointsLink.setAttribute("data-aksrt-vip-points-open", "");
// 入口文案跟随自定义货币名称(后台「积分配置 → 自定义货币名称」),
// 与它打开的服务端静态弹窗标题保持同一命名。
var currencyName = (catalog.currency_name || (window.aksrtData && window.aksrtData.currencyName) || "积分");
pointsLink.innerHTML = '<svg class="icon" aria-hidden="true"><use xlink:href="#icon-points-color"></use></svg>'
+ "积分兑换会员"
+ currencyName + "兑换会员"
+ '<i class="fa fas fa-angle-right em12 ml10" aria-hidden="true"></i>';
append(products, pointsLink);
}
+9 -3
View File
@@ -13,6 +13,12 @@
var signinBusy = false;
var refreshSequence = 0;
// 自定义货币名称(后台「积分配置 → 自定义货币名称」)由服务端注入,
// 状态行文案必须跟随它,否则改名后这里仍显示「积分」。
function currencyName() {
return (window.aksrtData && window.aksrtData.currencyName) || '积分';
}
function api(path, options) {
return window.AksrtRequest.request(path, options || {}).then(function (response) {
return {
@@ -111,11 +117,11 @@
return;
}
if (data.signed) {
setStatusHtml('已签到 <strong>' + data.streak + '</strong> 天 +' + data.reward_today);
setStatusHtml('已签到 <strong>' + data.streak + '</strong> 天 +' + data.reward_today + ' ' + currencyName());
swapButtonsToDetailsLink();
return;
}
setStatusHtml('连续 <strong>' + data.streak + '</strong> 天,+' + data.reward_if_signin);
setStatusHtml('连续 <strong>' + data.streak + '</strong> 天,+' + data.reward_if_signin + ' ' + currencyName());
});
}
@@ -168,7 +174,7 @@
element.textContent = Number(result.json.balance || 0).toLocaleString();
element.title = element.textContent;
});
setStatusHtml('已签到 <strong>' + result.json.streak + '</strong> 天 +' + result.json.reward);
setStatusHtml('已签到 <strong>' + result.json.streak + '</strong> 天 +' + result.json.reward + ' ' + currencyName());
swapButtonsToDetailsLink();
}).catch(function (error) {
restoreButton();