clone:legacy
This commit is contained in:
35
src/transferhistories/dto/transferhistories.query.dto.ts
Normal file
35
src/transferhistories/dto/transferhistories.query.dto.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEmpty,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
} from 'class-validator';
|
||||
|
||||
export default class TransferQueryDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiProperty({
|
||||
nullable: true,
|
||||
required: false,
|
||||
})
|
||||
readonly address?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiProperty({
|
||||
nullable: true,
|
||||
required: false,
|
||||
})
|
||||
readonly reason?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@ApiProperty({
|
||||
nullable: true,
|
||||
required: false,
|
||||
})
|
||||
readonly page?: number;
|
||||
}
|
||||
22
src/transferhistories/tranferhistories.controller.spec.ts
Normal file
22
src/transferhistories/tranferhistories.controller.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TranferHistoriesController } from './transferhhistories.controller';
|
||||
import { TranferHistoriesService } from './transferhistories.service';
|
||||
|
||||
describe('TranferHistoriesController', () => {
|
||||
let controller: TranferHistoriesController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [TranferHistoriesController],
|
||||
providers: [TranferHistoriesService],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<TranferHistoriesController>(
|
||||
TranferHistoriesController,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
18
src/transferhistories/tranferhistories.service.spec.ts
Normal file
18
src/transferhistories/tranferhistories.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TranferHistoriesService } from './transferhistories.service';
|
||||
|
||||
describe('TranferHistoriesService', () => {
|
||||
let service: TranferHistoriesService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [TranferHistoriesService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<TranferHistoriesService>(TranferHistoriesService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
51
src/transferhistories/transferhhistories.controller.ts
Normal file
51
src/transferhistories/transferhhistories.controller.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Patch,
|
||||
Param,
|
||||
Delete,
|
||||
ParseIntPipe,
|
||||
Query,
|
||||
} from '@nestjs/common';
|
||||
import { TranferHistoriesService } from './transferhistories.service';
|
||||
import TransferQueryDto from './dto/transferhistories.query.dto';
|
||||
import { ApiOperation } from '@nestjs/swagger';
|
||||
|
||||
@Controller('transferlogs')
|
||||
export class TranferHistoriesController {
|
||||
constructor(
|
||||
private readonly tranferHistoriesService: TranferHistoriesService,
|
||||
) {}
|
||||
|
||||
@Get('/listAll')
|
||||
@ApiOperation({
|
||||
summary: '로그 전체 ',
|
||||
description: '트랜젝션 로그 전체 리스트',
|
||||
})
|
||||
getListAll() {
|
||||
return this.tranferHistoriesService.findAll();
|
||||
}
|
||||
|
||||
@Get('/list')
|
||||
getListPaging(@Query('page', ParseIntPipe) page: number) {
|
||||
const currentPage = Number.isFinite(page) && page > 0 ? page : 1;
|
||||
return this.tranferHistoriesService.findPageList(currentPage);
|
||||
}
|
||||
|
||||
@Get('/list/filter')
|
||||
getListFilterPaging(
|
||||
@Query('page') page: string,
|
||||
@Query('address') address: string,
|
||||
@Query('reason') reason: string,
|
||||
@Query('timestamp') timestamp: string,
|
||||
) {
|
||||
return this.tranferHistoriesService.findListPaging(
|
||||
page,
|
||||
address,
|
||||
reason,
|
||||
timestamp,
|
||||
);
|
||||
}
|
||||
}
|
||||
11
src/transferhistories/transferhistories.module.ts
Normal file
11
src/transferhistories/transferhistories.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TranferHistoriesService } from './transferhistories.service';
|
||||
import { TranferHistoriesController } from './transferhhistories.controller';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule],
|
||||
controllers: [TranferHistoriesController],
|
||||
providers: [TranferHistoriesService],
|
||||
})
|
||||
export class TranferHistoriesModule {}
|
||||
90
src/transferhistories/transferhistories.service.ts
Normal file
90
src/transferhistories/transferhistories.service.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/prisma.service';
|
||||
import TransferQueryDto from './dto/transferhistories.query.dto';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { formatUnits } from 'ethers';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import {
|
||||
TRANSFERLOGS_QUERY,
|
||||
TRANSFERLOGS_UNIONALL_QUERY,
|
||||
} from './transferhistories.sql';
|
||||
|
||||
@Injectable()
|
||||
export class TranferHistoriesService {
|
||||
private pageSize: number;
|
||||
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.pageSize = Number(this.configService.get<number>('PAGE_SIZE', 50));
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
return await this.prisma.transferHistories.findMany({
|
||||
orderBy: { idx: 'desc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findPageList(page: number) {
|
||||
return await this.prisma.transferHistories.findMany({
|
||||
orderBy: { idx: 'desc' },
|
||||
take: this.pageSize,
|
||||
skip: ((page ?? 1) - 1) * this.pageSize,
|
||||
});
|
||||
}
|
||||
|
||||
async findList(body: TransferQueryDto) {
|
||||
const where: any = {};
|
||||
|
||||
if (body.reason) {
|
||||
where.memo = body.reason;
|
||||
}
|
||||
|
||||
if (body.address) {
|
||||
where.OR = [
|
||||
{ from_address: { contains: body.address } },
|
||||
{ to_address: { contains: body.address } },
|
||||
];
|
||||
}
|
||||
|
||||
return await this.prisma.transferHistories.findMany({
|
||||
where,
|
||||
orderBy: { idx: 'desc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findListPaging(
|
||||
page: string,
|
||||
address: string,
|
||||
reason: string,
|
||||
timestamp: string,
|
||||
) {
|
||||
const parsed = page ? parseInt(page, 10) : NaN;
|
||||
const currentPage =
|
||||
!page || Number.isNaN(parsed) || parsed <= 0 ? 1 : parsed;
|
||||
|
||||
const take = this.pageSize;
|
||||
const skip = (currentPage - 1) * take;
|
||||
const ts = timestamp ? new Date(timestamp) : undefined;
|
||||
|
||||
let rows = [];
|
||||
|
||||
if (!address) {
|
||||
rows = await this.prisma.$queryRaw(
|
||||
TRANSFERLOGS_QUERY(reason, ts, take, skip),
|
||||
);
|
||||
} else {
|
||||
rows = await this.prisma.$queryRaw(
|
||||
TRANSFERLOGS_UNIONALL_QUERY(reason, address, ts, take, skip),
|
||||
);
|
||||
}
|
||||
|
||||
const mapped = rows.map((r) => ({
|
||||
...r,
|
||||
amount: parseFloat(formatUnits(r.amount.toFixed(0), 18)).toString(),
|
||||
}));
|
||||
|
||||
return mapped;
|
||||
}
|
||||
}
|
||||
89
src/transferhistories/transferhistories.sql.ts
Normal file
89
src/transferhistories/transferhistories.sql.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
export const TRANSFERLOGS_UNIONALL_QUERY = (
|
||||
reason: string,
|
||||
address: string,
|
||||
ts: Date,
|
||||
take: number,
|
||||
skip: number,
|
||||
) => {
|
||||
return Prisma.sql`
|
||||
SELECT
|
||||
idx,
|
||||
txhash,
|
||||
blockNumber,
|
||||
log_index,
|
||||
from_address,
|
||||
to_address,
|
||||
amount,
|
||||
memo,
|
||||
timestamp,
|
||||
createdAt
|
||||
FROM (
|
||||
SELECT
|
||||
idx,
|
||||
txhash,
|
||||
blockNumber,
|
||||
log_index,
|
||||
from_address,
|
||||
to_address,
|
||||
amount,
|
||||
memo,
|
||||
timestamp,
|
||||
createdAt
|
||||
FROM TransferHistories
|
||||
WHERE 1=1
|
||||
${reason ? Prisma.sql`AND memo = ${reason}` : Prisma.empty}
|
||||
${address ? Prisma.sql`AND from_address = ${address}` : Prisma.empty}
|
||||
${ts ? Prisma.sql`AND timestamp >= ${ts}` : Prisma.empty}
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
idx,
|
||||
txhash,
|
||||
blockNumber,
|
||||
log_index,
|
||||
from_address,
|
||||
to_address,
|
||||
amount,
|
||||
memo,
|
||||
timestamp,
|
||||
createdAt
|
||||
FROM TransferHistories
|
||||
WHERE 1=1
|
||||
${reason ? Prisma.sql`AND memo = ${reason}` : Prisma.empty}
|
||||
${address ? Prisma.sql`AND to_address = ${address}` : Prisma.empty}
|
||||
${ts ? Prisma.sql`AND timestamp >= ${ts}` : Prisma.empty}
|
||||
) AS t
|
||||
ORDER BY t.idx DESC
|
||||
LIMIT ${take} OFFSET ${skip}
|
||||
`;
|
||||
};
|
||||
|
||||
export const TRANSFERLOGS_QUERY = (
|
||||
reason: string,
|
||||
ts: Date,
|
||||
take: number,
|
||||
skip: number,
|
||||
) => {
|
||||
return Prisma.sql`
|
||||
SELECT
|
||||
idx,
|
||||
txhash,
|
||||
blockNumber,
|
||||
log_index,
|
||||
from_address,
|
||||
to_address,
|
||||
amount,
|
||||
memo,
|
||||
timestamp,
|
||||
createdAt
|
||||
FROM TransferHistories
|
||||
WHERE 1=1
|
||||
${reason ? Prisma.sql`AND memo = ${reason}` : Prisma.empty}
|
||||
${ts ? Prisma.sql`AND timestamp >= ${ts}` : Prisma.empty}
|
||||
ORDER BY idx DESC
|
||||
LIMIT ${take} OFFSET ${skip}
|
||||
`;
|
||||
};
|
||||
Reference in New Issue
Block a user