Files
wordpress-theme-aksrt/inc/helpers/user-center-renderers/profile-creator.php
T
kate522 aad83072a8 refactor(pay): 统一流水号,移除订单/流水/提现三类号码前缀
订单号、资金流水号、提现单号此前各自带前缀配置,同一笔业务在不同界面会
呈现多个号码口径,对账与客诉排查都要先做一次前缀换算。现收敛为单一流水号
分配器,不再按业务类型区分号码形态。

- 删除 payment_order_prefix / payment_flow_prefix /
  payment_withdrawal_prefix 三项配置项及其生成、校验链路
- BusinessNumber::allocate() 成为唯一入口,输出 {YmdHis}{6 位随机},
  共 20 位无前缀,满足 VARCHAR(32) 与网关 out_trade_no ≤ 32 的限制
- 订单、资金流水、提现、卡密渠道交易号四处生成点全部改走该分配器
- 后台支付中心表头「订单号 / 提现单号」统一为「流水号」
- 前台用户中心与订单卡片文案同步统一;前台订单详情合并为单行流水号,
  账本流水号不再下发到前台,避免同一单据出现两个对外号码
- 同步更新 financial-flow / pay-card / card-pass-order-numbers 契约测试
  与 BusinessNumberTest 断言

按用户要求不做双路逻辑与数据迁移,直接替换为统一方案,历史行不做转换。

验证:node --test tests/**/*.test.cjs 362/364 通过,新增 37 项契约;失败的
2 项在改动前的干净 HEAD 基线上同样失败(基线 327 项 / 失败 2 项),分别命中
遗留的 fa fa- 标记与 FA 版本号断言,与本次改动无关。phpunit 44 项 / 103
断言全部通过;php -l 全部改动的 PHP 文件通过。
2026-09-18 22:14:27 +08:00

148 lines
7.7 KiB
PHP

<?php
/**
* User center creator income panel.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
$context = is_array($args['context'] ?? null) ? $args['context'] : [];
$user_id = (int) ($context['user_id'] ?? get_current_user_id());
if ($user_id <= 0) {
echo '<div class="uc-panel-empty muted-2-color">' . esc_html__('请先登录', 'aksrt') . '</div>';
return;
}
$settings = class_exists('\\AKSRT\\Settings\\Settings')
? \AKSRT\Settings\Settings::get_payment_revenue_settings()
: [];
if (empty($settings['enabled'])) {
echo '<div class="uc-panel-empty muted-2-color">' . esc_html__('创作收益功能暂未开启。', 'aksrt') . '</div>';
return;
}
$request = is_array($context['creator_income_request'] ?? null) ? $context['creator_income_request'] : [];
$page = max(1, min(100, (int) ($request['page'] ?? ($_GET['income_page'] ?? 1))));
$view = class_exists('\\AKSRT\\Payment\\Revenue')
? \AKSRT\Payment\Revenue::get_instance()->get_user_income_view($user_id, ['page' => $page])
: ['stats' => [], 'items' => [], 'total' => 0, 'max_pages' => 1, 'page' => 1];
$stats = (array) ($view['stats'] ?? []);
$items = (array) ($view['items'] ?? []);
$base_url = function_exists('aksrt_get_user_center_tab_url')
? aksrt_get_user_center_tab_url('creator')
: home_url('/profile/?tab=creator');
$page_url = static function (int $target_page) use ($base_url): string {
return add_query_arg(
['tab' => 'creator', 'income_page' => max(1, $target_page)],
remove_query_arg(['income_currency', 'income_status', 'income_page'], $base_url)
);
};
$format = static function ($amount, string $unit): string {
if ($unit === 'points') {
return aksrt_format_points(max(0, (int) $amount));
}
try {
return \AKSRT\Ledger\AssetAmount::balance(is_string($amount) ? $amount : '')->formatted();
} catch (\InvalidArgumentException $e) {
return '0.00';
}
};
$note = trim((string) ($settings['note'] ?? ''));
if ($note === '') {
$note = __('<p>订单完成并经过结算周期后,作者分成会自动转入对应的钱包。</p>', 'aksrt');
}
$status_labels = [
'pending' => __('待结算', 'aksrt'),
'settled' => __('已结算', 'aksrt'),
];
$currency_labels = [
'CNY' => __('现金收益', 'aksrt'),
'points' => __('积分收益', 'aksrt'),
];
?>
<div class="creator-income" data-creator-income>
<section class="creator-income__cards" aria-label="<?php esc_attr_e('收益概览', 'aksrt'); ?>">
<?php foreach (['CNY' => __('现金收益', 'aksrt'), 'points' => __('积分收益', 'aksrt')] as $unit => $label) : ?>
<article class="creator-income-card creator-income-card--<?php echo esc_attr(strtolower($unit)); ?>">
<h2><?php echo esc_html($label); ?></h2>
<div class="creator-income-card__metrics">
<?php foreach (['today' => __('今日收入', 'aksrt'), 'total' => __('累计收益', 'aksrt'), 'pending' => __('待结算', 'aksrt'), 'settled' => __('已结算', 'aksrt')] as $metric => $metric_label) : ?>
<span>
<strong><?php echo esc_html($format($stats[$metric][$unit] ?? 0, $unit)); ?></strong>
<small><?php echo esc_html($metric_label); ?></small>
</span>
<?php endforeach; ?>
</div>
</article>
<?php endforeach; ?>
</section>
<section class="creator-income__info widget-card">
<h2><?php esc_html_e('结算备注', 'aksrt'); ?></h2>
<div><?php echo wp_kses_post($note); ?></div>
</section>
<section class="creator-income__details widget-card">
<div class="creator-income__toolbar">
<div>
<h2><?php esc_html_e('收入明细', 'aksrt'); ?></h2>
<p><?php esc_html_e('按产生时间倒序显示,每页 20 条。', 'aksrt'); ?></p>
</div>
</div>
<?php if (!$items) : ?>
<div class="creator-income__empty">
<i class="fa fas fa-chart-line" aria-hidden="true"></i>
<p><?php esc_html_e('暂无收益明细', 'aksrt'); ?></p>
</div>
<?php else : ?>
<div class="creator-income__list" role="list" aria-label="<?php esc_attr_e('收入明细', 'aksrt'); ?>">
<?php foreach ($items as $item) :
$unit = (string) ($item['currency'] ?? 'CNY') === 'points' ? 'points' : 'CNY';
$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');
$post = get_post((int) ($item['post_id'] ?? 0));
$source = $post instanceof WP_Post && $post->post_type === 'post'
? get_the_title($post)
: __('内容已删除', 'aksrt');
$source = trim((string) $source) !== '' ? (string) $source : __('内容已删除', 'aksrt');
$created_at = trim((string) ($item['created_at'] ?? ''));
$time_label = '';
$time_datetime = '';
if ($created_at !== '') {
try {
$created = new DateTimeImmutable($created_at, wp_timezone());
$time_datetime = $created->format('c');
$time_label = wp_date(get_option('date_format') . ' ' . get_option('time_format'), $created->getTimestamp());
} catch (Exception $exception) {
$time_label = '';
}
}
?>
<article class="creator-income-row" role="listitem">
<span class="creator-income-row__order" title="<?php echo esc_attr($order_number); ?>"><?php echo esc_html($order_number); ?></span>
<span class="creator-income-row__currency"><?php echo esc_html($currency_labels[$unit === 'points' ? 'points' : 'CNY']); ?></span>
<span class="creator-income-row__source" title="<?php echo esc_attr($source); ?>"><?php echo esc_html($source); ?></span>
<span class="creator-income-row__detail">
<strong class="creator-income-row__amount">+<?php echo esc_html($amount . ($unit === 'points' ? __('积分', 'aksrt') : __('现金', 'aksrt'))); ?></strong>
<?php if ($time_label !== '') : ?>
<time class="creator-income-row__time" datetime="<?php echo esc_attr($time_datetime); ?>"><?php echo esc_html($time_label); ?></time>
<?php endif; ?>
<span class="creator-income-row__status creator-income-row__status--<?php echo esc_attr($status); ?>"><?php echo esc_html($status_labels[$status]); ?></span>
</span>
</article>
<?php endforeach; ?>
</div>
<?php if ((int) ($view['max_pages'] ?? 1) > 1) : ?>
<nav class="creator-income__pagination" aria-label="<?php esc_attr_e('收入明细分页', 'aksrt'); ?>">
<?php for ($i = 1; $i <= (int) $view['max_pages']; $i++) : ?>
<a class="<?php echo $i === (int) ($view['page'] ?? $page) ? 'is-active' : ''; ?>" href="<?php echo esc_url($page_url($i)); ?>"><?php echo esc_html((string) $i); ?></a>
<?php endfor; ?>
</nav>
<?php endif; ?>
<?php endif; ?>
</section>
</div>