feat(ledger): 流水明细显示来源用户ID + 统计兼容历史批量转换数据
- wallet_service.dart: LedgerEntry 新增 sourceAccountFromMemo 从 memo 提取来源用户 - ledger_detail_page.dart: 流水列表项显示"来自 Dxxx"金色文字 - ledger_detail_page.dart: 权益详情弹窗添加来源用户行和备注行 - wallet-application.service.ts: 统计/趋势保留 memo 兼容历史批量转换记录 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d876dd1591
commit
e4a2a0e37a
|
|
@ -2697,7 +2697,11 @@ export class WalletApplicationService {
|
|||
const amount = Number(entry.amount);
|
||||
|
||||
// 只计算非临时性流水的收支统计
|
||||
if (!excludeFromStats.has(entry.entryType)) {
|
||||
// 兼容历史数据:老的批量转换记录 entry_type 仍为 REWARD_TO_SETTLEABLE,
|
||||
// 通过 memo 中 "pending rewards settled" 识别并排除
|
||||
const isExcluded = excludeFromStats.has(entry.entryType) ||
|
||||
(entry.entryType === 'REWARD_TO_SETTLEABLE' && entry.memo?.includes('pending rewards settled'));
|
||||
if (!isExcluded) {
|
||||
if (amount > 0) {
|
||||
totalIncome += amount;
|
||||
} else {
|
||||
|
|
@ -2791,8 +2795,10 @@ export class WalletApplicationService {
|
|||
const amount = Number(entry.amount);
|
||||
const existing = dailyMap.get(dateStr) || { income: 0, expense: 0, count: 0 };
|
||||
|
||||
// 只计算非临时性流水的收支统计
|
||||
if (!excludeFromStats.has(entry.entryType)) {
|
||||
// 只计算非临时性流水的收支统计(兼容历史批量转换数据)
|
||||
const isExcluded = excludeFromStats.has(entry.entryType) ||
|
||||
(entry.entryType === 'REWARD_TO_SETTLEABLE' && entry.memo?.includes('pending rewards settled'));
|
||||
if (!isExcluded) {
|
||||
if (amount > 0) {
|
||||
existing.income += amount;
|
||||
periodIncome += amount;
|
||||
|
|
|
|||
|
|
@ -1522,6 +1522,13 @@ class LedgerEntry {
|
|||
return baseName;
|
||||
}
|
||||
|
||||
/// 从 memo 中提取来源用户ID(格式如:"来源: D26022600016")
|
||||
String? get sourceAccountFromMemo {
|
||||
if (memo == null) return null;
|
||||
final match = RegExp(r'来源:\s*(D\d+)').firstMatch(memo!);
|
||||
return match?.group(1);
|
||||
}
|
||||
|
||||
/// 是否为收入
|
||||
bool get isIncome => amount > 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,16 @@ class _LedgerDetailPageState extends ConsumerState<LedgerDetailPage>
|
|||
color: Color(0xFF5D4037),
|
||||
),
|
||||
),
|
||||
if (entry.sourceAccountFromMemo != null) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'来自 ${entry.sourceAccountFromMemo}',
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFFD4AF37),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_formatDate(entry.createdAt),
|
||||
|
|
@ -1715,11 +1725,15 @@ class _RewardDetailSheet extends StatelessWidget {
|
|||
),
|
||||
_buildDetailRow('权益类型', entry.displayName),
|
||||
_buildDetailRow('流水类型', entry.entryTypeName),
|
||||
if (entry.sourceAccountFromMemo != null)
|
||||
_buildDetailRow('来源用户', entry.sourceAccountFromMemo!),
|
||||
if (entry.balanceAfter != null)
|
||||
_buildDetailRow('入账后余额', '${_formatAmount(entry.balanceAfter!)} 绿积分'),
|
||||
_buildDetailRow('入账时间', _formatDateTime(entry.createdAt)),
|
||||
if (entry.refOrderId != null && entry.refOrderId!.isNotEmpty)
|
||||
_buildDetailRow('关联订单', entry.refOrderId!),
|
||||
if (entry.memo != null && entry.memo!.isNotEmpty)
|
||||
_buildDetailRow('备注', entry.memo!),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue