fix(frontend): 统一计数缩写口径并将流水号改为订单号

前台各处评论、浏览、点赞、收藏、已售数量统一走
aksrt_format_number() 缩写(≥10000 → 1.2W+,≥1000 → 1.5K),
缩写后缀统一为大写 K,与既有 W+ 保持一致。PHP 渲染缩写文本的
同时保留 data-base-count 原始整数,JS 增量计算不受影响;
article.js / comment-ajax.js 内的 formatStatCount / formatCount
与 PHP 规则保持同一套,避免点赞收藏后文本回跳成全量数字。

文章详情页购买信息卡、用户中心创作者收益明细、后台分成与提现
管理页、支付设置页以及四封订单/提现邮件模板中,面向用户展示的
「流水号」字样统一改为「订单号」;代码注释、内部错误码与
WP_Error 文案保留原表述。

验证:node --test "tests/*/*.test.cjs" 508 项全部通过;
php -l 检查全部改动文件无语法错误;重新构建 admin SPA 与
前台 runtime bundle。
This commit is contained in:
2026-10-06 14:13:51 +08:00
parent fe57022550
commit 2595bb02db
23 changed files with 136 additions and 37 deletions
@@ -123,7 +123,7 @@ export const knowledgeSchema = {
{ key: 'pay_mark', label: '付费标记', type: 'input', default: '付费' },
{ key: 'payment_show_ip', label: '显示用户IP', type: 'switch', default: false },
{ key: 'payment_show_device', label: '显示设备信息', type: 'switch', default: false },
{ key: 'payment_show_order_no', label: '显示流水号', type: 'switch', default: true },
{ key: 'payment_show_order_no', label: '显示订单号', type: 'switch', default: true },
{ key: 'payment_show_create_time', label: '显示创建时间', type: 'switch', default: true },
{ key: 'payment_show_pay_time', label: '显示支付时间', type: 'switch', default: true },
],
+13 -1
View File
@@ -67,6 +67,18 @@
}
});
function formatCount(count) {
// 与 PHP aksrt_format_number() 同一套缩写:≥10000 → 1.2W+,≥1000 → 1.5K。
var safeCount = Math.max(0, parseInt(count, 10) || 0);
if (safeCount >= 10000) {
return Math.round((safeCount / 10000) * 10) / 10 + 'W+';
}
if (safeCount >= 1000) {
return Math.round((safeCount / 1000) * 10) / 10 + 'K';
}
return String(safeCount);
}
function handleLike(btn, commentId) {
if (btn.dataset.busy === '1') return;
btn.dataset.busy = '1';
@@ -81,7 +93,7 @@
btn.setAttribute('aria-pressed', active ? 'true' : 'false');
btn.classList.toggle('actived', active);
var countEl = btn.querySelector('count');
if (countEl) countEl.textContent = String(count);
if (countEl) countEl.textContent = formatCount(count);
})
.catch(function () { notyf('网络错误', 'danger'); })
.finally(function () { btn.dataset.busy = ''; });
+14 -2
View File
@@ -149,15 +149,27 @@
}
}
function formatStatCount(count) {
// 与 PHP aksrt_format_number() 同一套缩写:≥10000 → 1.2W+,≥1000 → 1.5K。
var safeCount = Math.max(0, count);
if (safeCount >= 10000) {
return Math.round((safeCount / 10000) * 10) / 10 + "W+";
}
if (safeCount >= 1000) {
return Math.round((safeCount / 1000) * 10) / 10 + "K";
}
return String(safeCount);
}
function getBaseStatCount(statName) {
var statEl = document.querySelector('[data-stat-count="' + statName + '"][data-base-count]');
return statEl ? (parseInt(statEl.dataset.baseCount, 10) || 0) : 0;
}
function updateStatCounts(statName, count) {
var safeCount = Math.max(0, count);
var label = formatStatCount(count);
document.querySelectorAll('[data-stat-count="' + statName + '"]').forEach(function (statEl) {
statEl.textContent = String(safeCount);
statEl.textContent = label;
});
}
+1 -1
View File
@@ -1193,7 +1193,7 @@
var number = document.createElement('span');
number.className = 'uc-withdraw-history__number muted-2-color em09';
var numberLabel = document.createElement('span');
numberLabel.textContent = '流水号:';
numberLabel.textContent = '订单号:';
number.appendChild(numberLabel);
var code = document.createElement('code');
code.textContent = text(item && item.withdrawal_number);
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -377,7 +377,7 @@
if (data.redirect && (data.payment_url || data.qr_content)) {
callback(options, "onPending", data);
if (!data.order_number) {
var missing = { ok: false, status: 500, json: { message: "流水号缺失" } };
var missing = { ok: false, status: 500, json: { message: "订单号缺失" } };
callback(options, "onError", missing);
return missing;
}
+1 -1
View File
@@ -489,7 +489,7 @@ add_action('manage_post_posts_custom_column', function ($column, $post_id) {
$format = function (int $n): string {
if ($n >= 10000) return round($n / 10000, 1) . '万';
if ($n >= 1000) return round($n / 1000, 1) . 'k';
if ($n >= 1000) return round($n / 1000, 1) . 'K';
return (string) $n;
};
+1 -1
View File
@@ -288,7 +288,7 @@ if (! function_exists('aksrt_format_number')) :
if ($num >= 10000) {
return round($num / 10000, 1) . 'W+';
} elseif ($num >= 1000) {
return round($num / 1000, 1) . 'k';
return round($num / 1000, 1) . 'K';
}
return (string) number_format_i18n($num);
}
+5 -3
View File
@@ -1379,7 +1379,8 @@ if (!function_exists('aksrt_get_paywall_html')) {
$price = aksrt_get_show_pay_price_html($meta, $priced);
$vip = aksrt_get_posts_vip_price($meta);
$attrs = aksrt_get_pay_attributes_html($post, 'pay-attr');
$count = $sales > 0 ? '<badge class="img-badge hot jb-blue px12">' . esc_html(sprintf(__('已售 %s', 'aksrt'), $sales)) . '</badge>' : '';
$sales_label = function_exists('aksrt_format_number') ? aksrt_format_number($sales) : number_format_i18n($sales);
$count = $sales > 0 ? '<badge class="img-badge hot jb-blue px12">' . esc_html(sprintf(__('已售 %s', 'aksrt'), $sales_label)) . '</badge>' : '';
$service = aksrt_get_pay_service_html('muted-2-color');
$widget_service = $service !== '' ? '<div class="px12 muted-2-color">' . $service . '</div>' : '';
$article_service = $service !== '' ? '<div class="px12 muted-2-color mt10 text-right">' . $service . '</div>' : '';
@@ -1538,7 +1539,8 @@ if (!function_exists('aksrt_get_paid_box_html')) {
$title = get_the_title($post);
$sales = max(0, (int) ($meta['virtual_sales'] ?? 0));
$sales += max(0, (int) get_post_meta($post->ID, \AKSRT\Core\DomainModel::RESOURCE_SALES_VOLUME_KEY, true));
$count = $sales > 0 ? '<badge class="img-badge hot jb-blue px12">' . esc_html(sprintf(__('已售 %s', 'aksrt'), $sales)) . '</badge>' : '';
$sales_label = function_exists('aksrt_format_number') ? aksrt_format_number($sales) : number_format_i18n($sales);
$count = $sales > 0 ? '<badge class="img-badge hot jb-blue px12">' . esc_html(sprintf(__('已售 %s', 'aksrt'), $sales_label)) . '</badge>' : '';
$order = aksrt_get_current_content_paid_order($post);
$priced = aksrt_get_user_pay_price($post);
$vip_level = max(0, min(2, (int) ($priced['vip_level'] ?? 0)));
@@ -1561,7 +1563,7 @@ if (!function_exists('aksrt_get_paid_box_html')) {
}
$amount_text = $cash_symbol . aksrt_format_price($order_amount);
}
$paid_info = '<div class="flex jsb"><span>' . esc_html__('流水号', 'aksrt') . '</span><span>' . esc_html($order_number) . '</span></div>';
$paid_info = '<div class="flex jsb"><span>' . esc_html__('订单号', 'aksrt') . '</span><span>' . esc_html($order_number) . '</span></div>';
if ($paid_at !== '') {
$paid_info .= '<div class="flex jsb"><span>' . esc_html__('支付时间', 'aksrt') . '</span><span>' . esc_html($paid_at) . '</span></div>';
}
+4 -2
View File
@@ -73,8 +73,9 @@ if (!function_exists('aksrt_get_posts_meta_items_html')) :
? 'javascript:(typeof scrollTopTo===\'function\'?scrollTopTo(\'#comments\'):void(0));'
: get_comments_link($post_id);
$count = (int) get_comments_number($post_id);
$count_label = function_exists('aksrt_format_number') ? aksrt_format_number($count) : number_format_i18n($count);
$html .= '<span class="item meta-comm"><a rel="nofollow" href="' . esc_attr($href) . '" title="' . esc_attr__('去评论', 'aksrt') . '">'
. '<i class="fa fas fa-comment" aria-hidden="true"></i> ' . esc_html((string) $count) . '</a></span>';
. '<i class="fa fas fa-comment" aria-hidden="true"></i> ' . esc_html((string) $count_label) . '</a></span>';
}
$views = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($post_id) : 0;
@@ -88,7 +89,8 @@ if (!function_exists('aksrt_get_posts_meta_items_html')) :
}
if ($like_on && $post->post_type === 'post') {
$likes = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($post_id) : 0;
$html .= '<span class="item meta-like"><i class="fa fas fa-heart" aria-hidden="true"></i> ' . esc_html((string) $likes) . '</span>';
$likes_label = function_exists('aksrt_format_number') ? aksrt_format_number($likes) : number_format_i18n($likes);
$html .= '<span class="item meta-like"><i class="fa fas fa-heart" aria-hidden="true"></i> ' . esc_html((string) $likes_label) . '</span>';
}
return $html;
+4 -2
View File
@@ -197,10 +197,11 @@ if (!function_exists('aksrt_single_render_actions')) :
<div class="text-center post-actions">
<?php
$like_icon = function_exists('aksrt_icon_markup') ? aksrt_icon_markup('zibsvg-like') : '';
$like_label = function_exists('aksrt_format_number') ? aksrt_format_number($like_count) : number_format_i18n($like_count);
if (!empty($settings['like_enabled'])) : ?>
<button type="button" class="action action-like<?php echo $is_liked ? ' actived' : ''; ?>" id="action-like" data-post-id="<?php echo esc_attr((string) $post_id); ?>" data-initial-active="<?php echo $is_liked ? '1' : '0'; ?>">
<?php echo $like_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
<text><?php esc_html_e('点赞', 'aksrt'); ?></text><count data-stat-count="likes" data-base-count="<?php echo esc_attr((string) $like_count); ?>"><?php echo esc_html((string) $like_count); ?></count>
<text><?php esc_html_e('点赞', 'aksrt'); ?></text><count data-stat-count="likes" data-base-count="<?php echo esc_attr((string) $like_count); ?>"><?php echo esc_html((string) $like_label); ?></count>
</button>
<?php endif; ?>
@@ -221,10 +222,11 @@ if (!function_exists('aksrt_single_render_actions')) :
<?php
$favorite_icon = function_exists('aksrt_icon_markup') ? aksrt_icon_markup('zibsvg-favorite') : '';
$favorite_label = function_exists('aksrt_format_number') ? aksrt_format_number($favorite_count) : number_format_i18n($favorite_count);
if (!empty($settings['favorite_enabled'])) : ?>
<button type="button" class="action action-favorite<?php echo $is_favorited ? ' actived' : ''; ?>" id="action-favorite" data-post-id="<?php echo esc_attr((string) $post_id); ?>" data-initial-active="<?php echo $is_favorited ? '1' : '0'; ?>">
<?php echo $favorite_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
<text><?php esc_html_e('收藏', 'aksrt'); ?></text><count data-stat-count="favorites" data-base-count="<?php echo esc_attr((string) $favorite_count); ?>"><?php echo esc_html((string) $favorite_count); ?></count>
<text><?php esc_html_e('收藏', 'aksrt'); ?></text><count data-stat-count="favorites" data-base-count="<?php echo esc_attr((string) $favorite_count); ?>"><?php echo esc_html((string) $favorite_label); ?></count>
</button>
<?php endif; ?>
</div>
+2 -1
View File
@@ -27,6 +27,7 @@ if (!function_exists('aksrt_get_comment_like_html')) :
return '';
}
$like_count = function_exists('aksrt_get_comment_likes') ? (int) aksrt_get_comment_likes($comment_id) : 0;
$like_label = function_exists('aksrt_format_number') ? aksrt_format_number($like_count) : number_format_i18n($like_count);
$is_liked = function_exists('aksrt_is_comment_liked') && aksrt_is_comment_liked($comment_id);
$classes = 'action action-comment-like muted-2-color flex0 ml10' . ($is_liked ? ' actived' : '');
$icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('like', 'icon mr3') : '';
@@ -38,7 +39,7 @@ if (!function_exists('aksrt_get_comment_like_html')) :
$is_liked ? '1' : '0',
$is_liked ? 'true' : 'false',
$icon, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup.
esc_html((string) $like_count)
esc_html((string) $like_label)
);
}
endif;
+1 -1
View File
@@ -264,7 +264,7 @@ if (!function_exists('aksrt_renderer_meta')) {
$right = '';
if (!empty($data['comments_open']) && empty($cfg['close_comments'])) {
$right .= '<item class="meta-comm"><a rel="nofollow" data-toggle="tooltip" title="' . esc_attr__('去评论', 'aksrt') . '" href="' . esc_url((string) $data['comments_link']) . '">' . aksrt_renderer_svg_icon('comment') . esc_html((string) $data['comments']) . '</a></item>';
$right .= '<item class="meta-comm"><a rel="nofollow" data-toggle="tooltip" title="' . esc_attr__('去评论', 'aksrt') . '" href="' . esc_url((string) $data['comments_link']) . '">' . aksrt_renderer_svg_icon('comment') . esc_html(aksrt_renderer_meta_number((int) $data['comments'])) . '</a></item>';
}
$right .= '<item class="meta-view">' . aksrt_renderer_svg_icon('view') . esc_html(aksrt_renderer_meta_number((int) $data['views'])) . '</item>';
if (!empty($cfg['show_like']) && (string) ($data['post_type'] ?? '') === 'post') {
@@ -422,6 +422,9 @@ if (!function_exists('aksrt_render_footer_tabbar_single_extend')) :
$is_liked = function_exists('aksrt_is_post_liked') ? aksrt_is_post_liked($post_id) : false;
$is_favorited = function_exists('aksrt_is_post_favorited') ? aksrt_is_post_favorited($post_id) : false;
$comment_count = (int) get_comments_number($post_id);
$like_label = function_exists('aksrt_format_number') ? aksrt_format_number($like_count) : number_format_i18n($like_count);
$favorite_label = function_exists('aksrt_format_number') ? aksrt_format_number($favorite_count) : number_format_i18n($favorite_count);
$comment_label = function_exists('aksrt_format_number') ? aksrt_format_number($comment_count) : number_format_i18n($comment_count);
if ($like_on) :
$like_tabbar_icon = function_exists('aksrt_icon_markup') ? aksrt_icon_markup('zibsvg-like') : '';
@@ -433,7 +436,7 @@ if (!function_exists('aksrt_render_footer_tabbar_single_extend')) :
data-initial-active="<?php echo $is_liked ? '1' : '0'; ?>"
aria-label="<?php esc_attr_e('点赞', 'aksrt'); ?>">
<?php echo $like_tabbar_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
<?php if ($show_text) : ?><count data-stat-count="likes" data-base-count="<?php echo esc_attr((string) $like_count); ?>"><?php echo esc_html((string) $like_count); ?></count><?php endif; ?>
<?php if ($show_text) : ?><count data-stat-count="likes" data-base-count="<?php echo esc_attr((string) $like_count); ?>"><?php echo esc_html((string) $like_label); ?></count><?php endif; ?>
</button>
<?php
endif;
@@ -448,7 +451,7 @@ if (!function_exists('aksrt_render_footer_tabbar_single_extend')) :
data-initial-active="<?php echo $is_favorited ? '1' : '0'; ?>"
aria-label="<?php esc_attr_e('收藏', 'aksrt'); ?>">
<?php echo $favorite_tabbar_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
<?php if ($show_text) : ?><count data-stat-count="favorites" data-base-count="<?php echo esc_attr((string) $favorite_count); ?>"><?php echo esc_html((string) $favorite_count); ?></count><?php endif; ?>
<?php if ($show_text) : ?><count data-stat-count="favorites" data-base-count="<?php echo esc_attr((string) $favorite_count); ?>"><?php echo esc_html((string) $favorite_label); ?></count><?php endif; ?>
</button>
<?php
endif;
@@ -464,7 +467,7 @@ if (!function_exists('aksrt_render_footer_tabbar_single_extend')) :
data-type="comment"
aria-label="<?php esc_attr_e('评论', 'aksrt'); ?>">
<i class="fa fas fa-comment" aria-hidden="true"></i>
<?php if ($show_text) : ?><span><?php echo esc_html((string) $comment_count); ?></span><?php endif; ?>
<?php if ($show_text) : ?><span><?php echo esc_html((string) $comment_label); ?></span><?php endif; ?>
</a>
<?php
endif;
@@ -102,7 +102,7 @@ $currency_labels = [
$status = (string) ($item['status'] ?? '') === 'pending' ? 'pending' : 'settled';
$amount = $format($item['amount'] ?? 0, $unit);
$order_number = trim((string) ($item['order_number'] ?? ''));
$order_number = $order_number !== '' ? $order_number : __('流水号未知', 'aksrt');
$order_number = $order_number !== '' ? $order_number : __('订单号未知', 'aksrt');
$post = get_post((int) ($item['post_id'] ?? 0));
$source = $post instanceof WP_Post && $post->post_type === 'post'
? get_the_title($post)
+2 -2
View File
@@ -99,7 +99,7 @@ class PayIncome {
echo '<input type="number" min="0" name="user_id" value="' . esc_attr($user_id > 0 ? (string) $user_id : '') . '" placeholder="' . esc_attr__('用户 ID', 'aksrt') . '" class="small-text" /> ';
echo '<input type="number" min="0" name="post_id" value="' . esc_attr($post_id > 0 ? (string) $post_id : '') . '" placeholder="' . esc_attr__('文章 ID', 'aksrt') . '" class="small-text" /> ';
echo '<select name="currency"><option value="">' . esc_html__('全部货币', 'aksrt') . '</option><option value="CNY"' . selected($currency, 'CNY', false) . '>CNY</option><option value="points"' . selected($currency, 'points', false) . '>' . esc_html__('积分', 'aksrt') . '</option></select> ';
echo '<input type="search" name="order_number" value="' . esc_attr($order_number) . '" placeholder="' . esc_attr__('流水号', 'aksrt') . '" /> ';
echo '<input type="search" name="order_number" value="' . esc_attr($order_number) . '" placeholder="' . esc_attr__('订单号', 'aksrt') . '" /> ';
echo '<input type="date" name="date_from" value="' . esc_attr($date_from) . '" /> — <input type="date" name="date_to" value="' . esc_attr($date_to) . '" /> ';
submit_button(__('筛选', 'aksrt'), 'secondary', '', false);
if ($user_id > 0) {
@@ -127,7 +127,7 @@ class PayIncome {
$pages = max(1, (int) ($result['max_pages'] ?? 1));
echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
echo '<th><input type="checkbox" form="aksrt-pay-batch-settle-income" aria-label="' . esc_attr__('全选待结算记录', 'aksrt') . '" /></th><th>ID</th><th>' . esc_html__('用户', 'aksrt') . '</th><th>' . esc_html__('流水号', 'aksrt') . '</th><th>' . esc_html__('金额', 'aksrt') . '</th><th>' . esc_html__('状态', 'aksrt') . '</th><th>' . esc_html__('时间', 'aksrt') . '</th><th>' . esc_html__('操作', 'aksrt') . '</th>';
echo '<th><input type="checkbox" form="aksrt-pay-batch-settle-income" aria-label="' . esc_attr__('全选待结算记录', 'aksrt') . '" /></th><th>ID</th><th>' . esc_html__('用户', 'aksrt') . '</th><th>' . esc_html__('订单号', 'aksrt') . '</th><th>' . esc_html__('金额', 'aksrt') . '</th><th>' . esc_html__('状态', 'aksrt') . '</th><th>' . esc_html__('时间', 'aksrt') . '</th><th>' . esc_html__('操作', 'aksrt') . '</th>';
echo '</tr></thead><tbody>';
if (!$items) {
echo '<tr><td colspan="8">' . esc_html__('暂无分成记录', 'aksrt') . '</td></tr>';
+2 -2
View File
@@ -83,7 +83,7 @@ class PayWithdrawals {
);
}
echo '</select> ';
echo '<input type="search" name="s" value="' . esc_attr($keyword) . '" placeholder="' . esc_attr__('流水号 / 用户 ID', 'aksrt') . '" /> ';
echo '<input type="search" name="s" value="' . esc_attr($keyword) . '" placeholder="' . esc_attr__('订单号 / 用户 ID', 'aksrt') . '" /> ';
echo '<input type="number" min="1" name="user_id" value="' . esc_attr($user_filter > 0 ? (string) $user_filter : '') . '" placeholder="' . esc_attr__('用户 ID', 'aksrt') . '" class="small-text" /> ';
echo '<label>' . esc_html__('从', 'aksrt') . ' <input type="date" name="date_from" value="' . esc_attr($date_from) . '"></label> ';
echo '<label>' . esc_html__('至', 'aksrt') . ' <input type="date" name="date_to" value="' . esc_attr($date_to) . '"></label> ';
@@ -113,7 +113,7 @@ class PayWithdrawals {
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr>';
echo '<th>' . esc_html__('流水号', 'aksrt') . '</th>';
echo '<th>' . esc_html__('订单号', 'aksrt') . '</th>';
echo '<th>' . esc_html__('用户', 'aksrt') . '</th>';
echo '<th>' . esc_html__('金额明细', 'aksrt') . '</th>';
echo '<th>' . esc_html__('渠道 / 账户', 'aksrt') . '</th>';
+1 -1
View File
@@ -61,7 +61,7 @@ class SchemaPayment {
['key' => 'pay_mark', 'label' => '付费标记', 'type' => 'input', 'default' => '付费'],
['key' => 'payment_show_ip', 'label' => '显示用户IP', 'type' => 'switch', 'default' => false],
['key' => 'payment_show_device', 'label' => '显示设备信息', 'type' => 'switch', 'default' => false],
['key' => 'payment_show_order_no', 'label' => '显示流水号', 'type' => 'switch', 'default' => true],
['key' => 'payment_show_order_no', 'label' => '显示订单号', 'type' => 'switch', 'default' => true],
['key' => 'payment_show_create_time', 'label' => '显示创建时间', 'type' => 'switch', 'default' => true],
['key' => 'payment_show_pay_time', 'label' => '显示支付时间', 'type' => 'switch', 'default' => true],
]],
+4 -4
View File
@@ -14,8 +14,8 @@ final class MailTemplates {
public static function definitions(): array {
return [
'links_submit_admin' => self::event('友情链接提交通知', '新友情链接提交:{title}\n提交人:{username}\n链接:{url}\n请登录后台审核。', ['title', 'username', 'url']),
'order_paid_admin' => self::event('新订单通知(管理员)', '收到一笔新订单。\n流水号:{order_number}\n用户:{username}\n商品:{product}\n金额:{amount} {currency}\n支付方式:{payment_method}', ['order_number', 'username', 'product', 'amount', 'currency', 'payment_method']),
'withdraw_submitted_admin' => self::event('提现申请通知(管理员)', '用户 {username} 提交了提现申请。\n流水号:{withdrawal_number}\n金额:{amount}\n方式:{method}', ['username', 'withdrawal_number', 'amount', 'method']),
'order_paid_admin' => self::event('新订单通知(管理员)', '收到一笔新订单。\n订单号:{order_number}\n用户:{username}\n商品:{product}\n金额:{amount} {currency}\n支付方式:{payment_method}', ['order_number', 'username', 'product', 'amount', 'currency', 'payment_method']),
'withdraw_submitted_admin' => self::event('提现申请通知(管理员)', '用户 {username} 提交了提现申请。\n订单号:{withdrawal_number}\n金额:{amount}\n方式:{method}', ['username', 'withdrawal_number', 'amount', 'method']),
'post_pending_admin' => self::event('投稿待审核通知', '用户 {username} 提交了待审核内容:{title}\n查看地址:{url}', ['username', 'title', 'url']),
'auth_apply_admin' => self::event('身份认证申请通知', '用户 {username} 提交了身份认证申请,请登录后台审核。\n查看地址:{url}', ['username', 'url']),
'ban_appeal_admin' => self::event('账号申诉通知', '用户 {username} 提交了账号申诉。\n查看地址:{url}', ['username', 'url']),
@@ -27,9 +27,9 @@ final class MailTemplates {
'password_reset' => self::event('密码重置验证码', '您好 {username},\n\n您正在重置 {site_name} 的账号密码,验证码为:\n\n【{code}】\n\n验证码 10 分钟内有效。如非本人操作,请忽略此邮件。', ['username', 'site_name', 'code']),
'change_code' => self::event('敏感操作验证码', '您好 {username},\n\n您正在进行敏感操作,验证码为:\n\n【{code}】\n\n验证码 5 分钟内有效。如非本人操作,请忽略此邮件。', ['username', 'site_name', 'code']),
'change_notice' => self::event('账号邮箱已变更', '您好 {username},\n\n您的账号邮箱已成功修改为:{new_email}\n\n如果这不是您的操作,请立即联系站点管理员。', ['username', 'site_name', 'new_email']),
'order_paid' => self::event('订单支付成功', '您好 {username},\n\n您的订单已支付成功。\n流水号:{order_number}\n商品:{product}\n金额:{amount} {currency}\n\n查看订单:{url}', ['username', 'order_number', 'product', 'amount', 'currency', 'url']),
'order_paid' => self::event('订单支付成功', '您好 {username},\n\n您的订单已支付成功。\n订单号:{order_number}\n商品:{product}\n金额:{amount} {currency}\n\n查看订单:{url}', ['username', 'order_number', 'product', 'amount', 'currency', 'url']),
'order_status' => self::event('订单状态更新', '您好 {username},\n\n您的订单 {order_number} 状态已更新为:{status}。\n商品:{product}\n查看详情:{url}', ['username', 'order_number', 'status', 'product', 'url']),
'withdraw_submitted' => self::event('提现申请已提交', '您好 {username},\n\n您的提现申请已提交。\n流水号:{withdrawal_number}\n金额:{amount}\n方式:{method}', ['username', 'withdrawal_number', 'amount', 'method']),
'withdraw_submitted' => self::event('提现申请已提交', '您好 {username},\n\n您的提现申请已提交。\n订单号:{withdrawal_number}\n金额:{amount}\n方式:{method}', ['username', 'withdrawal_number', 'amount', 'method']),
'withdraw_completed' => self::event('提现状态更新', '您好 {username},\n\n您的提现申请 {withdrawal_number} 当前状态为:{status}。\n金额:{amount}\n{note}', ['username', 'withdrawal_number', 'status', 'amount', 'note']),
'affiliate_commission' => self::event('返佣到账通知', '您好 {username},\n\n您的推广返佣已到账。\n金额:{amount}\n来源订单:{order_number}\n查看收益:{url}', ['username', 'amount', 'order_number', 'url']),
'creator_income' => self::event('创作分成到账通知', '您好 {username},\n\n您的创作分成已到账。\n金额:{amount}\n来源订单:{order_number}\n查看收益:{url}', ['username', 'amount', 'order_number', 'url']),
+3 -2
View File
@@ -167,7 +167,8 @@ if ($is_need_purchase && $user_amount > 0) {
<i class="fa fas fa-fire" aria-hidden="true"></i>
<?php
/* translators: %s: 下载/销量数 */
printf(esc_html__('已售 %s', 'aksrt'), number_format_i18n($display_count));
$sales_label = function_exists('aksrt_format_number') ? aksrt_format_number($display_count) : number_format_i18n($display_count);
printf(esc_html__('已售 %s', 'aksrt'), $sales_label);
?>
</span>
<?php endif; ?>
@@ -210,7 +211,7 @@ if ($is_need_purchase && $user_amount > 0) {
</div>
<?php if (is_array($paid_order) && !empty($paid_order['order_number'])) : ?>
<div class="resource-download-box__paid-meta">
<span><?php printf(esc_html__('流水号:%s', 'aksrt'), esc_html((string) $paid_order['order_number'])); ?></span>
<span><?php printf(esc_html__('订单号:%s', 'aksrt'), esc_html((string) $paid_order['order_number'])); ?></span>
<?php if (!empty($paid_order['paid_at'])) : ?>
<span><?php printf(esc_html__('支付时间:%s', 'aksrt'), esc_html((string) $paid_order['paid_at'])); ?></span>
<?php endif; ?>
@@ -59,8 +59,8 @@ test('orders have no independent flow page or visible flow number', () => {
assert.equal(fs.existsSync(path.join(root, 'src/Finance/FinancialFlowQuery.php')), false)
assert.match(payOrders, /订单明细/)
assert.doesNotMatch(payOrders, /账本流水号|资金流水号/)
assert.match(read('src/Admin/Native/PayWithdrawals.php'), /esc_html__\('流水号'/)
assert.doesNotMatch(read('src/Admin/Native/PayWithdrawals.php'), /提现单号/)
assert.match(read('src/Admin/Native/PayWithdrawals.php'), /esc_html__\('订单号'/)
assert.doesNotMatch(read('src/Admin/Native/PayWithdrawals.php'), /esc_html__\('流水号'|提现单号/)
// 前台订单详情只展示公开订单号,账本流水号不下发也不展示。
assert.match(read('assets/js/order-center.js'), /\["订单号", order\.order_number\]/)
assert.doesNotMatch(read('assets/js/order-center.js'), /flow_number|账本流水号/)
@@ -40,8 +40,8 @@ test('paid article and sidebar widget use the Zibll purchase-card DOM', () => {
assert.match(pay, /function aksrt_get_paid_box_html/);
assert.match(pay, /pay-box zib-widget paid-box order-type-/);
assert.match(pay, /flex ac jb-green padding-10 em09/);
assert.match(pay, /流水号/);
assert.doesNotMatch(pay, /'订单号'/);
assert.match(pay, /订单号/);
assert.doesNotMatch(pay, /'流水号'/);
assert.match(pay, /支付时间/);
assert.match(pay, /支付金额/);
assert.match(pay, /hidden-box show/);
@@ -745,6 +745,10 @@ test('single post more menu has one accessible runtime and an in-flow author anc
assert.match(components, /aria-haspopup="true"/);
assert.match(single, /aksrt_get_single_meta_box\(\$post_id\)/);
assert.doesNotMatch(components, /\$direction/);
assert.match(components, /\$count_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$count\) : number_format_i18n\(\$count\)/);
assert.match(components, /\$likes_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$likes\) : number_format_i18n\(\$likes\)/);
assert.match(components, /esc_html\(\(string\) \$count_label\)/);
assert.match(components, /esc_html\(\(string\) \$likes_label\)/);
assert.match(authorBar, /class="single-meta-row"/);
assert.doesNotMatch(authorBar, /single-metabox abs-right/);
assert.match(singleRender, /'meta_html'\s*=>\s*\(string\) \(\$ctx\['meta_box_html'\] \?\? ''\)/);
@@ -754,6 +758,66 @@ test('single post more menu has one accessible runtime and an in-flow author anc
assert.match(styles, /\.article-header:has\(\.post-drop-meta\.is-open\)\s*\{[^}]*z-index:\s*30;/s);
});
test('single post like, favorite and comment counts abbreviate everywhere', () => {
const actionsRender = read('inc/helpers/aksrt-single-render.php');
const tabbar = read('inc/helpers/template-tags/pagination-permissions.php');
const article = read('assets/js/core/article.js');
assert.match(actionsRender, /\$like_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$like_count\) : number_format_i18n\(\$like_count\)/);
assert.match(actionsRender, /\$favorite_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$favorite_count\) : number_format_i18n\(\$favorite_count\)/);
assert.match(actionsRender, /data-stat-count="likes" data-base-count="<\?php echo esc_attr\(\(string\) \$like_count\); \?>"><\?php echo esc_html\(\(string\) \$like_label\);/);
assert.match(actionsRender, /data-stat-count="favorites" data-base-count="<\?php echo esc_attr\(\(string\) \$favorite_count\); \?>"><\?php echo esc_html\(\(string\) \$favorite_label\);/);
assert.match(tabbar, /\$like_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$like_count\) : number_format_i18n\(\$like_count\)/);
assert.match(tabbar, /\$favorite_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$favorite_count\) : number_format_i18n\(\$favorite_count\)/);
assert.match(tabbar, /\$comment_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$comment_count\) : number_format_i18n\(\$comment_count\)/);
assert.match(tabbar, /echo esc_html\(\(string\) \$like_label\)/);
assert.match(tabbar, /echo esc_html\(\(string\) \$favorite_label\)/);
assert.match(tabbar, /echo esc_html\(\(string\) \$comment_label\)/);
assert.match(article, /function formatStatCount\(count\)/);
assert.match(article, /safeCount >= 10000[\s\S]*?"W\+"/);
assert.match(article, /safeCount >= 1000[\s\S]*?"K"/);
assert.match(article, /var label = formatStatCount\(count\);/);
});
test('abbreviated counts use uppercase unit suffixes everywhere', () => {
const frontendTags = read('inc/helpers/aksrt-frontend-tags.php');
const article = read('assets/js/core/article.js');
const commentAjax = read('assets/js/comment-ajax.js');
const formatNumber = frontendTags.match(/function aksrt_format_number\([\s\S]*?\nendif;/)[0];
assert.match(formatNumber, /round\(\$num \/ 10000, 1\) \. 'W\+'/);
assert.match(formatNumber, /round\(\$num \/ 1000, 1\) \. 'K'/);
assert.doesNotMatch(formatNumber, /\. 'k'/);
assert.doesNotMatch(article, /"k"/);
assert.match(article, /"K"/);
assert.match(commentAjax, /function formatCount\(count\)/);
assert.match(commentAjax, /safeCount >= 10000[\s\S]*?'W\+'/);
assert.match(commentAjax, /safeCount >= 1000[\s\S]*?'K'/);
assert.doesNotMatch(commentAjax, /'k'/);
});
test('article page sales counts and comment likes abbreviate', () => {
const pay = read('inc/helpers/aksrt-pay.php');
const downloadBox = read('templates/parts/resource-download-box.php');
const commentItem = read('inc/helpers/comments/item.php');
// 付费盒(文章页 + 侧栏小工具)「已售」徽章。
assert.match(pay, /\$sales_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$sales\) : number_format_i18n\(\$sales\)/);
assert.doesNotMatch(pay, /sprintf\(__\('已售 %s', 'aksrt'\), \$sales\)/);
// 资源下载盒「已售」徽章。
assert.match(downloadBox, /\$sales_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$display_count\) : number_format_i18n\(\$display_count\)/);
assert.match(downloadBox, /printf\(esc_html__\('已售 %s', 'aksrt'\), \$sales_label\)/);
assert.doesNotMatch(downloadBox, /number_format_i18n\(\$display_count\)\);/);
// 评论区点赞数。
assert.match(commentItem, /\$like_label = function_exists\('aksrt_format_number'\) \? aksrt_format_number\(\$like_count\) : number_format_i18n\(\$like_count\)/);
assert.match(commentItem, /esc_html\(\(string\) \$like_label\)/);
});
test('single post has no word-count or estimated-reading-time chain', () => {
const chain = join([
'inc/helpers/aksrt-single.php',