-
+
+
+
{{ group.label }}
+
-
{{ formatLabel(item.date) }}
+ v-for="(item, index) in group.items"
+ :key="`${group.key}-${index}`"
+ class="aksrt-revenue__chart-bar-wrap"
+ :title="`${item.date}: ${formatAmount(item.amount, group.key)} (${item.count}笔)`"
+ >
+
+
{{ formatLabel(item.date) }}
+
+
+
+
+ 期间总计: {{ formatAmount(group.total, group.key) }}
+ 共 {{ group.count }} 笔
-
-
- 期间总计: ¥{{ periodTotal.toFixed(2) }}
- 共 {{ periodCount }} 笔
@@ -119,23 +105,53 @@ import { ref, computed, onMounted } from 'vue'
import PaymentSectionPage from '@/pages/payment/PaymentSectionPage.vue'
import api from '@/api'
-const revenueStats = ref({ total: 0, pending: 0, settled: 0, count: 0 })
+const emptyCurrencyStats = () => ({ total: 0, pending: 0, settled: 0, count: 0 })
+const revenueStats = ref({ cash: emptyCurrencyStats(), points: emptyCurrencyStats() })
const withdrawalStats = ref({ total: 0, pending: 0, processing: 0, completed: 0, rejected: 0, total_paid: 0 })
-const timeSeries = ref([])
+const timeSeries = ref({ cash: [], points: [] })
const granularity = ref('day')
-const periodTotal = computed(() => timeSeries.value.reduce((s, i) => s + i.amount, 0))
-const periodCount = computed(() => timeSeries.value.reduce((s, i) => s + i.count, 0))
-const maxAmount = computed(() => Math.max(1, ...timeSeries.value.map(i => i.amount)))
+const revenueSummary = computed(() => [
+ { key: 'cash-total', value: `${revenueStats.value.cash.total.toFixed(2)} 元`, label: '现金总收益' },
+ { key: 'cash-pending', value: `${revenueStats.value.cash.pending.toFixed(2)} 元`, label: '现金待结算' },
+ { key: 'cash-settled', value: `${revenueStats.value.cash.settled.toFixed(2)} 元`, label: '现金已结算' },
+ { key: 'cash-count', value: revenueStats.value.cash.count, label: '现金收益笔数' },
+ { key: 'points-total', value: `${formatAmount(revenueStats.value.points.total, 'points')}`, label: '积分总收益' },
+ { key: 'points-pending', value: `${formatAmount(revenueStats.value.points.pending, 'points')}`, label: '积分待结算' },
+ { key: 'points-settled', value: `${formatAmount(revenueStats.value.points.settled, 'points')}`, label: '积分已结算' },
+ { key: 'points-count', value: revenueStats.value.points.count, label: '积分收益笔数' },
+])
-function getBarHeight(amount) {
- return Math.max(2, (amount / maxAmount.value) * 100)
+const timeSeriesGroups = computed(() => [
+ {
+ key: 'cash',
+ label: '现金收益',
+ items: Array.isArray(timeSeries.value.cash) ? timeSeries.value.cash : [],
+ },
+ {
+ key: 'points',
+ label: '积分收益',
+ items: Array.isArray(timeSeries.value.points) ? timeSeries.value.points : [],
+ },
+].map((group) => ({
+ ...group,
+ total: group.items.reduce((sum, item) => sum + Number(item.amount || 0), 0),
+ count: group.items.reduce((sum, item) => sum + Number(item.count || 0), 0),
+})))
+
+const hasTimeSeries = computed(() => timeSeriesGroups.value.some((group) => group.items.length > 0))
+
+function formatAmount(amount, currency) {
+ return currency === 'points' ? `${Number(amount || 0).toFixed(0)} 积分` : `¥${Number(amount || 0).toFixed(2)}`
+}
+
+function getBarHeight(amount, items) {
+ const maxAmount = Math.max(1, ...items.map((item) => Number(item.amount || 0)))
+ return Math.max(2, (Number(amount || 0) / maxAmount) * 100)
}
function formatLabel(date) {
- if (granularity.value === 'month') return date.slice(5)
- if (granularity.value === 'week') return date.slice(5)
- return date.slice(5)
+ return String(date || '').slice(5)
}
function setGranularity(nextGranularity) {
@@ -153,10 +169,8 @@ async function loadRevenue() {
if (res?.data) {
if (res.data.revenue) {
revenueStats.value = {
- total: Number(res.data.revenue.total || 0),
- pending: Number(res.data.revenue.pending || 0),
- settled: Number(res.data.revenue.settled || 0),
- count: Number(res.data.revenue.count || 0),
+ cash: { ...emptyCurrencyStats(), ...(res.data.revenue.cash || {}) },
+ points: { ...emptyCurrencyStats(), ...(res.data.revenue.points || {}) },
}
}
if (res.data.withdrawal) {
@@ -169,7 +183,10 @@ async function loadRevenue() {
total_paid: Number(res.data.withdrawal.total_paid || 0),
}
}
- timeSeries.value = res.data.time_series || []
+ timeSeries.value = {
+ cash: res.data.time_series?.cash || [],
+ points: res.data.time_series?.points || [],
+ }
}
} catch {
// silent
@@ -200,10 +217,20 @@ onMounted(loadRevenue)
color: var(--color-ink-4, #8a909c);
}
+.aksrt-revenue__charts {
+ display: grid;
+ gap: 24px;
+}
+
.aksrt-revenue__chart {
min-height: 200px;
}
+.aksrt-revenue__chart h4 {
+ margin: 0 0 10px;
+ color: var(--color-ink, #1a1a2e);
+}
+
.aksrt-revenue__chart-bars {
display: flex;
align-items: flex-end;
diff --git a/assets/admin/src/schema/sections/payment/revenue.js b/assets/admin/src/schema/sections/payment/revenue.js
index 22ac339d..c7ffb874 100644
--- a/assets/admin/src/schema/sections/payment/revenue.js
+++ b/assets/admin/src/schema/sections/payment/revenue.js
@@ -2,46 +2,47 @@ export const revenueSchema = {
key: 'payment.revenue',
title: '创作分成',
icon: 'fas fa-chart-line',
- description: '配置作者分成比例、结算门槛和结算周期。',
+ description: '分别配置现金收益和积分收益的会员分成比例,结算周期结束后自动入账。',
defaults: {
pay_income_s: false,
- payment_revenue_share_ratio: 70,
- ratio_vip_1: 0,
- ratio_vip_2: 0,
- payment_revenue_settlement_threshold: 100,
payment_revenue_cycle_days: 30,
- payment_revenue_settlement_mode: 'automatic',
- payment_revenue_settlement_delay_hours: 24,
- payment_revenue_points_rule: '',
- payment_revenue_note: '分成规则已就绪,订单入账后自动按比例结算。',
- pay_income_desc_details: '',
- pay_income_desc_page: '',
+ payment_revenue_note: '
订单完成并经过结算周期后,作者分成会自动转入对应的钱包。
',
+ payment_revenue_cash_ratio_user: 60,
+ payment_revenue_cash_ratio_vip_1: 70,
+ payment_revenue_cash_ratio_vip_2: 80,
+ payment_revenue_points_ratio_user: 0,
+ payment_revenue_points_ratio_vip_1: 0,
+ payment_revenue_points_ratio_vip_2: 0,
},
groups: [
{
- key: 'policy',
- title: '分成策略',
- icon: 'fas fa-percentage',
+ key: 'basic',
+ title: '创作分成设置',
+ icon: 'fas fa-cog',
fields: [
- { key: 'pay_income_s', label: '启用创作分成结构', type: 'switch', default: false },
- { key: 'payment_revenue_share_ratio', label: '作者分成比例(%)', type: 'number', default: 70, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'ratio_vip_1', label: 'VIP1分成比例(%)', type: 'number', default: 0, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'ratio_vip_2', label: 'VIP2分成比例(%)', type: 'number', default: 0, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'payment_revenue_settlement_threshold', label: '最小结算金额', type: 'number', default: 100, min: 0, max: 100000, dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'pay_income_s', label: '启用创作分成', type: 'switch', default: false },
{ key: 'payment_revenue_cycle_days', label: '结算周期(天)', type: 'number', default: 30, min: 1, max: 365, dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'payment_revenue_settlement_mode', label: '结算模式', type: 'select', default: 'automatic', options: [{ value: 'automatic', label: '自动结算' }, { value: 'manual', label: '手动结算' }], dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'payment_revenue_settlement_delay_hours', label: '结算延迟(小时)', type: 'number', default: 24, min: 0, max: 8760, dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'payment_revenue_points_rule', label: '积分规则', type: 'textarea', default: '', dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'payment_revenue_note', label: '结算备注', type: 'textarea', default: '分成策略和台账结构已就绪,订单入账后自动按比例结算。', dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_note', label: '结算备注文案', type: 'textarea', sanitize_type: 'html', default: '
订单完成并经过结算周期后,作者分成会自动转入对应的钱包。
', help: '支持安全 HTML,结算后会展示在前台创作中心。', dependsOn: { key: 'pay_income_s', value: true } },
],
},
{
- key: 'display',
- title: '展示设置',
- icon: 'fas fa-file-alt',
+ key: 'cash',
+ title: '现金收益分成',
+ icon: 'fas fa-wallet',
fields: [
- { key: 'pay_income_desc_details', label: '收益明细文案', type: 'textarea', default: '', dependsOn: { key: 'pay_income_s', value: true } },
- { key: 'pay_income_desc_page', label: '收益说明页', type: 'input', default: '', dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_cash_ratio_user', label: '普通用户分成比例(%)', type: 'number', default: 60, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_cash_ratio_vip_1', label: '一级会员分成比例(%)', type: 'number', default: 70, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_cash_ratio_vip_2', label: '二级会员分成比例(%)', type: 'number', default: 80, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
+ ],
+ },
+ {
+ key: 'points',
+ title: '积分收益分成',
+ icon: 'fas fa-coins',
+ fields: [
+ { key: 'payment_revenue_points_ratio_user', label: '普通用户分成比例(%)', type: 'number', default: 0, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_points_ratio_vip_1', label: '一级会员分成比例(%)', type: 'number', default: 0, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
+ { key: 'payment_revenue_points_ratio_vip_2', label: '二级会员分成比例(%)', type: 'number', default: 0, min: 0, max: 100, dependsOn: { key: 'pay_income_s', value: true } },
],
},
],
diff --git a/assets/css/routes/profile/lists.css b/assets/css/routes/profile/lists.css
index 70a1b809..08fdd582 100644
--- a/assets/css/routes/profile/lists.css
+++ b/assets/css/routes/profile/lists.css
@@ -710,8 +710,47 @@
}
/* ==================== 作者收益中心 ==================== */
-.creator-income { display:flex; flex-direction:column; gap:16px; }.creator-income__hero { padding:24px 26px; border-radius:var(--radius-lg); color:#fff; background:linear-gradient(135deg,var(--color-primary),#7c3aed); }.creator-income__hero p { margin:0 0 6px; opacity:.82; font-size:13px; }.creator-income__hero h2 { margin:0; color:inherit; }.creator-income__tabs { display:flex; gap:8px; flex-wrap:wrap; }.creator-income__tab { padding:7px 12px; border-radius:var(--radius-pill); color:var(--color-ink-3); text-decoration:none; }.creator-income__tab.is-active,.creator-income__tab:hover { color:var(--color-primary); background:var(--color-primary-soft); }.creator-income__cards { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }.creator-income-card { padding:18px; border:1px solid var(--color-line); border-radius:var(--radius-lg); background:var(--surface-1); }.creator-income-card h3 { margin:0 0 14px; }.creator-income-card__metrics { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px; }.creator-income-card__metrics strong,.creator-income-card__metrics small { display:block; }.creator-income-card__metrics strong { color:var(--color-ink); font-size:18px; }.creator-income-card__metrics small { margin-top:4px; color:var(--color-ink-4); font-size:11px; }.creator-income__info,.creator-income__details { padding:20px; }.creator-income__info h3,.creator-income__toolbar h3 { margin:0; }.creator-income__info div,.creator-income__toolbar p { margin:6px 0 0; color:var(--color-ink-4); font-size:13px; }.creator-income__toolbar { display:flex; justify-content:space-between; align-items:flex-end; gap:12px; margin-bottom:14px; }.creator-income__table-wrap { overflow-x:auto; }.creator-income__table { width:100%; border-collapse:collapse; font-size:12px; }.creator-income__table th,.creator-income__table td { padding:10px 8px; border-bottom:1px solid var(--color-line); text-align:left; white-space:nowrap; }.creator-income-status { padding:3px 7px; border-radius:var(--radius-pill); color:var(--color-primary); background:var(--color-primary-soft); }.creator-income-status--cancelled,.creator-income-status--reversed { color:var(--color-ink-4); background:var(--surface-2); }.creator-income-status--pending_recovery { color:var(--color-error); background:rgba(220,38,38,.08); }.creator-income__empty { padding:40px 20px; text-align:center; color:var(--color-ink-4); }.creator-income__empty i { font-size:28px; color:var(--color-primary); } .creator-income__details select { margin-left:6px; }
-@media (max-width:767px) { .creator-income__cards { grid-template-columns:1fr; }.creator-income-card__metrics { grid-template-columns:repeat(2,minmax(0,1fr)); }.creator-income__toolbar { align-items:flex-start; flex-direction:column; } }
+.creator-income { display: flex; flex-direction: column; gap: 16px; }
+.creator-income__cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
+.creator-income-card { padding: 18px; border: 1px solid var(--color-line); border-radius: var(--radius-lg); background: var(--surface-1); }
+.creator-income-card h2 { margin: 0 0 14px; font-size: 17px; }
+.creator-income-card--cny h2 { color: var(--color-primary); }
+.creator-income-card--points h2 { color: #16816c; }
+.creator-income-card__metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
+.creator-income-card__metrics strong,
+.creator-income-card__metrics small { display: block; }
+.creator-income-card__metrics strong { color: var(--color-ink); font-size: 18px; font-variant-numeric: tabular-nums; }
+.creator-income-card__metrics small { margin-top: 4px; color: var(--color-ink-4); font-size: 11px; }
+.creator-income__info { padding: 20px; }
+.creator-income__info h2,
+.creator-income__toolbar h2 { margin: 0; font-size: 16px; }
+.creator-income__info div,
+.creator-income__toolbar p { margin: 6px 0 0; color: var(--color-ink-4); font-size: 13px; line-height: 1.7; }
+.creator-income__details { padding: 4px 0 0; }
+.creator-income__toolbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
+.creator-income__list { border-top: 1px solid var(--color-line); }
+.creator-income-row { display: grid; grid-template-columns: minmax(110px, .8fr) minmax(0, 1fr) auto; align-items: center; gap: 14px; min-width: 0; padding: 14px 0; border-bottom: 1px solid var(--color-line); }
+.creator-income-row__currency { color: var(--color-ink-3); font-size: 13px; }
+.creator-income-row__amount { min-width: 0; overflow: hidden; color: #16816c; font-size: 15px; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
+.creator-income-row__status { justify-self: end; padding: 3px 8px; border-radius: var(--radius-pill); color: var(--color-ink-4); background: var(--surface-2); font-size: 11px; white-space: nowrap; }
+.creator-income-row__status--settled { color: #16816c; background: rgba(22, 129, 108, .1); }
+.creator-income-row__status--pending { color: #a86d28; background: rgba(168, 109, 40, .12); }
+.creator-income__pagination { display: flex; justify-content: center; gap: 6px; padding-top: 16px; }
+.creator-income__pagination a { display: grid; width: 30px; height: 30px; place-items: center; border-radius: 6px; color: var(--color-ink-3); background: var(--surface-2); font-size: 12px; text-decoration: none; }
+.creator-income__pagination a.is-active,
+.creator-income__pagination a:hover { color: #fff; background: var(--color-primary); }
+.creator-income__empty { padding: 40px 20px; color: var(--color-ink-4); text-align: center; }
+.creator-income__empty i { display: block; margin-bottom: 8px; color: var(--color-primary); font-size: 28px; }
+@media (max-width: 767px) {
+ .creator-income__cards { grid-template-columns: 1fr; }
+ .creator-income-card__metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
+}
+@media (max-width: 480px) {
+ .creator-income-row { grid-template-columns: minmax(82px, .8fr) minmax(0, 1fr) auto; gap: 8px; }
+ .creator-income-row__currency,
+ .creator-income-row__amount { font-size: 13px; }
+ .creator-income-row__status { padding-inline: 6px; }
+}
/* ==================== 独立创作中心工作台 ==================== */
.creator-workspace { display: flex; flex-direction: column; gap: 16px; }
diff --git a/assets/js/routes/user-center.js b/assets/js/routes/user-center.js
index 5a48424e..eed259cb 100644
--- a/assets/js/routes/user-center.js
+++ b/assets/js/routes/user-center.js
@@ -81,7 +81,7 @@
var url = restUrl.replace(/\/$/, '') + '/user-center/panel/' + encodeURIComponent(name);
if (name === 'creator') {
var params = new URLSearchParams(window.location.search);
- ['income_currency', 'income_status', 'income_page'].forEach(function(key) {
+ ['income_page'].forEach(function(key) {
if (params.get(key)) url += (url.indexOf('?') === -1 ? '?' : '&') + key + '=' + encodeURIComponent(params.get(key));
});
}
diff --git a/inc/helpers/aksrt-user-center.php b/inc/helpers/aksrt-user-center.php
index dc2b1002..36adb10d 100644
--- a/inc/helpers/aksrt-user-center.php
+++ b/inc/helpers/aksrt-user-center.php
@@ -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'];
diff --git a/inc/helpers/user-center-renderers/profile-creator.php b/inc/helpers/user-center-renderers/profile-creator.php
index d109796b..e73b0409 100644
--- a/inc/helpers/user-center-renderers/profile-creator.php
+++ b/inc/helpers/user-center-renderers/profile-creator.php
@@ -13,35 +13,102 @@ if ($user_id <= 0) {
echo '
' . esc_html__('请先登录', 'aksrt') . '
';
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 '
' . esc_html__('创作收益功能暂未开启。', 'aksrt') . '
';
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 = __('
订单完成并经过结算周期后,作者分成会自动转入对应的钱包。
', 'aksrt');
+}
+$status_labels = [
+ 'pending' => __('待结算', 'aksrt'),
+ 'settled' => __('已结算', 'aksrt'),
+];
+$currency_labels = [
+ 'CNY' => __('现金收益', 'aksrt'),
+ 'points' => __('积分收益', 'aksrt'),
+];
?>
-
-
- __('现金', 'aksrt'), 'points' => __('积分', 'aksrt')] as $unit => $label) : ?> __('今日收入', 'aksrt'), 'total' => __('累计收益', 'aksrt'), 'pending' => __('待结算', 'aksrt'), 'settled' => __('已入钱包', 'aksrt')] as $metric => $metric_label) : ?>
+ __('现金收益', 'aksrt'), 'points' => __('积分收益', 'aksrt')] as $unit => $label) : ?>
+
+
+
+ __('今日收入', 'aksrt'), 'total' => __('累计收益', 'aksrt'), 'pending' => __('待结算', 'aksrt'), 'settled' => __('已结算', 'aksrt')] as $metric => $metric_label) : ?>
+
+
+
+
+
+
+
+
-
-
diff --git a/src/Admin/Native/PayIncome.php b/src/Admin/Native/PayIncome.php
index dc2d126d..61aae314 100644
--- a/src/Admin/Native/PayIncome.php
+++ b/src/Admin/Native/PayIncome.php
@@ -51,12 +51,16 @@ class PayIncome {
$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'] ?? []);
echo '
' . esc_html(sprintf(
- /* translators: 1: total 2: pending 3: settled */
- __('合计 %1$s · 待结算 %2$s · 已结算 %3$s', 'aksrt'),
- number_format((float) ($stats['total'] ?? 0), 2),
- number_format((float) ($stats['pending'] ?? 0), 2),
- number_format((float) ($stats['settled'] ?? 0), 2)
+ __('现金:合计 ¥%1$s · 待结算 ¥%2$s · 已结算 ¥%3$s;积分:合计 %4$s · 待结算 %5$s · 已结算 %6$s', 'aksrt'),
+ number_format((float) ($cash_stats['total'] ?? 0), 2),
+ number_format((float) ($cash_stats['pending'] ?? 0), 2),
+ number_format((float) ($cash_stats['settled'] ?? 0), 2),
+ number_format((float) ($points_stats['total'] ?? 0), 0),
+ number_format((float) ($points_stats['pending'] ?? 0), 0),
+ number_format((float) ($points_stats['settled'] ?? 0), 0)
)) . '
';
echo '