fix(authorization): 修复 grantProvinceCompany 业务验证逻辑
- 添加省区域/市区域互斥检查:同一用户不能同时拥有两种身份 - 添加省区域全局唯一性检查:整个系统只允许一个省区域角色被授权 - 添加 findAnyProvinceCompany 仓储方法用于全局唯一性校验 - 移除错误的 validateAuthorizationRequest 调用(该方法只适用于团队角色) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
298ce52fc7
commit
4478351f89
|
|
@ -268,27 +268,46 @@ export class AuthorizationApplicationService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理员授权正式省公司(省区域)
|
* 管理员授权正式省公司(省区域)
|
||||||
* 需要验证团队内唯一性:同一推荐链上不能有重复的相同省份授权
|
*
|
||||||
|
* 业务规则:
|
||||||
|
* - 同一个用户不能同时拥有省区域和市区域两种身份
|
||||||
|
* - 整个系统中只允许一个省区域角色被授权(全局唯一)
|
||||||
*/
|
*/
|
||||||
async grantProvinceCompany(command: GrantProvinceCompanyCommand): Promise<void> {
|
async grantProvinceCompany(command: GrantProvinceCompanyCommand): Promise<void> {
|
||||||
const userId = UserId.create(command.userId, command.accountSequence)
|
const userId = UserId.create(command.userId, command.accountSequence)
|
||||||
const adminId = AdminUserId.create(command.adminId, command.adminAccountSequence)
|
const adminId = AdminUserId.create(command.adminId, command.adminAccountSequence)
|
||||||
const regionCode = RegionCode.create(command.provinceCode)
|
|
||||||
|
|
||||||
// 1. 验证团队内唯一性(同一推荐链上不能有重复的相同省份授权)
|
// 1. 检查用户是否已有市区域授权(省区域和市区域互斥)
|
||||||
const validation = await this.validatorService.validateAuthorizationRequest(
|
const existingCityCompany = await this.authorizationRepository.findByAccountSequenceAndRoleType(
|
||||||
userId,
|
command.accountSequence,
|
||||||
RoleType.PROVINCE_COMPANY,
|
RoleType.CITY_COMPANY,
|
||||||
regionCode,
|
|
||||||
this.referralRepository,
|
|
||||||
this.authorizationRepository,
|
|
||||||
)
|
)
|
||||||
|
if (existingCityCompany && existingCityCompany.status !== AuthorizationStatus.REVOKED) {
|
||||||
if (!validation.isValid) {
|
throw new ApplicationError(
|
||||||
throw new ApplicationError(validation.errorMessage!)
|
`用户 ${command.accountSequence} 已拥有市区域角色「${existingCityCompany.regionName}」,不能同时拥有省区域角色`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 创建授权
|
// 2. 检查用户是否已有省区域授权(一个用户只能有一个省区域)
|
||||||
|
const existingProvinceCompany = await this.authorizationRepository.findByAccountSequenceAndRoleType(
|
||||||
|
command.accountSequence,
|
||||||
|
RoleType.PROVINCE_COMPANY,
|
||||||
|
)
|
||||||
|
if (existingProvinceCompany && existingProvinceCompany.status !== AuthorizationStatus.REVOKED) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
`用户 ${command.accountSequence} 已拥有省区域角色「${existingProvinceCompany.regionName}」,不能重复授权`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查系统中是否已有省区域授权(整个系统全局唯一)
|
||||||
|
const existingAnyProvince = await this.authorizationRepository.findAnyProvinceCompany()
|
||||||
|
if (existingAnyProvince) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
`系统中已有省区域角色授权给用户 ${existingAnyProvince.userId.accountSequence}(${existingAnyProvince.regionName}),整个系统只允许一个省区域角色`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 创建授权
|
||||||
const authorization = AuthorizationRole.createProvinceCompany({
|
const authorization = AuthorizationRole.createProvinceCompany({
|
||||||
userId,
|
userId,
|
||||||
provinceCode: command.provinceCode,
|
provinceCode: command.provinceCode,
|
||||||
|
|
|
||||||
|
|
@ -96,4 +96,9 @@ export interface IAuthorizationRoleRepository {
|
||||||
* 根据社区名称查找社区授权(用于社区名称全局唯一性校验)
|
* 根据社区名称查找社区授权(用于社区名称全局唯一性校验)
|
||||||
*/
|
*/
|
||||||
findCommunityByName(communityName: string): Promise<AuthorizationRole | null>
|
findCommunityByName(communityName: string): Promise<AuthorizationRole | null>
|
||||||
|
/**
|
||||||
|
* 查找系统中任何已授权的省区域角色(用于省区域全局唯一性校验)
|
||||||
|
* 整个系统只允许一个省区域角色被授权
|
||||||
|
*/
|
||||||
|
findAnyProvinceCompany(): Promise<AuthorizationRole | null>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,16 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findAnyProvinceCompany(): Promise<AuthorizationRole | null> {
|
||||||
|
const record = await this.prisma.authorizationRole.findFirst({
|
||||||
|
where: {
|
||||||
|
roleType: RoleType.PROVINCE_COMPANY,
|
||||||
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return record ? this.toDomain(record) : null
|
||||||
|
}
|
||||||
|
|
||||||
private toDomain(record: any): AuthorizationRole {
|
private toDomain(record: any): AuthorizationRole {
|
||||||
const props: AuthorizationRoleProps = {
|
const props: AuthorizationRoleProps = {
|
||||||
authorizationId: AuthorizationId.create(record.id),
|
authorizationId: AuthorizationId.create(record.id),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue