fix(admin): 用户详情页 USDT 改为绿积分 + 添加调试日志

前端修改:
- 钱包汇总: USDT 可用/冻结 → 绿积分 可用/冻结
- 认种汇总: 总金额 (USDT) → 总金额 (绿积分)
- 资产类型标签: USDT → 绿积分

后端修改:
- UserDetailController: 添加认种/钱包查询日志
- UserDetailQueryRepositoryImpl: 添加数据库查询日志
- 日志包含 accountSequence、查询结果、数据条数等信息

🤖 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-07 20:53:30 -08:00
parent f15bdeaef8
commit 5f6ecf9670
3 changed files with 36 additions and 5 deletions

View File

@ -7,6 +7,7 @@ import {
HttpStatus, HttpStatus,
NotFoundException, NotFoundException,
Inject, Inject,
Logger,
} from '@nestjs/common'; } from '@nestjs/common';
import { ReferralTreeQueryDto, LedgerQueryDto, WalletLedgerQueryDto } from '../dto/request/user-detail-query.dto'; import { ReferralTreeQueryDto, LedgerQueryDto, WalletLedgerQueryDto } from '../dto/request/user-detail-query.dto';
import { import {
@ -32,6 +33,8 @@ import {
*/ */
@Controller('admin/users') @Controller('admin/users')
export class UserDetailController { export class UserDetailController {
private readonly logger = new Logger(UserDetailController.name);
constructor( constructor(
@Inject(USER_QUERY_REPOSITORY) @Inject(USER_QUERY_REPOSITORY)
private readonly userQueryRepository: IUserQueryRepository, private readonly userQueryRepository: IUserQueryRepository,
@ -188,7 +191,10 @@ export class UserDetailController {
@Param('accountSequence') accountSequence: string, @Param('accountSequence') accountSequence: string,
@Query() query: LedgerQueryDto, @Query() query: LedgerQueryDto,
): Promise<PlantingLedgerResponseDto> { ): Promise<PlantingLedgerResponseDto> {
this.logger.log(`[getPlantingLedger] 查询认种分类账, accountSequence=${accountSequence}`);
const user = await this.userQueryRepository.findByAccountSequence(accountSequence); const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
this.logger.log(`[getPlantingLedger] 用户查询结果: ${user ? `userId=${user.userId}` : 'null'}`);
if (!user) { if (!user) {
throw new NotFoundException(`用户 ${accountSequence} 不存在`); throw new NotFoundException(`用户 ${accountSequence} 不存在`);
} }
@ -204,6 +210,9 @@ export class UserDetailController {
), ),
]); ]);
this.logger.log(`[getPlantingLedger] 认种汇总: ${JSON.stringify(summary)}`);
this.logger.log(`[getPlantingLedger] 认种流水条数: ${ledger.items.length}, total=${ledger.total}`);
return { return {
summary: { summary: {
totalOrders: summary?.totalOrders || 0, totalOrders: summary?.totalOrders || 0,
@ -244,7 +253,10 @@ export class UserDetailController {
@Param('accountSequence') accountSequence: string, @Param('accountSequence') accountSequence: string,
@Query() query: WalletLedgerQueryDto, @Query() query: WalletLedgerQueryDto,
): Promise<WalletLedgerResponseDto> { ): Promise<WalletLedgerResponseDto> {
this.logger.log(`[getWalletLedger] 查询钱包分类账, accountSequence=${accountSequence}`);
const user = await this.userQueryRepository.findByAccountSequence(accountSequence); const user = await this.userQueryRepository.findByAccountSequence(accountSequence);
this.logger.log(`[getWalletLedger] 用户查询结果: ${user ? `userId=${user.userId}` : 'null'}`);
if (!user) { if (!user) {
throw new NotFoundException(`用户 ${accountSequence} 不存在`); throw new NotFoundException(`用户 ${accountSequence} 不存在`);
} }
@ -264,6 +276,9 @@ export class UserDetailController {
), ),
]); ]);
this.logger.log(`[getWalletLedger] 钱包汇总: ${JSON.stringify(summary)}`);
this.logger.log(`[getWalletLedger] 钱包流水条数: ${ledger.items.length}, total=${ledger.total}`);
return { return {
summary: { summary: {
usdtAvailable: this.formatDecimal(summary?.usdtAvailable), usdtAvailable: this.formatDecimal(summary?.usdtAvailable),

View File

@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { Decimal } from '@prisma/client/runtime/library'; import { Decimal } from '@prisma/client/runtime/library';
import { PrismaService } from '../prisma/prisma.service'; import { PrismaService } from '../prisma/prisma.service';
import { import {
@ -19,6 +19,8 @@ import {
@Injectable() @Injectable()
export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository { export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository {
private readonly logger = new Logger(UserDetailQueryRepositoryImpl.name);
constructor(private readonly prisma: PrismaService) {} constructor(private readonly prisma: PrismaService) {}
// ============================================================================ // ============================================================================
@ -160,12 +162,16 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository
// ============================================================================ // ============================================================================
async getPlantingSummary(accountSequence: string): Promise<PlantingSummary | null> { async getPlantingSummary(accountSequence: string): Promise<PlantingSummary | null> {
this.logger.log(`[getPlantingSummary] 查询认种汇总, accountSequence=${accountSequence}`);
// 先获取用户的 userId 用于查询持仓 // 先获取用户的 userId 用于查询持仓
const user = await this.prisma.userQueryView.findUnique({ const user = await this.prisma.userQueryView.findUnique({
where: { accountSequence }, where: { accountSequence },
select: { userId: true }, select: { userId: true },
}); });
this.logger.log(`[getPlantingSummary] 用户查询结果: ${user ? `userId=${user.userId}` : 'null'}`);
if (!user) return null; if (!user) return null;
// 获取持仓信息 // 获取持仓信息
@ -173,6 +179,8 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository
where: { userId: user.userId }, where: { userId: user.userId },
}); });
this.logger.log(`[getPlantingSummary] 持仓查询结果: ${position ? `effectiveTreeCount=${position.effectiveTreeCount}` : 'null'}`);
// 获取订单统计 - 使用 accountSequence // 获取订单统计 - 使用 accountSequence
const [orderStats, firstOrder, lastOrder] = await Promise.all([ const [orderStats, firstOrder, lastOrder] = await Promise.all([
this.prisma.plantingOrderQueryView.aggregate({ this.prisma.plantingOrderQueryView.aggregate({
@ -195,6 +203,8 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository
}), }),
]); ]);
this.logger.log(`[getPlantingSummary] 订单统计: count=${orderStats._count}, treeCount=${orderStats._sum.treeCount}, totalAmount=${orderStats._sum.totalAmount}`);
return { return {
totalOrders: orderStats._count, totalOrders: orderStats._count,
totalTreeCount: orderStats._sum.treeCount || 0, totalTreeCount: orderStats._sum.treeCount || 0,
@ -257,10 +267,14 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository
// ============================================================================ // ============================================================================
async getWalletSummary(accountSequence: string): Promise<WalletSummary | null> { async getWalletSummary(accountSequence: string): Promise<WalletSummary | null> {
this.logger.log(`[getWalletSummary] 查询钱包, accountSequence=${accountSequence}`);
const wallet = await this.prisma.walletAccountQueryView.findUnique({ const wallet = await this.prisma.walletAccountQueryView.findUnique({
where: { accountSequence }, where: { accountSequence },
}); });
this.logger.log(`[getWalletSummary] 查询结果: ${wallet ? `id=${wallet.id}, userId=${wallet.userId}, usdtAvailable=${wallet.usdtAvailable}` : 'null'}`);
if (!wallet) return null; if (!wallet) return null;
return { return {
@ -292,6 +306,8 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository
pageSize: number, pageSize: number,
filters?: WalletLedgerFilters, filters?: WalletLedgerFilters,
): Promise<WalletLedgerResult> { ): Promise<WalletLedgerResult> {
this.logger.log(`[getWalletLedger] 查询钱包流水, accountSequence=${accountSequence}, page=${page}`);
const where: any = { accountSequence }; const where: any = { accountSequence };
if (filters?.assetType) { if (filters?.assetType) {

View File

@ -62,7 +62,7 @@ const entryTypeLabels: Record<string, string> = {
}; };
const assetTypeLabels: Record<string, string> = { const assetTypeLabels: Record<string, string> = {
USDT: 'USDT', USDT: '绿积分',
DST: 'DST', DST: 'DST',
BNB: 'BNB', BNB: 'BNB',
OG: 'OG', OG: 'OG',
@ -440,7 +440,7 @@ export default function UserDetailPage() {
</span> </span>
</div> </div>
<div className={styles.plantingTab__summaryItem}> <div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}> (USDT)</span> <span className={styles.plantingTab__summaryLabel}> (绿)</span>
<span className={styles.plantingTab__summaryValue}> <span className={styles.plantingTab__summaryValue}>
{formatAmount(plantingData.summary.totalAmount)} {formatAmount(plantingData.summary.totalAmount)}
</span> </span>
@ -543,13 +543,13 @@ export default function UserDetailPage() {
<h3></h3> <h3></h3>
<div className={styles.walletTab__summaryGrid}> <div className={styles.walletTab__summaryGrid}>
<div className={styles.walletTab__summaryItem}> <div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}>USDT </span> <span className={styles.walletTab__summaryLabel}>绿 </span>
<span className={styles.walletTab__summaryValue}> <span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.usdtAvailable)} {formatAmount(walletData.summary.usdtAvailable)}
</span> </span>
</div> </div>
<div className={styles.walletTab__summaryItem}> <div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}>USDT </span> <span className={styles.walletTab__summaryLabel}>绿 </span>
<span className={styles.walletTab__summaryValue}> <span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.usdtFrozen)} {formatAmount(walletData.summary.usdtFrozen)}
</span> </span>