128 lines
4.6 KiB
TypeScript
128 lines
4.6 KiB
TypeScript
import { Controller, Get, Param, Logger, Inject } from '@nestjs/common';
|
||
import { ApiTags, ApiOperation, ApiParam, ApiResponse } from '@nestjs/swagger';
|
||
import {
|
||
TEAM_STATISTICS_REPOSITORY,
|
||
ITeamStatisticsRepository,
|
||
} from '../../domain';
|
||
|
||
/**
|
||
* 内部团队统计API - 供其他微服务调用
|
||
* 无需JWT认证(服务间内部通信)
|
||
*/
|
||
@ApiTags('Internal Team Statistics API')
|
||
@Controller('internal/team-statistics')
|
||
export class InternalTeamStatisticsController {
|
||
private readonly logger = new Logger(InternalTeamStatisticsController.name);
|
||
|
||
constructor(
|
||
@Inject(TEAM_STATISTICS_REPOSITORY)
|
||
private readonly teamStatsRepo: ITeamStatisticsRepository,
|
||
) {}
|
||
|
||
@Get('user/:userId')
|
||
@ApiOperation({ summary: '根据 userId 获取团队统计(内部API)' })
|
||
@ApiParam({ name: 'userId', description: '用户ID (bigint)' })
|
||
@ApiResponse({
|
||
status: 200,
|
||
description: '团队统计数据',
|
||
schema: {
|
||
type: 'object',
|
||
properties: {
|
||
userId: { type: 'string' },
|
||
accountSequence: { type: 'string' },
|
||
totalTeamPlantingCount: { type: 'number' },
|
||
selfPlantingCount: { type: 'number' },
|
||
provinceCityDistribution: { type: 'object' },
|
||
},
|
||
},
|
||
})
|
||
async getStatsByUserId(@Param('userId') userId: string) {
|
||
this.logger.debug(`[INTERNAL] getStatsByUserId: ${userId}`);
|
||
|
||
try {
|
||
const stats = await this.teamStatsRepo.findByUserId(BigInt(userId));
|
||
|
||
if (!stats) {
|
||
this.logger.debug(`[INTERNAL] No stats found for userId: ${userId}`);
|
||
return null;
|
||
}
|
||
|
||
const distribution = stats.provinceCityDistribution;
|
||
|
||
return {
|
||
userId: stats.userId.toString(),
|
||
accountSequence: '0', // userId 查询时无法获取 accountSequence
|
||
totalTeamPlantingCount: stats.teamPlantingCount, // 团队总认种(不含自己,只有下级)
|
||
selfPlantingCount: stats.personalPlantingCount, // 自己的认种数
|
||
provinceCityDistribution: distribution.toJson(),
|
||
};
|
||
} catch (error) {
|
||
this.logger.error(`[INTERNAL] Error getting stats for userId ${userId}:`, error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
@Get('account/:accountSequence')
|
||
@ApiOperation({ summary: '根据 accountSequence 获取团队统计(内部API)' })
|
||
@ApiParam({ name: 'accountSequence', description: '账户序列号' })
|
||
@ApiResponse({
|
||
status: 200,
|
||
description: '团队统计数据',
|
||
schema: {
|
||
type: 'object',
|
||
properties: {
|
||
userId: { type: 'string' },
|
||
accountSequence: { type: 'string' },
|
||
totalTeamPlantingCount: { type: 'number' },
|
||
selfPlantingCount: { type: 'number' },
|
||
provinceCityDistribution: { type: 'object' },
|
||
},
|
||
},
|
||
})
|
||
async getStatsByAccountSequence(@Param('accountSequence') accountSequence: string) {
|
||
this.logger.debug(`[INTERNAL] getStatsByAccountSequence: ${accountSequence}`);
|
||
|
||
try {
|
||
// 需要先通过 accountSequence 查找 userId
|
||
// 这里需要扩展 repository 方法
|
||
const stats = await this.findByAccountSequence(accountSequence);
|
||
|
||
if (!stats) {
|
||
this.logger.debug(`[INTERNAL] No stats found for accountSequence: ${accountSequence}`);
|
||
return null;
|
||
}
|
||
|
||
const distribution = stats.provinceCityDistribution;
|
||
|
||
return {
|
||
userId: stats.userId.toString(),
|
||
accountSequence: accountSequence,
|
||
totalTeamPlantingCount: stats.teamPlantingCount, // 团队总认种(不含自己,只有下级)
|
||
selfPlantingCount: stats.personalPlantingCount, // 自己的认种数
|
||
provinceCityDistribution: distribution.toJson(),
|
||
};
|
||
} catch (error) {
|
||
this.logger.error(`[INTERNAL] Error getting stats for accountSequence ${accountSequence}:`, error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通过 accountSequence 查找团队统计
|
||
* 需要先查询 referral_relationships 获取 userId,再查询 team_statistics
|
||
*/
|
||
private async findByAccountSequence(accountSequence: string) {
|
||
// 使用 repository 的 findByUserId,但这里需要 accountSequence 到 userId 的映射
|
||
// 由于当前架构 accountSequence 和 userId 不一定相等,需要通过 referral_relationships 表查询
|
||
// 暂时尝试将 accountSequence 字符串转换为 BigInt 作为 userId 查询
|
||
// 注意:这里的实现取决于业务逻辑,可能需要通过 referral_relationships 表查询
|
||
try {
|
||
// 尝试从 accountSequence 中提取数字部分或直接使用
|
||
// 这是临时方案,实际应该通过 referral_relationships 查询
|
||
return this.teamStatsRepo.findByUserId(BigInt(accountSequence.replace(/\D/g, '')));
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
}
|