ensure_cap();
$this->render_header(__('创作分成', 'aksrt'));
if (!class_exists('\AKSRT\Payment\Revenue')) {
echo '
' . esc_html__('分成模块未初始化。', 'aksrt') . '
';
$this->render_footer();
return;
}
$status = isset($_GET['status']) ? sanitize_key((string) wp_unslash($_GET['status'])) : '';
$order_status = isset($_GET['order_status']) ? sanitize_key((string) wp_unslash($_GET['order_status'])) : '';
$user_id = isset($_GET['user_id']) ? max(0, (int) $_GET['user_id']) : 0;
$post_id = isset($_GET['post_id']) ? max(0, (int) $_GET['post_id']) : 0;
$currency = isset($_GET['currency']) ? strtolower(sanitize_key((string) wp_unslash($_GET['currency']))) : '';
if ($currency === 'cny') {
$currency = 'CNY';
}
$order_number = isset($_GET['order_number']) ? sanitize_text_field((string) wp_unslash($_GET['order_number'])) : '';
$date_from = isset($_GET['date_from']) ? sanitize_text_field((string) wp_unslash($_GET['date_from'])) : '';
$date_to = isset($_GET['date_to']) ? sanitize_text_field((string) wp_unslash($_GET['date_to'])) : '';
$page_num = max(1, (int) ($_GET['paged'] ?? 1));
$per_page = AdminListPagination::DEFAULT_PER_PAGE;
$order_statuses = class_exists('\\AKSRT\\Payment\\Order')
? \AKSRT\Payment\Order::get_valid_statuses()
: [];
$svc = \AKSRT\Payment\Revenue::get_instance();
$stats = $user_id > 0 ? $svc->get_stats($user_id) : $svc->get_stats();
$cash_stats = (array) ($stats['cash'] ?? []);
$points_stats = (array) ($stats['points'] ?? []);
$cash_amount = static function ($value): string {
try {
return \AKSRT\Ledger\AssetAmount::balance(is_string($value) ? $value : '')->formatted();
} catch (\InvalidArgumentException $e) {
return '0.00';
}
};
echo '' . esc_html(sprintf(
__('现金:合计 ¥%1$s · 待结算 ¥%2$s · 已结算 ¥%3$s;积分:合计 %4$s · 待结算 %5$s · 已结算 %6$s', 'aksrt'),
$cash_amount($cash_stats['total'] ?? '0'),
$cash_amount($cash_stats['pending'] ?? '0'),
$cash_amount($cash_stats['settled'] ?? '0'),
number_format_i18n(max(0, (int) ($points_stats['total'] ?? 0))),
number_format_i18n(max(0, (int) ($points_stats['pending'] ?? 0))),
number_format_i18n(max(0, (int) ($points_stats['settled'] ?? 0)))
)) . '
';
echo '';
echo '';
$list_args = [
'status' => $status,
'order_status' => $order_status,
'limit' => $per_page,
'offset' => ($page_num - 1) * $per_page,
'post_id' => $post_id,
'currency' => $currency,
'order_number' => $order_number,
'date_from' => $date_from,
'date_to' => $date_to,
];
if ($user_id > 0) {
$list_args['user_id'] = $user_id;
}
$result = $svc->get_list($list_args);
$items = $result['items'] ?? [];
$total = (int) ($result['total'] ?? 0);
$pages = max(1, (int) ceil($total / $per_page));
// 页码越界(手工改 URL、或筛选后总数变小)会让 offset 落到数据之外:表格空掉
// 且分页条不输出,只能手改 URL 退出。回退到最后一页重查一次。
if ($page_num > $pages) {
$page_num = $pages;
$list_args['offset'] = ($page_num - 1) * $per_page;
$result = $svc->get_list($list_args);
$items = $result['items'] ?? [];
}
// 翻页链接显式带上当前筛选条件(不含 paged)。必须在下面的行循环之前取好:
// 循环里 $user_id 会被每行的 author_id 覆盖。
$query_args = array_filter([
'status' => $status !== '' ? $status : null,
'order_status' => $order_status !== '' ? $order_status : null,
'user_id' => $user_id > 0 ? $user_id : null,
'post_id' => $post_id > 0 ? $post_id : null,
'currency' => $currency !== '' ? $currency : null,
'order_number' => $order_number !== '' ? $order_number : null,
'date_from' => $date_from !== '' ? $date_from : null,
'date_to' => $date_to !== '' ? $date_to : null,
], static function ($value): bool {
return $value !== null;
});
echo '';
AdminListPagination::render(self::PAGE_SLUG, $total, $page_num, $per_page, $query_args);
$this->render_footer();
}
public function handle_settle_income(): void {
if (!current_user_can(self::CAPABILITY)) {
wp_die(esc_html__('权限不足', 'aksrt'));
}
$id = isset($_POST['revenue_id']) ? (int) $_POST['revenue_id'] : 0;
check_admin_referer('aksrt_pay_settle_income_' . $id);
$request_key = sanitize_text_field((string) wp_unslash($_POST['operation_key'] ?? ''));
$operation_key = wp_is_uuid($request_key)
? \AKSRT\Ledger\OperationKey::deterministic('admin-revenue-settle', [get_current_user_id(), strtolower($request_key)])
: '';
$ok = $id > 0 && $operation_key !== '' && class_exists('\AKSRT\Payment\Revenue') && \AKSRT\Payment\Revenue::get_instance()->settle($id, get_current_user_id(), $operation_key);
wp_safe_redirect($this->page_url('aksrt_income', ['aksrt_pay_msg' => $ok ? 'income_settled' : 'income_failed']));
exit;
}
public function handle_batch_settle_income(): void {
if (!current_user_can(self::CAPABILITY)) {
wp_die(esc_html__('权限不足', 'aksrt'));
}
check_admin_referer('aksrt_pay_batch_settle_income');
$raw_ids = isset($_POST['revenue_ids']) ? wp_unslash($_POST['revenue_ids']) : [];
$ids = [];
if (is_array($raw_ids)) {
foreach ($raw_ids as $raw_id) {
$id = (int) $raw_id;
if ($id > 0) {
$ids[] = $id;
}
}
}
$ids = array_values(array_unique($ids));
$request_key = sanitize_text_field((string) wp_unslash($_POST['operation_key'] ?? ''));
$operation_key = wp_is_uuid($request_key)
? \AKSRT\Ledger\OperationKey::deterministic('admin-revenue-settle-batch', [get_current_user_id(), strtolower($request_key)])
: '';
$batch_result = !empty($ids) && $operation_key !== '' && class_exists('\\AKSRT\\Payment\\Revenue')
? \AKSRT\Payment\Revenue::get_instance()->settle_batch($ids, get_current_user_id(), $operation_key)
: ['settled' => [], 'failed' => $ids];
$message = empty($batch_result['settled'])
? 'income_failed'
: (!empty($batch_result['failed']) ? 'income_batch_partial' : 'income_batch_settled');
wp_safe_redirect($this->page_url('aksrt_income', ['aksrt_pay_msg' => $message]));
exit;
}
private function ensure_cap(): void {
if (!current_user_can(self::CAPABILITY)) {
wp_die(esc_html__('您没有权限访问此页面。', 'aksrt'));
}
}
private function render_header(string $title): void {
echo '';
echo '
' . esc_html($title) . '
';
$this->render_flash();
}
private function render_footer(): void {
echo '';
}
private function render_flash(): void {
if (empty($_GET['aksrt_pay_msg'])) {
return;
}
$code = sanitize_key((string) wp_unslash($_GET['aksrt_pay_msg']));
$map = [
'income_settled' => __('分成已结算。', 'aksrt'),
'income_batch_settled' => __('选中分成已批量结算。', 'aksrt'),
'income_batch_partial' => __('部分分成已结算,失败记录可稍后重试。', 'aksrt'),
'income_failed' => __('分成结算失败。', 'aksrt'),
];
if (!isset($map[$code])) {
return;
}
$class = $code === 'income_batch_partial'
? 'notice-warning'
: (str_contains($code, 'failed') ? 'notice-error' : 'notice-success');
echo '' . esc_html($map[$code]) . '
';
}
private function page_url(string $slug, array $args = []): string {
return add_query_arg(array_merge(['page' => $slug], $args), admin_url('admin.php'));
}
}