import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify' import { TeamService } from '../services/team.service' import { CreateTeamBody, UpdateTeamBody, ListTeamQuery, TeamParams, UpdateRevenueBody, UpdateThemeColorBody, GenerateFirstLevelAgentLinkResponse, UpdateWithdrawPasswordBody, UpdateWithdrawPasswordResponse, WithdrawPasswordStatusResponse } from '../dto/team.dto' import { UserRole } from '../entities/user.entity' import { instanceToPlain } from 'class-transformer' export class TeamController { private teamService: TeamService constructor(app: FastifyInstance) { this.teamService = new TeamService(app) } async create(request: FastifyRequest<{ Body: CreateTeamBody }>, reply: FastifyReply) { try { const team = await this.teamService.create(request.body, request.user.id) return reply.code(201).send(instanceToPlain(team)) } catch (error) { return reply.code(500).send({ message: '创建团队失败' }) } } async findById(request: FastifyRequest<{ Params: TeamParams }>, reply: FastifyReply) { try { const { id } = request.params const team = await this.teamService.findById(id) return reply.send(instanceToPlain(team)) } catch (error) { return reply.code(404).send({ message: '团队不存在' }) } } async findAll(request: FastifyRequest<{ Querystring: ListTeamQuery }>, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } if (user.role === UserRole.TEAM) { request.query.userId = user.id } const result = await this.teamService.findAll(request.query) return reply.send({ ...result, content: result.content.map(team => instanceToPlain(team)) }) } catch (error) { return reply.code(500).send({ message: '获取团队列表失败' }) } } async update(request: FastifyRequest<{ Params: TeamParams; Body: UpdateTeamBody }>, reply: FastifyReply) { try { const { id } = request.params const updateData = { ...request.body, id } try { await this.teamService.findById(id) } catch (error) { return reply.code(404).send({ message: '团队不存在' }) } const updatedTeam = await this.teamService.update(updateData) return reply.send(instanceToPlain(updatedTeam)) } catch (error) { return reply.code(500).send({ message: '更新团队失败' }) } } async delete(request: FastifyRequest<{ Params: TeamParams }>, reply: FastifyReply) { try { const { id } = request.params try { await this.teamService.findById(id) } catch (error) { return reply.code(404).send({ message: '团队不存在' }) } await this.teamService.delete(id) return reply.send({ message: '团队已删除' }) } catch (error) { return reply.code(500).send({ message: '删除团队失败' }) } } async updateRevenue(request: FastifyRequest<{ Body: UpdateRevenueBody }>, reply: FastifyReply) { try { const { id, amount, type } = request.body try { await this.teamService.findById(id) } catch (error) { return reply.code(404).send({ message: '团队不存在' }) } const updatedTeam = await this.teamService.updateRevenue(id, amount, type) return reply.send(instanceToPlain(updatedTeam)) } catch (error) { return reply.code(500).send({ message: '更新团队收入失败' }) } } async getStatistics(request: FastifyRequest, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } let userId: number | undefined if (user.role === UserRole.TEAM) { userId = user.id } const statistics = await this.teamService.getStatistics(userId) return reply.send(statistics) } catch (error) { return reply.code(500).send({ message: '获取统计数据失败' }) } } async getTeamStatistics(request: FastifyRequest, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } const statistics = await this.teamService.getTeamStatistics(user.id) return reply.send(statistics) } catch (error) { return reply.code(500).send({ message: '获取统计数据失败' }) } } async getTeams(request: FastifyRequest, reply: FastifyReply) { try { const teams = await this.teamService.getTeams() return reply.send(teams.map(team => instanceToPlain(team))) } catch (error) { return reply.code(500).send({ message: '获取团队失败' }) } } async findByUserId(request: FastifyRequest, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } const team = await this.teamService.findByUserId(user.id) return reply.send(instanceToPlain(team)) } catch (error) { return reply.code(404).send({ message: '团队不存在' }) } } async getIpConversionRate(request: FastifyRequest, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } // 允许团队用户和推广员使用此接口 if (user.role !== UserRole.TEAM && user.role !== UserRole.PROMOTER) { return reply.code(403).send({ message: '只有团队用户和推广员可以使用此接口' }) } const statistics = await this.teamService.getIpConversionRate(user.id, user.role) return reply.send(statistics) } catch (error) { return reply.code(500).send({ message: '获取IP成交率失败' }) } } async updateThemeColor(request: FastifyRequest<{ Body: UpdateThemeColorBody }>, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } // 只允许团队用户和管理员使用此接口 if (user.role !== UserRole.TEAM && user.role !== UserRole.ADMIN) { return reply.code(403).send({ message: '只有团队用户和管理员可以使用此接口' }) } const updatedTeam = await this.teamService.updateThemeColor(user.id, request.body.themeColor) return reply.send(instanceToPlain(updatedTeam)) } catch (error) { const errorMessage = error instanceof Error ? error.message : '更新主题颜色失败' return reply.code(500).send({ message: errorMessage }) } } async getMyTeamTheme(request: FastifyRequest, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } const themeColor = await this.teamService.getTeamThemeColorByUser(user.id, user.role as UserRole) if (!themeColor) { // 如果没有找到团队,返回默认主题 return reply.send({ themeColor: 'dark' }) } return reply.send(themeColor) } catch (error) { return reply.code(500).send({ message: '获取团队主题颜色失败' }) } } /** * 生成一级代理链接(不带code,直接域名跳转) * 一级代理就是团队(team) */ async generateFirstLevelAgentLink(request: FastifyRequest<{ Params: TeamParams }>, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } const { id } = request.params // 权限检查:只有团队管理员或系统管理员可以生成一级代理链接 if (user.role === UserRole.TEAM) { // 团队管理员只能为自己的团队生成一级代理链接 const team = await this.teamService.findByUserId(user.id) if (team.id !== Number(id)) { return reply.code(403).send({ message: '无权限为其他团队生成一级代理链接' }) } } else if (user.role !== UserRole.ADMIN) { return reply.code(403).send({ message: '无权限生成一级代理链接' }) } // 生成一级代理链接 const links = await this.teamService.generateFirstLevelAgentLink(Number(id)) const team = await this.teamService.findById(Number(id)) const response: GenerateFirstLevelAgentLinkResponse = { teamId: team.id, generalLink: links.generalLink, browserLink: links.browserLink, message: '一级代理链接生成成功' } return reply.send(response) } catch (error) { console.error('生成一级代理链接失败:', error) const errorMessage = error instanceof Error ? error.message : '未知错误' // 如果是找不到记录的错误,返回404 if (errorMessage.includes('Could not find any entity') || errorMessage.includes('未找到')) { return reply.code(404).send({ message: '团队不存在', error: errorMessage }) } // 如果未配置域名 if (errorMessage.includes('未配置域名')) { return reply.code(400).send({ message: errorMessage, error: 'CONFIG_ERROR' }) } return reply.code(500).send({ message: '生成一级代理链接失败', error: errorMessage }) } } /** * 修改团队提现密码 * 团队用户修改自己的提现密码,管理员可以通过路径参数指定团队ID */ async updateWithdrawPassword(request: FastifyRequest<{ Params?: TeamParams; Body: UpdateWithdrawPasswordBody }>, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } const { oldPassword, newPassword } = request.body if (!newPassword) { return reply.code(400).send({ message: '新密码不能为空' }) } let teamId: number // 权限检查:只有团队用户和管理员可以修改提现密码 if (user.role === UserRole.TEAM) { // 团队用户只能修改自己团队的提现密码 const team = await this.teamService.findByUserId(user.id) teamId = team.id } else if (user.role === UserRole.ADMIN) { // 管理员可以通过路径参数指定团队ID,如果没有指定则返回错误 if (request.params && request.params.id) { teamId = Number(request.params.id) } else { return reply.code(400).send({ message: '管理员需要指定团队ID' }) } } else { return reply.code(403).send({ message: '无权限修改提现密码' }) } await this.teamService.updateWithdrawPassword(teamId, oldPassword, newPassword) const response: UpdateWithdrawPasswordResponse = { message: '提现密码修改成功' } return reply.send(response) } catch (error) { console.error('修改提现密码失败:', error) const errorMessage = error instanceof Error ? error.message : '未知错误' if (errorMessage.includes('旧密码错误') || errorMessage.includes('请提供旧密码')) { return reply.code(400).send({ message: errorMessage, error: 'VALIDATION_ERROR' }) } return reply.code(500).send({ message: '修改提现密码失败', error: errorMessage }) } } /** * 检查团队是否已设置提现密码 * 团队用户检查自己的,管理员可以指定团队ID */ async checkWithdrawPasswordStatus(request: FastifyRequest<{ Params?: TeamParams }>, reply: FastifyReply) { try { const user = request.user if (!user) { return reply.code(403).send({ message: '用户未登录' }) } let teamId: number // 权限检查:只有团队用户和管理员可以检查提现密码状态 if (user.role === UserRole.TEAM) { // 团队用户只能检查自己团队的提现密码状态 const team = await this.teamService.findByUserId(user.id) teamId = team.id } else if (user.role === UserRole.ADMIN) { // 管理员可以通过路径参数指定团队ID,如果没有指定则返回错误 if (request.params && request.params.id) { teamId = Number(request.params.id) } else { return reply.code(400).send({ message: '管理员需要指定团队ID' }) } } else { return reply.code(403).send({ message: '无权限检查提现密码状态' }) } const hasPassword = await this.teamService.checkWithdrawPasswordStatus(teamId) const response: WithdrawPasswordStatusResponse = { hasPassword, message: hasPassword ? '已设置提现密码' : '未设置提现密码' } return reply.send(response) } catch (error) { console.error('检查提现密码状态失败:', error) const errorMessage = error instanceof Error ? error.message : '未知错误' return reply.code(500).send({ message: '检查提现密码状态失败', error: errorMessage }) } } }