156 lines
4.7 KiB
TypeScript
156 lines
4.7 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { PrismaService } from '../database/prisma.service';
|
|
import { IVirtualAccountRepository } from '../../domain/repositories/virtual-account.repository.interface';
|
|
import { VirtualAccount } from '../../domain/entities/virtual-account.entity';
|
|
import { VirtualAccountType } from '../../domain/value-objects/virtual-account-type.enum';
|
|
import { Decimal } from '@prisma/client/runtime/library';
|
|
|
|
@Injectable()
|
|
export class VirtualAccountRepositoryImpl implements IVirtualAccountRepository {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async save(account: VirtualAccount): Promise<void> {
|
|
const data = {
|
|
accountType: account.accountType,
|
|
displayName: account.displayName,
|
|
avatar: account.avatar,
|
|
provinceCode: account.provinceCode,
|
|
cityCode: account.cityCode,
|
|
minScore: account.minScore,
|
|
maxScore: account.maxScore,
|
|
currentScore: account.currentScore,
|
|
usdtBalance: new Decimal(account.usdtBalance),
|
|
hashpowerBalance: new Decimal(account.hashpowerBalance),
|
|
isActive: account.isActive,
|
|
};
|
|
|
|
if (account.id) {
|
|
await this.prisma.virtualAccount.update({
|
|
where: { id: account.id },
|
|
data,
|
|
});
|
|
} else {
|
|
const result = await this.prisma.virtualAccount.create({
|
|
data,
|
|
});
|
|
account.setId(result.id);
|
|
}
|
|
}
|
|
|
|
async saveAll(accounts: VirtualAccount[]): Promise<void> {
|
|
await this.prisma.$transaction(
|
|
accounts.map((account) =>
|
|
this.prisma.virtualAccount.create({
|
|
data: {
|
|
accountType: account.accountType,
|
|
displayName: account.displayName,
|
|
avatar: account.avatar,
|
|
provinceCode: account.provinceCode,
|
|
cityCode: account.cityCode,
|
|
minScore: account.minScore,
|
|
maxScore: account.maxScore,
|
|
currentScore: account.currentScore,
|
|
usdtBalance: new Decimal(account.usdtBalance),
|
|
hashpowerBalance: new Decimal(account.hashpowerBalance),
|
|
isActive: account.isActive,
|
|
},
|
|
})
|
|
)
|
|
);
|
|
}
|
|
|
|
async findById(id: bigint): Promise<VirtualAccount | null> {
|
|
const record = await this.prisma.virtualAccount.findUnique({
|
|
where: { id },
|
|
});
|
|
|
|
if (!record) return null;
|
|
return this.toDomain(record);
|
|
}
|
|
|
|
async findByType(type: VirtualAccountType): Promise<VirtualAccount[]> {
|
|
const records = await this.prisma.virtualAccount.findMany({
|
|
where: { accountType: type },
|
|
orderBy: { createdAt: 'asc' },
|
|
});
|
|
|
|
return records.map((r) => this.toDomain(r));
|
|
}
|
|
|
|
async findActiveRankingVirtuals(limit: number): Promise<VirtualAccount[]> {
|
|
const records = await this.prisma.virtualAccount.findMany({
|
|
where: {
|
|
accountType: VirtualAccountType.RANKING_VIRTUAL,
|
|
isActive: true,
|
|
},
|
|
take: limit,
|
|
orderBy: { createdAt: 'asc' },
|
|
});
|
|
|
|
return records.map((r) => this.toDomain(r));
|
|
}
|
|
|
|
async findByProvinceCode(provinceCode: string): Promise<VirtualAccount | null> {
|
|
const record = await this.prisma.virtualAccount.findFirst({
|
|
where: {
|
|
accountType: VirtualAccountType.SYSTEM_PROVINCE,
|
|
provinceCode,
|
|
},
|
|
});
|
|
|
|
if (!record) return null;
|
|
return this.toDomain(record);
|
|
}
|
|
|
|
async findByCityCode(cityCode: string): Promise<VirtualAccount | null> {
|
|
const record = await this.prisma.virtualAccount.findFirst({
|
|
where: {
|
|
accountType: VirtualAccountType.SYSTEM_CITY,
|
|
cityCode,
|
|
},
|
|
});
|
|
|
|
if (!record) return null;
|
|
return this.toDomain(record);
|
|
}
|
|
|
|
async findHeadquarters(): Promise<VirtualAccount | null> {
|
|
const record = await this.prisma.virtualAccount.findFirst({
|
|
where: { accountType: VirtualAccountType.HEADQUARTERS },
|
|
});
|
|
|
|
if (!record) return null;
|
|
return this.toDomain(record);
|
|
}
|
|
|
|
async countByType(type: VirtualAccountType): Promise<number> {
|
|
return this.prisma.virtualAccount.count({
|
|
where: { accountType: type },
|
|
});
|
|
}
|
|
|
|
async deleteById(id: bigint): Promise<void> {
|
|
await this.prisma.virtualAccount.delete({
|
|
where: { id },
|
|
});
|
|
}
|
|
|
|
private toDomain(record: any): VirtualAccount {
|
|
return VirtualAccount.reconstitute({
|
|
id: record.id,
|
|
accountType: record.accountType as VirtualAccountType,
|
|
displayName: record.displayName,
|
|
avatar: record.avatar,
|
|
provinceCode: record.provinceCode,
|
|
cityCode: record.cityCode,
|
|
minScore: record.minScore,
|
|
maxScore: record.maxScore,
|
|
currentScore: record.currentScore,
|
|
usdtBalance: Number(record.usdtBalance),
|
|
hashpowerBalance: Number(record.hashpowerBalance),
|
|
isActive: record.isActive,
|
|
createdAt: record.createdAt,
|
|
});
|
|
}
|
|
}
|