feat(admin-web): 添加系统账户收益类型汇总统计功能

在数据统计-系统账户中新增5个统计Tab:
- 手续费账户汇总:统计成本费、运营费、总部社区基础费、RWAD底池注入
- 省团队收益汇总:统计省团队权益收益
- 市团队收益汇总:统计市团队权益收益
- 分享引荐收益汇总:统计分享权益收益
- 社区收益汇总:统计社区权益收益

后端变更:
- reward-service: 添加 getRewardsSummaryByType、getAllRewardTypeSummaries 方法
- reporting-service: 聚合收益类型汇总统计接口

前端变更:
- 添加 RewardTypeSummary、FeeAccountSummary 类型定义
- 添加 getRewardTypeSummaries API 方法
- 添加 FeeAccountSection、RewardTypeSummarySection 组件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-06 08:54:35 -08:00
parent bbafe58e86
commit 99b725db0a
9 changed files with 692 additions and 3 deletions

View File

@ -98,4 +98,15 @@ export class SystemAccountReportController {
endDate,
});
}
// [2026-01-06] 新增:收益类型汇总统计接口
// 用于系统账户报表中的:手续费汇总、省团队收益汇总、市团队收益汇总、分享引荐收益汇总、社区收益汇总
// 回滚方式:删除以下 API 方法即可
@Get('reward-type-summaries')
@ApiOperation({ summary: '获取所有收益类型汇总统计' })
@ApiResponse({ status: 200, description: '所有收益类型汇总' })
async getAllRewardTypeSummaries() {
this.logger.log(`[getAllRewardTypeSummaries] 请求所有收益类型汇总统计`);
return this.systemAccountReportService.getAllRewardTypeSummaries();
}
}

View File

@ -2,11 +2,12 @@
*
* [2026-01-04]
* [2026-01-05] wallet-service
* [2026-01-06]
* application.module.ts
*/
import { Injectable, Logger } from '@nestjs/common';
import { WalletServiceClient, OfflineSettlementSummary, AllSystemAccountsResponse, AllSystemAccountsLedgerResponse } from '../../infrastructure/external/wallet-service/wallet-service.client';
import { RewardServiceClient, ExpiredRewardsSummary } from '../../infrastructure/external/reward-service/reward-service.client';
import { RewardServiceClient, ExpiredRewardsSummary, AllRewardTypeSummaries } from '../../infrastructure/external/reward-service/reward-service.client';
/**
*
@ -200,6 +201,18 @@ export class SystemAccountReportApplicationService {
return result;
}
// [2026-01-06] 新增:获取所有收益类型汇总统计
/**
*
*
*/
async getAllRewardTypeSummaries(): Promise<AllRewardTypeSummaries> {
this.logger.log('[getAllRewardTypeSummaries] 开始获取所有收益类型汇总...');
const result = await this.rewardServiceClient.getAllRewardTypeSummaries();
this.logger.log(`[getAllRewardTypeSummaries] 完成`);
return result;
}
/**
*
*/

View File

@ -1,6 +1,7 @@
/**
* Reward Service HTTP
* [2026-01-04]
* [2026-01-06]
*
*/
@ -24,6 +25,37 @@ export interface ExpiredRewardsSummary {
}>;
}
// [2026-01-06] 新增:收益类型汇总接口类型
export interface RewardTypeSummary {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{
month: string;
amount: number;
count: number;
}>;
}
export interface FeeAccountSummary {
totalAmount: number;
totalCount: number;
breakdown: Array<{
rightType: string;
amount: number;
count: number;
}>;
}
export interface AllRewardTypeSummaries {
feeAccountSummary: FeeAccountSummary;
provinceTeamSummary: RewardTypeSummary;
cityTeamSummary: RewardTypeSummary;
shareReferralSummary: RewardTypeSummary;
communitySummary: RewardTypeSummary;
}
@Injectable()
export class RewardServiceClient {
private readonly logger = new Logger(RewardServiceClient.name);
@ -70,4 +102,43 @@ export class RewardServiceClient {
};
}
}
// [2026-01-06] 新增:获取所有收益类型汇总统计
/**
*
*
*/
async getAllRewardTypeSummaries(): Promise<AllRewardTypeSummaries> {
try {
const url = `${this.baseUrl}/api/v1/internal/statistics/reward-type-summaries`;
this.logger.debug(`[getAllRewardTypeSummaries] 请求: ${url}`);
const response = await firstValueFrom(
this.httpService.get<AllRewardTypeSummaries>(url),
);
return response.data;
} catch (error) {
this.logger.error(`[getAllRewardTypeSummaries] 失败: ${error.message}`);
// 返回默认值,不阻塞报表
const defaultSummary: RewardTypeSummary = {
totalAmount: 0,
totalCount: 0,
totalSettleableAmount: 0,
totalSettledAmount: 0,
byMonth: [],
};
return {
feeAccountSummary: {
totalAmount: 0,
totalCount: 0,
breakdown: [],
},
provinceTeamSummary: defaultSummary,
cityTeamSummary: defaultSummary,
shareReferralSummary: defaultSummary,
communitySummary: defaultSummary,
};
}
}
}

View File

@ -96,4 +96,26 @@ export class InternalController {
this.logger.log(`过期收益统计结果: totalAmount=${result.totalAmount}, totalCount=${result.totalCount}`);
return result;
}
// [2026-01-06] 新增:收益类型汇总统计接口
// 用于系统账户报表中的:手续费汇总、省团队收益汇总、市团队收益汇总、分享引荐收益汇总、社区收益汇总
// 回滚方式:删除以下 API 方法即可
@Get('statistics/reward-type-summaries')
@ApiOperation({ summary: '所有收益类型汇总统计(内部接口)- 用于系统账户报表' })
@ApiResponse({ status: 200, description: '所有收益类型汇总' })
async getAllRewardTypeSummaries() {
this.logger.log(`========== statistics/reward-type-summaries 请求 ==========`);
const result = await this.rewardService.getAllRewardTypeSummaries();
this.logger.log(`收益类型汇总统计结果:`);
this.logger.log(` - 手续费汇总: ${result.feeAccountSummary.totalAmount}`);
this.logger.log(` - 省团队收益: ${result.provinceTeamSummary.totalAmount}`);
this.logger.log(` - 市团队收益: ${result.cityTeamSummary.totalAmount}`);
this.logger.log(` - 分享引荐收益: ${result.shareReferralSummary.totalAmount}`);
this.logger.log(` - 社区收益: ${result.communitySummary.totalAmount}`);
return result;
}
}

View File

@ -905,6 +905,225 @@ export class RewardApplicationService {
// [2026-01-04] 新增:用于 reporting-service 聚合系统账户报表数据
// 回滚方式:删除以下方法和构造函数中的 prisma 注入即可
// [2026-01-06] 新增:按权益类型统计收益汇总
// 用于系统账户报表中的:手续费汇总、省团队收益汇总、市团队收益汇总、分享引荐收益汇总、社区收益汇总
// 回滚方式:删除以下方法即可
/**
*
* SETTLEABLE + SETTLED
*
* @param rightType
*/
async getRewardsSummaryByType(rightType: string): Promise<{
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{
month: string;
amount: number;
count: number;
}>;
}> {
this.logger.log(`[getRewardsSummaryByType] 查询权益类型收益统计: ${rightType}`);
// 查询总计SETTLEABLE + SETTLED 状态)
const aggregateResult = await this.prisma.rewardLedgerEntry.aggregate({
where: {
rightType: rightType,
rewardStatus: { in: ['SETTLEABLE', 'SETTLED'] },
},
_sum: {
usdtAmount: true,
},
_count: {
id: true,
},
});
// 查询可结算金额
const settleableResult = await this.prisma.rewardLedgerEntry.aggregate({
where: {
rightType: rightType,
rewardStatus: 'SETTLEABLE',
},
_sum: {
usdtAmount: true,
},
});
// 查询已结算金额
const settledResult = await this.prisma.rewardLedgerEntry.aggregate({
where: {
rightType: rightType,
rewardStatus: 'SETTLED',
},
_sum: {
usdtAmount: true,
},
});
const totalAmount = aggregateResult._sum.usdtAmount
? Number(aggregateResult._sum.usdtAmount)
: 0;
const totalCount = aggregateResult._count.id || 0;
const totalSettleableAmount = settleableResult._sum.usdtAmount
? Number(settleableResult._sum.usdtAmount)
: 0;
const totalSettledAmount = settledResult._sum.usdtAmount
? Number(settledResult._sum.usdtAmount)
: 0;
// 查询按月统计
const byMonth = await this.prisma.$queryRaw<Array<{
month: string;
amount: any;
count: any;
}>>`
SELECT
TO_CHAR(created_at, 'YYYY-MM') as month,
SUM(usdt_amount) as amount,
COUNT(*) as count
FROM reward_ledger_entries
WHERE right_type = ${rightType}
AND reward_status IN ('SETTLEABLE', 'SETTLED')
GROUP BY TO_CHAR(created_at, 'YYYY-MM')
ORDER BY month DESC
LIMIT 12
`;
return {
totalAmount,
totalCount,
totalSettleableAmount,
totalSettledAmount,
byMonth: byMonth.map(row => ({
month: row.month,
amount: Number(row.amount) || 0,
count: Number(row.count) || 0,
})),
};
}
/**
*
* Tab
*/
async getAllRewardTypeSummaries(): Promise<{
feeAccountSummary: {
totalAmount: number;
totalCount: number;
breakdown: Array<{ rightType: string; amount: number; count: number }>;
};
provinceTeamSummary: {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{ month: string; amount: number; count: number }>;
};
cityTeamSummary: {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{ month: string; amount: number; count: number }>;
};
shareReferralSummary: {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{ month: string; amount: number; count: number }>;
};
communitySummary: {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{ month: string; amount: number; count: number }>;
};
}> {
this.logger.log('[getAllRewardTypeSummaries] 查询所有收益类型汇总');
// 并行查询各类收益汇总
const [
provinceTeamSummary,
cityTeamSummary,
shareReferralSummary,
communitySummary,
feeBreakdown,
] = await Promise.all([
this.getRewardsSummaryByType(RightType.PROVINCE_TEAM_RIGHT),
this.getRewardsSummaryByType(RightType.CITY_TEAM_RIGHT),
this.getRewardsSummaryByType(RightType.SHARE_RIGHT),
this.getRewardsSummaryByType(RightType.COMMUNITY_RIGHT),
// 手续费汇总:包括系统费用类型
this.getFeeAccountSummary(),
]);
return {
feeAccountSummary: feeBreakdown,
provinceTeamSummary,
cityTeamSummary,
shareReferralSummary,
communitySummary,
};
}
/**
*
* RWAD底池注入
*/
private async getFeeAccountSummary(): Promise<{
totalAmount: number;
totalCount: number;
breakdown: Array<{ rightType: string; amount: number; count: number }>;
}> {
const feeTypes = [
RightType.COST_FEE,
RightType.OPERATION_FEE,
RightType.HEADQUARTERS_BASE_FEE,
RightType.RWAD_POOL_INJECTION,
];
// 使用 Prisma 的 groupBy 查询各手续费类型的汇总
const groupedResults = await this.prisma.rewardLedgerEntry.groupBy({
by: ['rightType'],
where: {
rightType: { in: feeTypes },
rewardStatus: { in: ['SETTLEABLE', 'SETTLED'] },
},
_sum: {
usdtAmount: true,
},
_count: {
id: true,
},
});
let totalAmount = 0;
let totalCount = 0;
const formattedBreakdown = groupedResults.map(row => {
const amount = Number(row._sum.usdtAmount) || 0;
const count = Number(row._count.id) || 0;
totalAmount += amount;
totalCount += count;
return {
rightType: row.rightType,
amount,
count,
};
});
return {
totalAmount,
totalCount,
breakdown: formattedBreakdown,
};
}
/**
*
*

View File

@ -2,6 +2,7 @@
* Tab组件
* [2026-01-04]
* [2026-01-05]
* [2026-01-06]
* system-account-report
*/
'use client';
@ -15,8 +16,11 @@ import type {
FixedAccountLedger,
RegionAccountLedger,
LedgerEntryDTO,
AllRewardTypeSummariesResponse,
RewardTypeSummary,
FeeAccountSummary,
} from '@/types';
import { ENTRY_TYPE_LABELS, ACCOUNT_TYPE_LABELS } from '@/types';
import { ENTRY_TYPE_LABELS, ACCOUNT_TYPE_LABELS, FEE_TYPE_LABELS } from '@/types';
import styles from './SystemAccountsTab.module.scss';
/**
@ -48,13 +52,19 @@ const getRightTypeName = (type: string): string => {
/**
* Tab组件
*/
// Tab类型定义
type TabType = 'fixed' | 'province' | 'city' | 'settlement' | 'expired' | 'ledger' | 'feeAccount' | 'provinceTeam' | 'cityTeam' | 'shareReferral' | 'community';
export default function SystemAccountsTab() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [reportData, setReportData] = useState<SystemAccountReportResponse | null>(null);
const [ledgerData, setLedgerData] = useState<AllSystemAccountsLedgerResponse | null>(null);
const [ledgerLoading, setLedgerLoading] = useState(false);
const [activeTab, setActiveTab] = useState<'fixed' | 'province' | 'city' | 'settlement' | 'expired' | 'ledger'>('fixed');
// [2026-01-06] 新增:收益类型汇总数据
const [rewardTypeSummaries, setRewardTypeSummaries] = useState<AllRewardTypeSummariesResponse | null>(null);
const [rewardTypeSummariesLoading, setRewardTypeSummariesLoading] = useState(false);
const [activeTab, setActiveTab] = useState<TabType>('fixed');
// 加载报表数据
const loadReportData = useCallback(async () => {
@ -88,6 +98,21 @@ export default function SystemAccountsTab() {
}
}, []);
// [2026-01-06] 新增:加载收益类型汇总数据
const loadRewardTypeSummaries = useCallback(async () => {
setRewardTypeSummariesLoading(true);
try {
const response = await systemAccountReportService.getRewardTypeSummaries();
if (response.data) {
setRewardTypeSummaries(response.data);
}
} catch (err) {
console.error('Failed to load reward type summaries:', err);
} finally {
setRewardTypeSummariesLoading(false);
}
}, []);
useEffect(() => {
loadReportData();
}, [loadReportData]);
@ -99,6 +124,14 @@ export default function SystemAccountsTab() {
}
}, [activeTab, ledgerData, ledgerLoading, loadLedgerData]);
// [2026-01-06] 切换到收益类型汇总Tab时加载数据
const rewardTypeTabs: TabType[] = ['feeAccount', 'provinceTeam', 'cityTeam', 'shareReferral', 'community'];
useEffect(() => {
if (rewardTypeTabs.includes(activeTab) && !rewardTypeSummaries && !rewardTypeSummariesLoading) {
loadRewardTypeSummaries();
}
}, [activeTab, rewardTypeSummaries, rewardTypeSummariesLoading, loadRewardTypeSummaries]);
if (loading) {
return (
<div className={styles.loading}>
@ -163,6 +196,37 @@ export default function SystemAccountsTab() {
>
</button>
{/* [2026-01-06] 新增收益类型汇总Tab */}
<button
className={`${styles.tab} ${activeTab === 'feeAccount' ? styles.active : ''}`}
onClick={() => setActiveTab('feeAccount')}
>
</button>
<button
className={`${styles.tab} ${activeTab === 'provinceTeam' ? styles.active : ''}`}
onClick={() => setActiveTab('provinceTeam')}
>
</button>
<button
className={`${styles.tab} ${activeTab === 'cityTeam' ? styles.active : ''}`}
onClick={() => setActiveTab('cityTeam')}
>
</button>
<button
className={`${styles.tab} ${activeTab === 'shareReferral' ? styles.active : ''}`}
onClick={() => setActiveTab('shareReferral')}
>
</button>
<button
className={`${styles.tab} ${activeTab === 'community' ? styles.active : ''}`}
onClick={() => setActiveTab('community')}
>
</button>
</div>
{/* 内容区域 */}
@ -173,6 +237,46 @@ export default function SystemAccountsTab() {
{activeTab === 'settlement' && <OfflineSettlementSection data={reportData.offlineSettlement} />}
{activeTab === 'expired' && <ExpiredRewardsSection data={reportData.expiredRewards} />}
{activeTab === 'ledger' && <LedgerSection data={ledgerData} loading={ledgerLoading} onRefresh={loadLedgerData} />}
{/* [2026-01-06] 新增收益类型汇总Tab内容 */}
{activeTab === 'feeAccount' && (
<FeeAccountSection
data={rewardTypeSummaries?.feeAccountSummary}
loading={rewardTypeSummariesLoading}
onRefresh={loadRewardTypeSummaries}
/>
)}
{activeTab === 'provinceTeam' && (
<RewardTypeSummarySection
title="省团队收益汇总"
data={rewardTypeSummaries?.provinceTeamSummary}
loading={rewardTypeSummariesLoading}
onRefresh={loadRewardTypeSummaries}
/>
)}
{activeTab === 'cityTeam' && (
<RewardTypeSummarySection
title="市团队收益汇总"
data={rewardTypeSummaries?.cityTeamSummary}
loading={rewardTypeSummariesLoading}
onRefresh={loadRewardTypeSummaries}
/>
)}
{activeTab === 'shareReferral' && (
<RewardTypeSummarySection
title="分享引荐收益汇总"
data={rewardTypeSummaries?.shareReferralSummary}
loading={rewardTypeSummariesLoading}
onRefresh={loadRewardTypeSummaries}
/>
)}
{activeTab === 'community' && (
<RewardTypeSummarySection
title="社区收益汇总"
data={rewardTypeSummaries?.communitySummary}
loading={rewardTypeSummariesLoading}
onRefresh={loadRewardTypeSummaries}
/>
)}
</div>
{/* 报表生成时间 */}
@ -670,3 +774,189 @@ function LedgerAccountCard({
</div>
);
}
// [2026-01-06] 新增:手续费账户汇总组件
/**
*
*/
function FeeAccountSection({
data,
loading,
onRefresh,
}: {
data: FeeAccountSummary | undefined;
loading: boolean;
onRefresh: () => void;
}) {
if (loading) {
return (
<div className={styles.loading}>
<div className={styles.spinner} />
<span>...</span>
</div>
);
}
if (!data) {
return (
<div className={styles.section}>
<div className={styles.emptyTable}>
<span></span>
<button onClick={onRefresh} className={styles.retryButton}>
</button>
</div>
</div>
);
}
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<h3 className={styles.sectionTitle}></h3>
<button onClick={onRefresh} className={styles.refreshButton}>
</button>
</div>
{/* 汇总卡片 */}
<div className={styles.summaryCards}>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{formatAmount(data.totalAmount)} 绿</span>
</div>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{data.totalCount}</span>
</div>
</div>
{/* 按类型明细 */}
{data.breakdown && data.breakdown.length > 0 ? (
<>
<h4 className={styles.subTitle}></h4>
<div className={styles.tableWrapper}>
<table className={styles.table}>
<thead>
<tr>
<th></th>
<th> (绿)</th>
<th></th>
</tr>
</thead>
<tbody>
{data.breakdown.map((item) => (
<tr key={item.rightType}>
<td>{FEE_TYPE_LABELS[item.rightType] || item.rightType}</td>
<td>{formatAmount(item.amount)}</td>
<td>{item.count}</td>
</tr>
))}
</tbody>
</table>
</div>
</>
) : (
<div className={styles.emptyTable}></div>
)}
</div>
);
}
// [2026-01-06] 新增:收益类型汇总组件
/**
*
*/
function RewardTypeSummarySection({
title,
data,
loading,
onRefresh,
}: {
title: string;
data: RewardTypeSummary | undefined;
loading: boolean;
onRefresh: () => void;
}) {
if (loading) {
return (
<div className={styles.loading}>
<div className={styles.spinner} />
<span>{title}...</span>
</div>
);
}
if (!data) {
return (
<div className={styles.section}>
<div className={styles.emptyTable}>
<span></span>
<button onClick={onRefresh} className={styles.retryButton}>
</button>
</div>
</div>
);
}
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<h3 className={styles.sectionTitle}>{title}</h3>
<button onClick={onRefresh} className={styles.refreshButton}>
</button>
</div>
{/* 汇总卡片 */}
<div className={styles.summaryCards}>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{formatAmount(data.totalAmount)} 绿</span>
</div>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{data.totalCount}</span>
</div>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{formatAmount(data.totalSettleableAmount)} 绿</span>
</div>
<div className={styles.summaryCard}>
<span className={styles.summaryLabel}></span>
<span className={styles.summaryValue}>{formatAmount(data.totalSettledAmount)} 绿</span>
</div>
</div>
{/* 按月统计 */}
{data.byMonth && data.byMonth.length > 0 ? (
<>
<h4 className={styles.subTitle}></h4>
<div className={styles.tableWrapper}>
<table className={styles.table}>
<thead>
<tr>
<th></th>
<th> (绿)</th>
<th></th>
</tr>
</thead>
<tbody>
{data.byMonth.map((item) => (
<tr key={item.month}>
<td>{item.month}</td>
<td>{formatAmount(item.amount)}</td>
<td>{item.count}</td>
</tr>
))}
</tbody>
</table>
</div>
</>
) : (
<div className={styles.emptyTable}></div>
)}
</div>
);
}

View File

@ -216,5 +216,7 @@ export const API_ENDPOINTS = {
EXPIRED_REWARDS: '/v1/system-account-reports/expired-rewards',
// [2026-01-05] 新增:所有系统账户分类账明细
ALL_LEDGER: '/v1/system-account-reports/all-ledger',
// [2026-01-06] 新增:收益类型汇总统计
REWARD_TYPE_SUMMARIES: '/v1/system-account-reports/reward-type-summaries',
},
} as const;

View File

@ -1,6 +1,7 @@
/**
*
* [2026-01-04] API调用
* [2026-01-06]
*
*/
@ -14,6 +15,7 @@ import type {
OfflineSettlementSummary,
ExpiredRewardsSummary,
AllSystemAccountsLedgerResponse,
AllRewardTypeSummariesResponse,
} from '@/types';
/**
@ -77,6 +79,15 @@ export const systemAccountReportService = {
async getAllLedger(params?: DateRangeParams & { pageSize?: number }): Promise<ApiResponse<AllSystemAccountsLedgerResponse>> {
return apiClient.get(API_ENDPOINTS.SYSTEM_ACCOUNT_REPORTS.ALL_LEDGER, { params });
},
// [2026-01-06] 新增:获取所有收益类型汇总统计
/**
*
*
*/
async getRewardTypeSummaries(): Promise<ApiResponse<AllRewardTypeSummariesResponse>> {
return apiClient.get(API_ENDPOINTS.SYSTEM_ACCOUNT_REPORTS.REWARD_TYPE_SUMMARIES);
},
};
export default systemAccountReportService;

View File

@ -186,3 +186,53 @@ export const ENTRY_TYPE_LABELS: Record<string, string> = {
ALLOCATION_IN: '分配收入',
ALLOCATION_OUT: '分配支出',
};
// [2026-01-06] 新增:收益类型汇总统计类型
/**
*
*/
export interface RewardTypeSummary {
totalAmount: number;
totalCount: number;
totalSettleableAmount: number;
totalSettledAmount: number;
byMonth: Array<{
month: string;
amount: number;
count: number;
}>;
}
/**
*
*/
export interface FeeAccountSummary {
totalAmount: number;
totalCount: number;
breakdown: Array<{
rightType: string;
amount: number;
count: number;
}>;
}
/**
*
*/
export interface AllRewardTypeSummariesResponse {
feeAccountSummary: FeeAccountSummary;
provinceTeamSummary: RewardTypeSummary;
cityTeamSummary: RewardTypeSummary;
shareReferralSummary: RewardTypeSummary;
communitySummary: RewardTypeSummary;
}
/**
*
*/
export const FEE_TYPE_LABELS: Record<string, string> = {
COST_FEE: '成本费',
OPERATION_FEE: '运营费',
HEADQUARTERS_BASE_FEE: '总部社区基础费',
RWAD_POOL_INJECTION: 'RWAD底池注入',
};