import { Controller, Get, Post, Delete, Param, Body, Query, UseGuards, HttpCode, HttpStatus, } from '@nestjs/common' import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiParam, ApiQuery, } from '@nestjs/swagger' import { AuthorizationApplicationService } from '@/application/services' import { ApplyCommunityAuthCommand, ApplyAuthProvinceCompanyCommand, ApplyAuthCityCompanyCommand, RevokeAuthorizationCommand, GrantMonthlyBypassCommand, ExemptLocalPercentageCheckCommand, SelfApplyAuthorizationCommand, } from '@/application/commands' import { ApplyCommunityAuthDto, ApplyAuthProvinceDto, ApplyAuthCityDto, RevokeAuthorizationDto, GrantMonthlyBypassDto, SelfApplyAuthorizationDto, SelfApplyAuthorizationResponseDto, UserAuthorizationStatusResponseDto, SelfApplyAuthorizationType, } from '@/api/dto/request' import { AuthorizationResponse, ApplyAuthorizationResponse, StickmanRankingResponse, CommunityHierarchyResponse, UserProfilePublicResponse, UserProfilePrivateResponse, } from '@/api/dto/response' import { CurrentUser } from '@/shared/decorators' import { JwtAuthGuard } from '@/shared/guards' import { RoleType } from '@/domain/enums' @ApiTags('Authorization') @Controller('authorizations') @UseGuards(JwtAuthGuard) @ApiBearerAuth() export class AuthorizationController { constructor(private readonly applicationService: AuthorizationApplicationService) {} @Post('community') @ApiOperation({ summary: '申请社区授权' }) @ApiResponse({ status: 201, type: ApplyAuthorizationResponse }) async applyCommunityAuth( @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: ApplyCommunityAuthDto, ): Promise { const command = new ApplyCommunityAuthCommand(user.userId, user.accountSequence, dto.communityName) return await this.applicationService.applyCommunityAuth(command) } @Post('province') @ApiOperation({ summary: '申请授权省公司' }) @ApiResponse({ status: 201, type: ApplyAuthorizationResponse }) async applyAuthProvinceCompany( @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: ApplyAuthProvinceDto, ): Promise { const command = new ApplyAuthProvinceCompanyCommand( user.userId, user.accountSequence, dto.provinceCode, dto.provinceName, ) return await this.applicationService.applyAuthProvinceCompany(command) } @Post('city') @ApiOperation({ summary: '申请授权市公司' }) @ApiResponse({ status: 201, type: ApplyAuthorizationResponse }) async applyAuthCityCompany( @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: ApplyAuthCityDto, ): Promise { const command = new ApplyAuthCityCompanyCommand(user.userId, user.accountSequence, dto.cityCode, dto.cityName) return await this.applicationService.applyAuthCityCompany(command) } @Get('my') @ApiOperation({ summary: '获取我的授权列表' }) @ApiResponse({ status: 200, type: [AuthorizationResponse] }) async getMyAuthorizations( @CurrentUser() user: { userId: string; accountSequence: string }, ): Promise { return await this.applicationService.getUserAuthorizations(user.accountSequence) } @Get('my/community-hierarchy') @ApiOperation({ summary: '获取我的社区层级(上级社区和下级社区)' }) @ApiResponse({ status: 200, type: CommunityHierarchyResponse }) async getMyCommunityHierarchy( @CurrentUser() user: { userId: string; accountSequence: string }, ): Promise { return await this.applicationService.getCommunityHierarchy(user.accountSequence) } @Get(':id') @ApiOperation({ summary: '获取授权详情' }) @ApiParam({ name: 'id', description: '授权ID' }) @ApiResponse({ status: 200, type: AuthorizationResponse }) async getAuthorizationById(@Param('id') id: string): Promise { return await this.applicationService.getAuthorizationById(id) } @Get('ranking/stickman') @ApiOperation({ summary: '获取火柴人排名' }) @ApiQuery({ name: 'month', description: '月份 (YYYY-MM)', example: '2024-01' }) @ApiQuery({ name: 'roleType', description: '角色类型', enum: RoleType }) @ApiQuery({ name: 'regionCode', description: '区域代码' }) @ApiResponse({ status: 200, type: [StickmanRankingResponse] }) async getStickmanRanking( @CurrentUser() user: { userId: string; accountSequence: string }, @Query('month') month: string, @Query('roleType') roleType: RoleType, @Query('regionCode') regionCode: string, ): Promise { return await this.applicationService.getStickmanRanking(month, roleType, regionCode, user.userId) } @Delete(':id') @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: '撤销授权(管理员)' }) @ApiParam({ name: 'id', description: '授权ID' }) @ApiResponse({ status: 204 }) async revokeAuthorization( @Param('id') id: string, @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: RevokeAuthorizationDto, ): Promise { const command = new RevokeAuthorizationCommand(id, user.accountSequence, dto.reason) await this.applicationService.revokeAuthorization(command) } @Post(':id/bypass') @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: '授予单月豁免(管理员)' }) @ApiParam({ name: 'id', description: '授权ID' }) @ApiResponse({ status: 204 }) async grantMonthlyBypass( @Param('id') id: string, @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: GrantMonthlyBypassDto, ): Promise { const command = new GrantMonthlyBypassCommand(id, dto.month, user.accountSequence, dto.reason) await this.applicationService.grantMonthlyBypass(command) } @Post(':id/exempt-percentage') @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: '豁免占比考核(管理员)' }) @ApiParam({ name: 'id', description: '授权ID' }) @ApiResponse({ status: 204 }) async exemptLocalPercentageCheck( @Param('id') id: string, @CurrentUser() user: { userId: string; accountSequence: string }, ): Promise { const command = new ExemptLocalPercentageCheckCommand(id, user.accountSequence) await this.applicationService.exemptLocalPercentageCheck(command) } // ============================================ // 自助申请授权相关接口 // ============================================ @Get('self-apply/status') @ApiOperation({ summary: '获取用户授权申请状态', description: '获取用户是否已认种、认种棵数、已有授权和待审核申请', }) @ApiResponse({ status: 200, type: UserAuthorizationStatusResponseDto }) async getUserAuthorizationStatus( @CurrentUser() user: { userId: string; accountSequence: string }, ): Promise { return await this.applicationService.getUserAuthorizationStatus(user.accountSequence) } @Post('self-apply') @ApiOperation({ summary: '自助申请授权', description: '用户自助申请社区、市团队或省团队授权(需先认种并上传办公室照片)', }) @ApiResponse({ status: 201, type: SelfApplyAuthorizationResponseDto }) async selfApplyAuthorization( @CurrentUser() user: { userId: string; accountSequence: string }, @Body() dto: SelfApplyAuthorizationDto, ): Promise { const command = new SelfApplyAuthorizationCommand( user.userId, user.accountSequence, dto.type, dto.officePhotoUrls, dto.communityName, dto.provinceCode, dto.provinceName, dto.cityCode, dto.cityName, ) return await this.applicationService.selfApplyAuthorization(command) } // ============================================ // 用户资料相关接口 // ============================================ @Get('users/:accountSequence/profile') @ApiOperation({ summary: '获取用户公开资料', description: '获取指定用户的公开资料,包括昵称、头像、注册时间、推荐人、直推人数、伞下用户数、认种数量、授权列表等', }) @ApiParam({ name: 'accountSequence', description: '目标用户的账户序列号' }) @ApiResponse({ status: 200, type: UserProfilePublicResponse }) async getUserProfile( @Param('accountSequence') accountSequence: string, ): Promise { return await this.applicationService.getUserPublicProfile(accountSequence) } @Get('users/:accountSequence/profile/private') @ApiOperation({ summary: '获取用户私密资料', description: '获取指定用户的私密资料(需要省团队以上权限),包括脱敏的手机号、邮箱、真实姓名等', }) @ApiParam({ name: 'accountSequence', description: '目标用户的账户序列号' }) @ApiResponse({ status: 200, type: UserProfilePrivateResponse }) async getUserPrivateProfile( @CurrentUser() user: { userId: string; accountSequence: string }, @Param('accountSequence') accountSequence: string, ): Promise { return await this.applicationService.getUserPrivateProfile(user.accountSequence, accountSequence) } }