fix(wallet-service): 修复流水查询使用 userId 导致记录丢失的问题
将所有流水查询从 userId 改为使用 accountSequence: - getMyLedger: 使用 findByAccountSequence 替代 findByUserId - getLedgerStatistics: 查询改为按 accountSequence - getLedgerTrend: 查询改为按 accountSequence - findByAccountSequence: 添加 HIDDEN_ENTRY_TYPES 过滤 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
53df97839d
commit
217be89c43
|
|
@ -22,7 +22,7 @@ export class LedgerController {
|
|||
@Query() queryDto: GetMyLedgerQueryDTO,
|
||||
): Promise<PaginatedLedgerResponseDTO> {
|
||||
const query = new GetMyLedgerQuery(
|
||||
user.userId,
|
||||
user.accountSequence, // 使用 accountSequence 替代 userId
|
||||
queryDto.page,
|
||||
queryDto.pageSize,
|
||||
queryDto.entryType,
|
||||
|
|
@ -39,7 +39,7 @@ export class LedgerController {
|
|||
async getStatistics(
|
||||
@CurrentUser() user: CurrentUserPayload,
|
||||
): Promise<LedgerStatisticsResponseDTO> {
|
||||
return this.walletService.getLedgerStatistics(user.userId);
|
||||
return this.walletService.getLedgerStatistics(user.accountSequence);
|
||||
}
|
||||
|
||||
@Get('trend')
|
||||
|
|
@ -51,6 +51,6 @@ export class LedgerController {
|
|||
@Query('days') days?: string,
|
||||
): Promise<LedgerTrendResponseDTO> {
|
||||
const numDays = days ? parseInt(days, 10) : 30;
|
||||
return this.walletService.getLedgerTrend(user.userId, numDays);
|
||||
return this.walletService.getLedgerTrend(user.accountSequence, numDays);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { LedgerEntryType, AssetType } from '@/domain/value-objects';
|
|||
|
||||
export class GetMyLedgerQuery {
|
||||
constructor(
|
||||
public readonly userId: string,
|
||||
public readonly accountSequence: string, // 使用 accountSequence 替代 userId
|
||||
public readonly page?: number,
|
||||
public readonly pageSize?: number,
|
||||
public readonly entryType?: LedgerEntryType,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ describe('WalletApplicationService', () => {
|
|||
const createMockWallet = (userId: bigint, usdtBalance = 0) => {
|
||||
return WalletAccount.reconstruct({
|
||||
walletId: BigInt(1),
|
||||
accountSequence: userId, // 使用 userId 作为 accountSequence
|
||||
accountSequence: `D${userId.toString().padStart(11, '0')}`, // 生成 accountSequence
|
||||
userId,
|
||||
usdtAvailable: new Decimal(usdtBalance),
|
||||
usdtFrozen: new Decimal(0),
|
||||
|
|
@ -51,6 +51,8 @@ describe('WalletApplicationService', () => {
|
|||
expiredTotalUsdt: new Decimal(0),
|
||||
expiredTotalHashpower: new Decimal(0),
|
||||
status: 'ACTIVE',
|
||||
hasPlanted: false,
|
||||
version: 0,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
|
|
@ -69,6 +71,7 @@ describe('WalletApplicationService', () => {
|
|||
save: jest.fn(),
|
||||
saveAll: jest.fn(),
|
||||
findByUserId: jest.fn(),
|
||||
findByAccountSequence: jest.fn(),
|
||||
findByRefOrderId: jest.fn(),
|
||||
findByRefTxHash: jest.fn(),
|
||||
};
|
||||
|
|
@ -187,9 +190,9 @@ describe('WalletApplicationService', () => {
|
|||
|
||||
describe('getMyLedger', () => {
|
||||
it('should return paginated ledger entries', async () => {
|
||||
const query = new GetMyLedgerQuery('1', 1, 10);
|
||||
const query = new GetMyLedgerQuery('D00000000001', 1, 10);
|
||||
|
||||
mockLedgerRepo.findByUserId.mockResolvedValue({
|
||||
mockLedgerRepo.findByAccountSequence.mockResolvedValue({
|
||||
data: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
|
|
|
|||
|
|
@ -1916,10 +1916,9 @@ export class WalletApplicationService {
|
|||
}
|
||||
|
||||
async getMyLedger(query: GetMyLedgerQuery): Promise<PaginatedLedgerDTO> {
|
||||
const userId = BigInt(query.userId);
|
||||
|
||||
const result = await this.ledgerRepo.findByUserId(
|
||||
userId,
|
||||
// 使用 accountSequence 查询流水(废弃 userId 查询)
|
||||
const result = await this.ledgerRepo.findByAccountSequence(
|
||||
query.accountSequence,
|
||||
{
|
||||
entryType: query.entryType,
|
||||
assetType: query.assetType,
|
||||
|
|
@ -1934,7 +1933,7 @@ export class WalletApplicationService {
|
|||
|
||||
// 调试日志:打印流水数据(只打印前5条)
|
||||
this.logger.debug(`[getMyLedger] ======== 流水数据调试 ========`);
|
||||
this.logger.debug(`[getMyLedger] userId: ${userId}, 共 ${result.data.length} 条, 总计 ${result.total} 条`);
|
||||
this.logger.debug(`[getMyLedger] accountSequence: ${query.accountSequence}, 共 ${result.data.length} 条, 总计 ${result.total} 条`);
|
||||
for (let i = 0; i < result.data.length && i < 5; i++) {
|
||||
const entry = result.data[i];
|
||||
const allocationType = (entry.payloadJson as Record<string, unknown>)?.allocationType;
|
||||
|
|
@ -2458,7 +2457,7 @@ export class WalletApplicationService {
|
|||
/**
|
||||
* 获取流水统计信息
|
||||
*/
|
||||
async getLedgerStatistics(userId: string): Promise<{
|
||||
async getLedgerStatistics(accountSequence: string): Promise<{
|
||||
totalIncome: number;
|
||||
totalExpense: number;
|
||||
netAmount: number;
|
||||
|
|
@ -2472,11 +2471,9 @@ export class WalletApplicationService {
|
|||
startDate: string;
|
||||
endDate: string;
|
||||
}> {
|
||||
const userIdBigInt = BigInt(userId);
|
||||
|
||||
// 获取所有流水
|
||||
// 使用 accountSequence 查询流水(废弃 userId 查询)
|
||||
const entries = await this.prisma.ledgerEntry.findMany({
|
||||
where: { userId: userIdBigInt, assetType: 'USDT' },
|
||||
where: { accountSequence, assetType: 'USDT' },
|
||||
orderBy: { createdAt: 'asc' },
|
||||
});
|
||||
|
||||
|
|
@ -2547,7 +2544,7 @@ export class WalletApplicationService {
|
|||
/**
|
||||
* 获取流水趋势
|
||||
*/
|
||||
async getLedgerTrend(userId: string, days: number = 30): Promise<{
|
||||
async getLedgerTrend(accountSequence: string, days: number = 30): Promise<{
|
||||
dailyTrend: Array<{
|
||||
date: string;
|
||||
income: number;
|
||||
|
|
@ -2560,14 +2557,14 @@ export class WalletApplicationService {
|
|||
periodExpense: number;
|
||||
periodNet: number;
|
||||
}> {
|
||||
const userIdBigInt = BigInt(userId);
|
||||
// 使用 accountSequence 查询流水(废弃 userId 查询)
|
||||
const startDate = new Date();
|
||||
startDate.setDate(startDate.getDate() - days);
|
||||
startDate.setHours(0, 0, 0, 0);
|
||||
|
||||
const entries = await this.prisma.ledgerEntry.findMany({
|
||||
where: {
|
||||
userId: userIdBigInt,
|
||||
accountSequence,
|
||||
assetType: 'USDT',
|
||||
createdAt: { gte: startDate },
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ describe('WalletAccount Aggregate', () => {
|
|||
let wallet: WalletAccount;
|
||||
|
||||
beforeEach(() => {
|
||||
wallet = WalletAccount.createNew(BigInt(1), UserId.create(1));
|
||||
wallet = WalletAccount.createNew('D00000000001', UserId.create(1));
|
||||
});
|
||||
|
||||
describe('createNew', () => {
|
||||
|
|
|
|||
|
|
@ -133,9 +133,14 @@ export class LedgerEntryRepositoryImpl implements ILedgerEntryRepository {
|
|||
filters?: LedgerFilters,
|
||||
pagination?: Pagination,
|
||||
): Promise<PaginatedResult<LedgerEntry>> {
|
||||
const where: Record<string, unknown> = { accountSequence };
|
||||
const where: Record<string, unknown> = {
|
||||
accountSequence,
|
||||
// 排除临时性流水类型
|
||||
entryType: { notIn: LedgerEntryRepositoryImpl.HIDDEN_ENTRY_TYPES },
|
||||
};
|
||||
|
||||
if (filters?.entryType) {
|
||||
// 如果用户指定了类型筛选,则使用用户指定的类型
|
||||
where.entryType = filters.entryType;
|
||||
}
|
||||
if (filters?.assetType) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue