feat(authorization): 实现软删除支持撤销后重新授权
- 添加 deletedAt 字段到 AuthorizationRole 聚合根和 Prisma schema - revoke() 方法同时设置 deletedAt,使撤销的记录被软删除 - Repository 所有查询添加 deletedAt: null 过滤条件 - 创建部分唯一索引,只对未删除记录生效 (大厂通用做法) - 支持撤销授权后重新创建相同角色 🤖 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
15e2bfe236
commit
29df9955f9
|
|
@ -0,0 +1,25 @@
|
||||||
|
-- 软删除支持迁移
|
||||||
|
-- 大厂通用做法: deleted_at 为 NULL 表示未删除,通过部分唯一索引确保有效记录唯一
|
||||||
|
|
||||||
|
-- 1. 添加 deleted_at 字段
|
||||||
|
ALTER TABLE authorization_roles
|
||||||
|
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP;
|
||||||
|
|
||||||
|
-- 2. 将现有 REVOKED 状态的记录设置 deleted_at
|
||||||
|
UPDATE authorization_roles
|
||||||
|
SET deleted_at = revoked_at
|
||||||
|
WHERE status = 'REVOKED' AND deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- 3. 删除原有的唯一约束(如果存在)
|
||||||
|
ALTER TABLE authorization_roles
|
||||||
|
DROP CONSTRAINT IF EXISTS authorization_roles_account_sequence_role_type_region_code_key;
|
||||||
|
|
||||||
|
-- 4. 创建部分唯一索引(只对未删除的记录生效)
|
||||||
|
-- 这是大厂的标准做法,支持软删除后重新创建相同记录
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS uk_authorization_active
|
||||||
|
ON authorization_roles (account_sequence, role_type, region_code)
|
||||||
|
WHERE deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- 5. 创建 deleted_at 索引用于查询优化
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_authorization_deleted_at
|
||||||
|
ON authorization_roles (deleted_at);
|
||||||
|
|
@ -28,6 +28,9 @@ model AuthorizationRole {
|
||||||
revokedBy String? @map("revoked_by")
|
revokedBy String? @map("revoked_by")
|
||||||
revokeReason String? @map("revoke_reason")
|
revokeReason String? @map("revoke_reason")
|
||||||
|
|
||||||
|
// 软删除 (大厂通用做法: deleted_at 为 NULL 表示未删除)
|
||||||
|
deletedAt DateTime? @map("deleted_at")
|
||||||
|
|
||||||
// 考核配置
|
// 考核配置
|
||||||
initialTargetTreeCount Int @map("initial_target_tree_count")
|
initialTargetTreeCount Int @map("initial_target_tree_count")
|
||||||
monthlyTargetType MonthlyTargetType @map("monthly_target_type")
|
monthlyTargetType MonthlyTargetType @map("monthly_target_type")
|
||||||
|
|
@ -58,12 +61,15 @@ model AuthorizationRole {
|
||||||
assessments MonthlyAssessment[]
|
assessments MonthlyAssessment[]
|
||||||
bypassRecords MonthlyBypass[]
|
bypassRecords MonthlyBypass[]
|
||||||
|
|
||||||
@@unique([accountSequence, roleType, regionCode])
|
// 注意: 唯一约束通过数据库层的部分索引实现,只对 deleted_at IS NULL 的记录生效
|
||||||
|
// 需要手动执行迁移 SQL 创建部分唯一索引
|
||||||
|
// @@unique([accountSequence, roleType, regionCode]) -- 已移除,改用部分索引
|
||||||
@@index([accountSequence])
|
@@index([accountSequence])
|
||||||
@@index([userId])
|
@@index([userId])
|
||||||
@@index([roleType, regionCode])
|
@@index([roleType, regionCode])
|
||||||
@@index([status])
|
@@index([status])
|
||||||
@@index([roleType, status])
|
@@index([roleType, status])
|
||||||
|
@@index([deletedAt])
|
||||||
@@map("authorization_roles")
|
@@map("authorization_roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export interface AuthorizationRoleProps {
|
||||||
monthlyTreesAdded: number // 当月新增树数
|
monthlyTreesAdded: number // 当月新增树数
|
||||||
lastMonthTreesAdded: number // 上月新增树数(考核用存档)
|
lastMonthTreesAdded: number // 上月新增树数(考核用存档)
|
||||||
currentMonthIndex: number
|
currentMonthIndex: number
|
||||||
|
deletedAt: Date | null // 软删除时间 (大厂通用做法)
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +90,9 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
// 当前考核月份索引
|
// 当前考核月份索引
|
||||||
private _currentMonthIndex: number
|
private _currentMonthIndex: number
|
||||||
|
|
||||||
|
// 软删除 (大厂通用做法)
|
||||||
|
private _deletedAt: Date | null
|
||||||
|
|
||||||
private _createdAt: Date
|
private _createdAt: Date
|
||||||
private _updatedAt: Date
|
private _updatedAt: Date
|
||||||
|
|
||||||
|
|
@ -168,6 +172,9 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
get updatedAt(): Date {
|
get updatedAt(): Date {
|
||||||
return this._updatedAt
|
return this._updatedAt
|
||||||
}
|
}
|
||||||
|
get deletedAt(): Date | null {
|
||||||
|
return this._deletedAt
|
||||||
|
}
|
||||||
get isActive(): boolean {
|
get isActive(): boolean {
|
||||||
return this._status === AuthorizationStatus.AUTHORIZED
|
return this._status === AuthorizationStatus.AUTHORIZED
|
||||||
}
|
}
|
||||||
|
|
@ -198,6 +205,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
this._monthlyTreesAdded = props.monthlyTreesAdded
|
this._monthlyTreesAdded = props.monthlyTreesAdded
|
||||||
this._lastMonthTreesAdded = props.lastMonthTreesAdded
|
this._lastMonthTreesAdded = props.lastMonthTreesAdded
|
||||||
this._currentMonthIndex = props.currentMonthIndex
|
this._currentMonthIndex = props.currentMonthIndex
|
||||||
|
this._deletedAt = props.deletedAt
|
||||||
this._createdAt = props.createdAt
|
this._createdAt = props.createdAt
|
||||||
this._updatedAt = props.updatedAt
|
this._updatedAt = props.updatedAt
|
||||||
}
|
}
|
||||||
|
|
@ -259,6 +267,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: 0,
|
currentMonthIndex: 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
})
|
})
|
||||||
|
|
@ -307,6 +316,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: skipAssessment ? 1 : 0,
|
currentMonthIndex: skipAssessment ? 1 : 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -354,6 +364,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: 0,
|
currentMonthIndex: 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -404,6 +415,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: 1, // 从第1个月开始考核
|
currentMonthIndex: 1, // 从第1个月开始考核
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -452,6 +464,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: 0,
|
currentMonthIndex: 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -502,6 +515,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: 1, // 从第1个月开始考核
|
currentMonthIndex: 1, // 从第1个月开始考核
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -553,6 +567,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: skipAssessment ? 1 : 0,
|
currentMonthIndex: skipAssessment ? 1 : 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -604,6 +619,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: 0,
|
monthlyTreesAdded: 0,
|
||||||
lastMonthTreesAdded: 0,
|
lastMonthTreesAdded: 0,
|
||||||
currentMonthIndex: skipAssessment ? 1 : 0,
|
currentMonthIndex: skipAssessment ? 1 : 0,
|
||||||
|
deletedAt: null,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
})
|
})
|
||||||
|
|
@ -783,19 +799,22 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 撤销授权
|
* 撤销授权
|
||||||
|
* 软删除: 设置 deletedAt 使记录在查询时被过滤 (大厂通用做法)
|
||||||
*/
|
*/
|
||||||
revoke(adminId: AdminUserId, reason: string): void {
|
revoke(adminId: AdminUserId, reason: string): void {
|
||||||
if (this._status === AuthorizationStatus.REVOKED) {
|
if (this._status === AuthorizationStatus.REVOKED) {
|
||||||
throw new DomainError('已撤销')
|
throw new DomainError('已撤销')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const now = new Date()
|
||||||
this._status = AuthorizationStatus.REVOKED
|
this._status = AuthorizationStatus.REVOKED
|
||||||
this._revokedAt = new Date()
|
this._revokedAt = now
|
||||||
this._revokedBy = adminId
|
this._revokedBy = adminId
|
||||||
this._revokeReason = reason
|
this._revokeReason = reason
|
||||||
this._benefitActive = false
|
this._benefitActive = false
|
||||||
this._benefitDeactivatedAt = new Date()
|
this._benefitDeactivatedAt = now
|
||||||
this._updatedAt = new Date()
|
this._deletedAt = now // 软删除: 允许将来重新创建相同 accountSequence + roleType + regionCode 的授权
|
||||||
|
this._updatedAt = now
|
||||||
|
|
||||||
this.addDomainEvent(
|
this.addDomainEvent(
|
||||||
new RoleRevokedEvent({
|
new RoleRevokedEvent({
|
||||||
|
|
@ -904,6 +923,7 @@ export class AuthorizationRole extends AggregateRoot {
|
||||||
monthlyTreesAdded: this._monthlyTreesAdded,
|
monthlyTreesAdded: this._monthlyTreesAdded,
|
||||||
lastMonthTreesAdded: this._lastMonthTreesAdded,
|
lastMonthTreesAdded: this._lastMonthTreesAdded,
|
||||||
currentMonthIndex: this._currentMonthIndex,
|
currentMonthIndex: this._currentMonthIndex,
|
||||||
|
deletedAt: this._deletedAt,
|
||||||
createdAt: this._createdAt,
|
createdAt: this._createdAt,
|
||||||
updatedAt: this._updatedAt,
|
updatedAt: this._updatedAt,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ import { RoleType, AuthorizationStatus, MonthlyTargetType } from '@/domain/enums
|
||||||
export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleRepository {
|
export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleRepository {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
// 软删除过滤条件 (大厂通用做法)
|
||||||
|
private readonly notDeleted = { deletedAt: null }
|
||||||
|
|
||||||
async save(authorization: AuthorizationRole): Promise<void> {
|
async save(authorization: AuthorizationRole): Promise<void> {
|
||||||
const data = authorization.toPersistence()
|
const data = authorization.toPersistence()
|
||||||
await this.prisma.authorizationRole.upsert({
|
await this.prisma.authorizationRole.upsert({
|
||||||
|
|
@ -48,6 +51,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
monthlyTreesAdded: data.monthlyTreesAdded,
|
monthlyTreesAdded: data.monthlyTreesAdded,
|
||||||
lastMonthTreesAdded: data.lastMonthTreesAdded,
|
lastMonthTreesAdded: data.lastMonthTreesAdded,
|
||||||
currentMonthIndex: data.currentMonthIndex,
|
currentMonthIndex: data.currentMonthIndex,
|
||||||
|
deletedAt: data.deletedAt,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
status: data.status,
|
status: data.status,
|
||||||
|
|
@ -67,13 +71,14 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
monthlyTreesAdded: data.monthlyTreesAdded,
|
monthlyTreesAdded: data.monthlyTreesAdded,
|
||||||
lastMonthTreesAdded: data.lastMonthTreesAdded,
|
lastMonthTreesAdded: data.lastMonthTreesAdded,
|
||||||
currentMonthIndex: data.currentMonthIndex,
|
currentMonthIndex: data.currentMonthIndex,
|
||||||
|
deletedAt: data.deletedAt,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(authorizationId: AuthorizationId): Promise<AuthorizationRole | null> {
|
async findById(authorizationId: AuthorizationId): Promise<AuthorizationRole | null> {
|
||||||
const record = await this.prisma.authorizationRole.findUnique({
|
const record = await this.prisma.authorizationRole.findFirst({
|
||||||
where: { id: authorizationId.value },
|
where: { id: authorizationId.value, ...this.notDeleted },
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +91,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
where: {
|
where: {
|
||||||
userId: userId.value,
|
userId: userId.value,
|
||||||
roleType: roleType,
|
roleType: roleType,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -101,6 +107,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
userId: userId.value,
|
userId: userId.value,
|
||||||
roleType: roleType,
|
roleType: roleType,
|
||||||
regionCode: regionCode.value,
|
regionCode: regionCode.value,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -114,6 +121,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
where: {
|
where: {
|
||||||
accountSequence: accountSequence,
|
accountSequence: accountSequence,
|
||||||
roleType: roleType,
|
roleType: roleType,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -121,7 +129,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
|
|
||||||
async findByUserId(userId: UserId): Promise<AuthorizationRole[]> {
|
async findByUserId(userId: UserId): Promise<AuthorizationRole[]> {
|
||||||
const records = await this.prisma.authorizationRole.findMany({
|
const records = await this.prisma.authorizationRole.findMany({
|
||||||
where: { userId: userId.value },
|
where: { userId: userId.value, ...this.notDeleted },
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
|
|
@ -129,7 +137,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
|
|
||||||
async findByAccountSequence(accountSequence: string): Promise<AuthorizationRole[]> {
|
async findByAccountSequence(accountSequence: string): Promise<AuthorizationRole[]> {
|
||||||
const records = await this.prisma.authorizationRole.findMany({
|
const records = await this.prisma.authorizationRole.findMany({
|
||||||
where: { accountSequence: accountSequence },
|
where: { accountSequence: accountSequence, ...this.notDeleted },
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
|
|
@ -145,6 +153,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
regionCode: regionCode.value,
|
regionCode: regionCode.value,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
benefitActive: true,
|
benefitActive: true,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
|
|
@ -156,6 +165,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
benefitActive: true,
|
benefitActive: true,
|
||||||
...(roleType && { roleType }),
|
...(roleType && { roleType }),
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
|
|
@ -166,6 +176,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
where: {
|
where: {
|
||||||
userId: userId.value,
|
userId: userId.value,
|
||||||
status: AuthorizationStatus.PENDING,
|
status: AuthorizationStatus.PENDING,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
|
|
@ -173,7 +184,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
|
|
||||||
async findByStatus(status: AuthorizationStatus): Promise<AuthorizationRole[]> {
|
async findByStatus(status: AuthorizationStatus): Promise<AuthorizationRole[]> {
|
||||||
const records = await this.prisma.authorizationRole.findMany({
|
const records = await this.prisma.authorizationRole.findMany({
|
||||||
where: { status },
|
where: { status, ...this.notDeleted },
|
||||||
})
|
})
|
||||||
return records.map((record) => this.toDomain(record))
|
return records.map((record) => this.toDomain(record))
|
||||||
}
|
}
|
||||||
|
|
@ -198,6 +209,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
accountSequence: { in: accountSequences },
|
accountSequence: { in: accountSequences },
|
||||||
roleType: RoleType.COMMUNITY,
|
roleType: RoleType.COMMUNITY,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
})
|
})
|
||||||
|
|
@ -219,6 +231,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
regionCode: provinceCode,
|
regionCode: provinceCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
benefitActive: true,
|
benefitActive: true,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
})
|
})
|
||||||
|
|
@ -240,6 +253,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
regionCode: cityCode,
|
regionCode: cityCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
benefitActive: true,
|
benefitActive: true,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
})
|
})
|
||||||
|
|
@ -258,6 +272,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
accountSequence: { in: accountSequences },
|
accountSequence: { in: accountSequences },
|
||||||
roleType: RoleType.COMMUNITY,
|
roleType: RoleType.COMMUNITY,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
// 注意:不过滤 benefitActive,用于计算社区权益分配
|
// 注意:不过滤 benefitActive,用于计算社区权益分配
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
|
|
@ -279,6 +294,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
roleType: RoleType.AUTH_PROVINCE_COMPANY,
|
roleType: RoleType.AUTH_PROVINCE_COMPANY,
|
||||||
regionCode: provinceCode,
|
regionCode: provinceCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
// 注意:不过滤 benefitActive,用于计算省团队权益分配
|
// 注意:不过滤 benefitActive,用于计算省团队权益分配
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
|
|
@ -300,6 +316,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
roleType: RoleType.AUTH_CITY_COMPANY,
|
roleType: RoleType.AUTH_CITY_COMPANY,
|
||||||
regionCode: cityCode,
|
regionCode: cityCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
// 注意:不过滤 benefitActive,用于计算市团队权益分配
|
// 注意:不过滤 benefitActive,用于计算市团队权益分配
|
||||||
},
|
},
|
||||||
orderBy: { accountSequence: 'asc' },
|
orderBy: { accountSequence: 'asc' },
|
||||||
|
|
@ -319,6 +336,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
accountSequence: { in: accountSequences },
|
accountSequence: { in: accountSequences },
|
||||||
roleType: RoleType.AUTH_PROVINCE_COMPANY,
|
roleType: RoleType.AUTH_PROVINCE_COMPANY,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
// 注意:不过滤 benefitActive,用于计算省团队权益分配
|
// 注意:不过滤 benefitActive,用于计算省团队权益分配
|
||||||
// 注意:不过滤 regionCode,省团队收益不要求省份匹配
|
// 注意:不过滤 regionCode,省团队收益不要求省份匹配
|
||||||
},
|
},
|
||||||
|
|
@ -339,6 +357,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
accountSequence: { in: accountSequences },
|
accountSequence: { in: accountSequences },
|
||||||
roleType: RoleType.AUTH_CITY_COMPANY,
|
roleType: RoleType.AUTH_CITY_COMPANY,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
// 注意:不过滤 benefitActive,用于计算市团队权益分配
|
// 注意:不过滤 benefitActive,用于计算市团队权益分配
|
||||||
// 注意:不过滤 regionCode,市团队收益不要求城市匹配
|
// 注意:不过滤 regionCode,市团队收益不要求城市匹配
|
||||||
},
|
},
|
||||||
|
|
@ -353,6 +372,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
roleType: RoleType.PROVINCE_COMPANY,
|
roleType: RoleType.PROVINCE_COMPANY,
|
||||||
regionCode: provinceCode,
|
regionCode: provinceCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -364,6 +384,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
roleType: RoleType.CITY_COMPANY,
|
roleType: RoleType.CITY_COMPANY,
|
||||||
regionCode: cityCode,
|
regionCode: cityCode,
|
||||||
status: AuthorizationStatus.AUTHORIZED,
|
status: AuthorizationStatus.AUTHORIZED,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -382,6 +403,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
benefitValidUntil: {
|
benefitValidUntil: {
|
||||||
lt: checkDate,
|
lt: checkDate,
|
||||||
},
|
},
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
take: limit,
|
take: limit,
|
||||||
orderBy: { benefitValidUntil: 'asc' },
|
orderBy: { benefitValidUntil: 'asc' },
|
||||||
|
|
@ -394,6 +416,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
where: {
|
where: {
|
||||||
roleType: RoleType.COMMUNITY,
|
roleType: RoleType.COMMUNITY,
|
||||||
regionCode: communityName,
|
regionCode: communityName,
|
||||||
|
...this.notDeleted,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return record ? this.toDomain(record) : null
|
return record ? this.toDomain(record) : null
|
||||||
|
|
@ -427,6 +450,7 @@ export class AuthorizationRoleRepositoryImpl implements IAuthorizationRoleReposi
|
||||||
monthlyTreesAdded: record.monthlyTreesAdded ?? 0,
|
monthlyTreesAdded: record.monthlyTreesAdded ?? 0,
|
||||||
lastMonthTreesAdded: record.lastMonthTreesAdded ?? 0,
|
lastMonthTreesAdded: record.lastMonthTreesAdded ?? 0,
|
||||||
currentMonthIndex: record.currentMonthIndex,
|
currentMonthIndex: record.currentMonthIndex,
|
||||||
|
deletedAt: record.deletedAt,
|
||||||
createdAt: record.createdAt,
|
createdAt: record.createdAt,
|
||||||
updatedAt: record.updatedAt,
|
updatedAt: record.updatedAt,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue