From bf50810830c6bfa24a9e518f70fba841991237ef Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 28 Feb 2026 20:22:40 -0800 Subject: [PATCH] =?UTF-8?q?feat(wallet+admin-web):=20=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E6=B5=81=E6=B0=B4=E5=A2=9E=E5=8A=A0=E6=9D=A5?= =?UTF-8?q?=E6=BA=90=E7=94=A8=E6=88=B7=E8=B4=A6=E6=88=B7=E5=92=8C=E6=9D=A5?= =?UTF-8?q?=E6=BA=90=E5=A4=87=E6=B3=A8=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:系统账户(S0000000001等)、省/市区域/团队账户的流水明细 只显示 allocationType 英文标识,无法追溯是哪个用户的认种产生的。 解决方案:从 wallet_ledger_entries.payload_json.metadata 中提取 sourceAccountSequence 和 memo 字段,通过 API 返回给前端展示。 后端 wallet-service 改动: - LedgerEntryDTO 新增 sourceAccountSequence / sourceMemo 两个可选字段 - 新增 extractPayloadInfo() 辅助函数统一从 payloadJson 提取信息 - 替换所有 5 处 LedgerEntryDTO 映射,使用 extractPayloadInfo() - 向后兼容:旧记录无 metadata 时返回 null,不影响已有功能 前端 admin-web 改动: - LedgerEntryDTO 类型新增 sourceAccountSequence / sourceMemo 字段 - 固定账户明细表格和分类账明细表格增加"来源账户"和"来源备注"列 - 新增 .sourceAccount 样式(等宽字体显示账户序列号) 数据来源说明: - 正常认种:reward-service 传入 metadata 含完整中文 memo 和 sourceAccountSequence - 预种:planting-service 传入 metadata 含 sourceAccountSequence 和中文 memo - 历史记录(2026-01-04前):metadata 可能为空,显示为"-" Co-Authored-By: Claude Opus 4.6 --- .../services/wallet-application.service.ts | 29 +++++++++++++++---- .../SystemAccountsTab.module.scss | 6 ++++ .../SystemAccountsTab.tsx | 8 +++++ .../src/types/system-account.types.ts | 4 +++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/backend/services/wallet-service/src/application/services/wallet-application.service.ts b/backend/services/wallet-service/src/application/services/wallet-application.service.ts index 85204ec3..35f3878a 100644 --- a/backend/services/wallet-service/src/application/services/wallet-application.service.ts +++ b/backend/services/wallet-service/src/application/services/wallet-application.service.ts @@ -64,6 +64,10 @@ export interface LedgerEntryDTO { refTxHash: string | null; memo: string | null; allocationType: string | null; + /** 来源用户账户序列号(从 payloadJson.metadata 提取) */ + sourceAccountSequence: string | null; + /** 来源中文备注(从 payloadJson.metadata.memo 提取) */ + sourceMemo: string | null; createdAt: string; } @@ -75,6 +79,21 @@ export interface PaginatedLedgerDTO { totalPages: number; } +/** 从 payloadJson 中提取 metadata 信息用于 LedgerEntryDTO */ +function extractPayloadInfo(payloadJson: unknown): { + allocationType: string | null; + sourceAccountSequence: string | null; + sourceMemo: string | null; +} { + const payload = payloadJson as Record | null; + const metadata = payload?.metadata as Record | null; + return { + allocationType: (payload?.allocationType as string) ?? null, + sourceAccountSequence: (metadata?.sourceAccountSequence as string) ?? null, + sourceMemo: (metadata?.memo as string) ?? null, + }; +} + @Injectable() export class WalletApplicationService { private readonly logger = new Logger(WalletApplicationService.name); @@ -1991,7 +2010,7 @@ export class WalletApplicationService { refOrderId: entry.refOrderId, refTxHash: entry.refTxHash, memo: entry.memo, - allocationType: (entry.payloadJson as Record)?.allocationType as string ?? null, + ...extractPayloadInfo(entry.payloadJson), createdAt: entry.createdAt.toISOString(), })), total: result.total, @@ -2036,7 +2055,7 @@ export class WalletApplicationService { refOrderId: entry.refOrderId, refTxHash: entry.refTxHash, memo: entry.memo, - allocationType: (entry.payloadJson as Record)?.allocationType as string ?? null, + ...extractPayloadInfo(entry.payloadJson), createdAt: entry.createdAt.toISOString(), })), total: result.total, @@ -2103,7 +2122,7 @@ export class WalletApplicationService { refOrderId: entry.refOrderId, refTxHash: entry.refTxHash, memo: entry.memo, - allocationType: (entry.payloadJson as Record)?.allocationType as string ?? null, + ...extractPayloadInfo(entry.payloadJson), createdAt: entry.createdAt.toISOString(), })), total: ledgerResult.total, @@ -2131,7 +2150,7 @@ export class WalletApplicationService { refOrderId: entry.refOrderId, refTxHash: entry.refTxHash, memo: entry.memo, - allocationType: (entry.payloadJson as Record)?.allocationType as string ?? null, + ...extractPayloadInfo(entry.payloadJson), createdAt: entry.createdAt.toISOString(), })), total: ledgerResult.total, @@ -2159,7 +2178,7 @@ export class WalletApplicationService { refOrderId: entry.refOrderId, refTxHash: entry.refTxHash, memo: entry.memo, - allocationType: (entry.payloadJson as Record)?.allocationType as string ?? null, + ...extractPayloadInfo(entry.payloadJson), createdAt: entry.createdAt.toISOString(), })), total: ledgerResult.total, diff --git a/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.module.scss b/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.module.scss index c9b2d04f..c5f032f0 100644 --- a/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.module.scss +++ b/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.module.scss @@ -512,6 +512,12 @@ word-break: break-word; } +.sourceAccount { + font-size: 13px; + font-family: monospace; + color: #374151; +} + /* [2026-01-06] 新增:详细明细列表样式 */ .detailsSection { margin-top: 24px; diff --git a/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.tsx b/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.tsx index 16f26ca0..c8067fdf 100644 --- a/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.tsx +++ b/frontend/admin-web/src/components/features/system-account-report/SystemAccountsTab.tsx @@ -443,6 +443,8 @@ function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fix 类型 金额 余额 + 来源账户 + 来源备注 备注 @@ -459,6 +461,8 @@ function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fix {entry.amount >= 0 ? '+' : ''}{formatAmount(entry.amount)} {getAssetTypeLabel(entry.assetType)} {entry.balanceAfter !== null ? formatAmount(entry.balanceAfter) : '-'} + {entry.sourceAccountSequence || '-'} + {entry.sourceMemo || '-'} {entry.memo || entry.allocationType || '-'} ))} @@ -1110,6 +1114,8 @@ function LedgerAccountCard({ 类型 金额 余额 + 来源账户 + 来源备注 备注 @@ -1126,6 +1132,8 @@ function LedgerAccountCard({ {entry.amount >= 0 ? '+' : ''}{formatAmount(entry.amount)} {getAssetTypeLabel(entry.assetType)} {entry.balanceAfter !== null ? formatAmount(entry.balanceAfter) : '-'} + {entry.sourceAccountSequence || '-'} + {entry.sourceMemo || '-'} {entry.memo || entry.allocationType || '-'} ))} diff --git a/frontend/admin-web/src/types/system-account.types.ts b/frontend/admin-web/src/types/system-account.types.ts index 4b4caf79..2c775425 100644 --- a/frontend/admin-web/src/types/system-account.types.ts +++ b/frontend/admin-web/src/types/system-account.types.ts @@ -195,6 +195,10 @@ export interface LedgerEntryDTO { refTxHash: string | null; memo: string | null; allocationType: string | null; + /** 来源用户账户序列号 */ + sourceAccountSequence: string | null; + /** 来源中文备注 */ + sourceMemo: string | null; createdAt: string; }