diff --git a/backend/services/authorization-service/src/application/services/authorization-application.service.ts b/backend/services/authorization-service/src/application/services/authorization-application.service.ts index 50993f0b..513fc7d4 100644 --- a/backend/services/authorization-service/src/application/services/authorization-application.service.ts +++ b/backend/services/authorization-service/src/application/services/authorization-application.service.ts @@ -225,11 +225,35 @@ export class AuthorizationApplicationService { /** * 管理员直接授权社区 + * + * 业务规则: + * - 一个用户只能拥有一个社区角色 + * - 社区名称全局唯一,不允许重复 */ async grantCommunity(command: GrantCommunityCommand): Promise { const userId = UserId.create(command.userId, command.accountSequence) const adminId = AdminUserId.create(command.adminId, command.adminAccountSequence) + // 1. 检查用户是否已有社区角色 + const existingUserCommunity = await this.authorizationRepository.findByAccountSequenceAndRoleType( + command.accountSequence, + RoleType.COMMUNITY, + ) + if (existingUserCommunity) { + throw new ApplicationError( + `用户 ${command.accountSequence} 已拥有社区角色「${existingUserCommunity.displayTitle}」,不能重复授权`, + ) + } + + // 2. 检查社区名称是否已被使用 + const existingCommunityName = await this.authorizationRepository.findCommunityByName(command.communityName) + if (existingCommunityName) { + throw new ApplicationError( + `社区名称「${command.communityName}」已被使用,请选择其他名称`, + ) + } + + // 3. 创建社区授权 const authorization = AuthorizationRole.createCommunity({ userId, communityName: command.communityName, diff --git a/backend/services/authorization-service/src/domain/repositories/authorization-role.repository.ts b/backend/services/authorization-service/src/domain/repositories/authorization-role.repository.ts index 0aee6576..548fd7fa 100644 --- a/backend/services/authorization-service/src/domain/repositories/authorization-role.repository.ts +++ b/backend/services/authorization-service/src/domain/repositories/authorization-role.repository.ts @@ -92,4 +92,8 @@ export interface IAuthorizationRoleRepository { checkDate: Date, limit: number, ): Promise + /** + * 根据社区名称查找社区授权(用于社区名称全局唯一性校验) + */ + findCommunityByName(communityName: string): Promise } diff --git a/backend/services/authorization-service/src/infrastructure/persistence/repositories/authorization-role.repository.impl.ts b/backend/services/authorization-service/src/infrastructure/persistence/repositories/authorization-role.repository.impl.ts index 53478414..d4069a58 100644 --- a/backend/services/authorization-service/src/infrastructure/persistence/repositories/authorization-role.repository.impl.ts +++ b/backend/services/authorization-service/src/infrastructure/persistence/repositories/authorization-role.repository.impl.ts @@ -389,6 +389,16 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi return records.map((record) => this.toDomain(record)) } + async findCommunityByName(communityName: string): Promise { + const record = await this.prisma.authorizationRole.findFirst({ + where: { + roleType: RoleType.COMMUNITY, + regionCode: communityName, + }, + }) + return record ? this.toDomain(record) : null + } + private toDomain(record: any): AuthorizationRole { const props: AuthorizationRoleProps = { authorizationId: AuthorizationId.create(record.id),