feat(payment): separate creator income settlement

This commit is contained in:
kate522 committed 2026-08-07 12:39:32 +08:00
1 parent cd93ea1656
commit e20418e909
17 files changed
+451 -445

No files matched your search

+2 -2
View File
@@ -109,7 +109,7 @@ if (!function_exists('aksrt_get_user_center_tab_url')) {
$url = remove_query_arg([
'tab', 'posts_page', 'comments_page', 'favorites_page', 'credits_page',
'post_status', 'creator_page', 'creator_status', 'saved', 'profile_error',
'order_tab', 'otab', 'order_status', 'order_page', 'order_type', 'section',
'order_tab', 'otab', 'order_status', 'order_page', 'order_type', 'income_currency', 'income_status', 'income_page', 'section',
], aksrt_get_user_center_url());
return add_query_arg('tab', $tab, $url);
@@ -480,7 +480,7 @@ if (!function_exists('aksrt_get_user_center_render_context')) {
$post_status_filter = 'publish';
}
$user_status_counts = ['publish' => 0, 'draft' => 0, 'pending' => 0, 'private' => 0];
if ('posts' === $active_tab || 'creator' === $active_tab) {
if ('posts' === $active_tab) {
$status = aksrt_user_center_post_status_counts($user_id);
$user_status_counts = $status['counts'];
$post_count = $status['total'];
@@ -13,35 +13,102 @@ 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() : [];
$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'] : [];
$currency = sanitize_key((string) ($request['currency'] ?? ($_GET['income_currency'] ?? '')));
$status = sanitize_key((string) ($request['status'] ?? ($_GET['income_status'] ?? '')));
$currency = in_array($currency, ['', 'CNY', 'points'], true) ? $currency : '';
$status = in_array($status, ['', 'pending', 'settled', 'cancelled', 'reversed', 'pending_recovery'], true) ? $status : '';
$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, ['currency' => $currency, 'status' => $status, 'page' => $page]) : ['stats' => [], 'items' => [], 'max_pages' => 1, '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');
$filter_url = static function (array $extra) use ($base_url): string { return add_query_arg(array_merge(['tab' => 'creator'], $extra), remove_query_arg(['income_page'])); };
$format = static function ($amount, string $unit): string { return number_format_i18n((float) $amount, $unit === 'points' ? 0 : 2); };
$status_labels = ['pending' => __('待结算', 'aksrt'), 'settled' => __('已入钱包', 'aksrt'), 'cancelled' => __('已取消', 'aksrt'), 'reversed' => __('已冲正', 'aksrt'), 'pending_recovery' => __('待追缴', 'aksrt')];
$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 {
return number_format_i18n((float) $amount, $unit === 'points' ? 0 : 2);
};
$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>
<header class="creator-income__hero"><p><?php esc_html_e('作者收益', 'aksrt'); ?></p><h2><?php esc_html_e('创作中心', 'aksrt'); ?></h2><p><?php esc_html_e('查看付费内容带来的现金和积分收益。', 'aksrt'); ?></p></header>
<nav class="creator-income__tabs" aria-label="<?php esc_attr_e('收益货币筛选', 'aksrt'); ?>">
<?php foreach (['' => __('全部', 'aksrt'), 'CNY' => __('现金收益', 'aksrt'), 'points' => __('积分收益', 'aksrt')] as $key => $label) : ?><a class="creator-income__tab<?php echo $currency === $key ? ' is-active' : ''; ?>" href="<?php echo esc_url($filter_url(['income_currency' => $key, 'income_status' => $status])); ?>"><?php echo esc_html($label); ?></a><?php endforeach; ?>
</nav>
<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"><h3><?php echo esc_html($label); ?></h3><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; ?>
<?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"><h3><?php esc_html_e('创作分成说明', 'aksrt'); ?></h3><div><?php echo wp_kses((string) ($settings['description'] ?? $settings['note'] ?? __('订单完成并经过结算延迟后,作者分成会进入对应的钱包。退款订单会取消或冲正收益。', 'aksrt')), ['p' => [], 'br' => [], 'strong' => [], 'em' => [], 'ul' => [], 'ol' => [], 'li' => []]); ?></div></section>
<section class="creator-income__details widget-card"><div class="creator-income__toolbar"><div><h3><?php esc_html_e('收入明细', 'aksrt'); ?></h3><p><?php esc_html_e('按产生时间倒序显示,每页 20 条。', 'aksrt'); ?></p></div><form method="get" action="<?php echo esc_url($base_url); ?>"><input type="hidden" name="tab" value="creator" /><input type="hidden" name="income_currency" value="<?php echo esc_attr($currency); ?>" /><label><?php esc_html_e('状态', 'aksrt'); ?> <select name="income_status" onchange="this.form.submit()"><option value=""><?php esc_html_e('全部状态', 'aksrt'); ?></option><?php foreach ($status_labels as $key => $label) : ?><option value="<?php echo esc_attr($key); ?>"<?php selected($status, $key); ?>><?php echo esc_html($label); ?></option><?php endforeach; ?></select></label></form></div>
<?php if (!$items) : ?><div class="creator-income__empty"><i class="fas fa-chart-line" aria-hidden="true"></i><p><?php esc_html_e('暂无收益明细', 'aksrt'); ?></p></div><?php else : ?><div class="creator-income__table-wrap"><table class="creator-income__table"><thead><tr><th><?php esc_html_e('文章', 'aksrt'); ?></th><th><?php esc_html_e('订单', 'aksrt'); ?></th><th><?php esc_html_e('支付金额', 'aksrt'); ?></th><th><?php esc_html_e('作者分成', 'aksrt'); ?></th><th><?php esc_html_e('状态', 'aksrt'); ?></th><th><?php esc_html_e('产生时间', 'aksrt'); ?></th></tr></thead><tbody><?php foreach ($items as $item) : $post = get_post((int) ($item['post_id'] ?? 0)); $unit = (string) ($item['currency'] ?? 'CNY'); ?><tr><td><?php echo esc_html($post ? get_the_title($post) : __('已删除文章', 'aksrt')); ?></td><td><code><?php echo esc_html((string) ($item['order_number'] ?? '')); ?></code></td><td><?php echo esc_html($format($item['original_amount'] ?? 0, $unit) . ' ' . $unit); ?></td><td><?php echo esc_html($format($item['amount'] ?? 0, $unit) . ' ' . $unit); ?></td><td><span class="creator-income-status creator-income-status--<?php echo esc_attr(sanitize_key((string) ($item['status'] ?? ''))); ?>"><?php echo esc_html($status_labels[$item['status'] ?? ''] ?? (string) ($item['status'] ?? '')); ?></span></td><td><?php echo esc_html((string) ($item['created_at'] ?? '')); ?></td></tr><?php endforeach; ?></tbody></table></div><?php endif; ?>
<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">
<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="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);
?>
<article class="creator-income-row" role="listitem">
<span class="creator-income-row__currency"><?php echo esc_html($currency_labels[$unit === 'points' ? 'points' : 'CNY']); ?></span>
<strong class="creator-income-row__amount">+<?php echo esc_html($amount . ($unit === 'points' ? __('积分', 'aksrt') : __('现金', 'aksrt'))); ?></strong>
<span class="creator-income-row__status creator-income-row__status--<?php echo esc_attr($status); ?>"><?php echo esc_html($status_labels[$status]); ?></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>