rwadurian/backend/services/authorization-service/src/api/controllers/authorization.controller.ts

252 lines
9.3 KiB
TypeScript

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<ApplyAuthorizationResponse> {
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<ApplyAuthorizationResponse> {
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<ApplyAuthorizationResponse> {
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<AuthorizationResponse[]> {
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<CommunityHierarchyResponse> {
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<AuthorizationResponse | null> {
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<StickmanRankingResponse[]> {
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<void> {
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<void> {
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<void> {
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<UserAuthorizationStatusResponseDto> {
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<SelfApplyAuthorizationResponseDto> {
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<UserProfilePublicResponse> {
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<UserProfilePrivateResponse> {
return await this.applicationService.getUserPrivateProfile(user.accountSequence, accountSequence)
}
}