import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import moment from 'moment'; import { type FindOptionsWhere, Repository } from 'typeorm'; import { type PageDto } from '../../common/dto/page.dto'; import { type OperateType } from '../../constants'; import { type GetAuditLogDto } from '../report/dtos/get-report-audit-log.dto'; import { type UserEntity } from '../user/user.entity'; import { AuditLogEntity } from './audit-log.entity'; import { type AuditLogDto } from './dtos/audit-log.dto'; import { type AuditLogPageOptionsDto } from './dtos/get-audit-log-page.dto'; import { ReportAuditLogDto } from './dtos/report-audit-log.dto'; @Injectable() export class AuditLogService { constructor( @InjectRepository(AuditLogEntity) private auditLogRepository: Repository<AuditLogEntity>, ) {} async findOne( findData: FindOptionsWhere<AuditLogEntity>, ): Promise<AuditLogEntity | null> { const queryBuilder = this.auditLogRepository.createQueryBuilder('auditLog'); queryBuilder.where(findData); return queryBuilder.getOne(); } async findMany( pageOptionsDto: AuditLogPageOptionsDto, ): Promise<PageDto<AuditLogDto>> { const { order, tableName, operateType, username } = pageOptionsDto; const queryBuilder = this.auditLogRepository.createQueryBuilder('auditLog'); queryBuilder.leftJoinAndSelect('auditLog.user', 'user'); if (tableName !== undefined) { queryBuilder.andWhere('auditLog.tableName ILIKE :tableName', { tableName: `%${tableName}%`, }); } if (operateType !== undefined) { queryBuilder.andWhere('auditLog.operateType = :operateType', { operateType, }); } if (username !== undefined) { queryBuilder.andWhere('user.name ILIKE :username', { username: `%${username}%`, }); } queryBuilder.orderBy('auditLog.createdAt', order); const [items, pageMetaDto] = await queryBuilder.paginate(pageOptionsDto); return items.toPageDto(pageMetaDto); } async create(options: { operateType: OperateType; tableName: string; itemId: Uuid; summaryChanges: string; oldValue: string | null; newValue: string | null; user: UserEntity; }): Promise<AuditLogEntity | void> { const { oldValue, newValue } = options; if (oldValue === newValue) { return; } const auditLogEntity = this.auditLogRepository.create(options); await this.auditLogRepository.save(auditLogEntity); return auditLogEntity; } async findReportMany(dto: GetAuditLogDto) { const { operateType, tableName, userName, monthFrom, monthTo, order, year, } = dto; const currentYear = year ?? moment.utc().year(); const queryBuilder = this.auditLogRepository.createQueryBuilder('auditLog'); queryBuilder.leftJoin('auditLog.user', 'user').addSelect(['user.name']); if (userName) { queryBuilder.andWhere('user.name = :userName', { userName }); } if (tableName) { queryBuilder.andWhere('auditLog.tableName = :tableName', { tableName, }); } if (operateType) { queryBuilder.andWhere('auditLog.operateType = :operateType', { operateType, }); } let fromDate: Date | undefined; let toDate: Date | undefined; if (monthFrom) { fromDate = moment .utc({ year: currentYear, month: monthFrom - 1, date: 1, }) .toDate(); queryBuilder.andWhere('auditLog.createdAt >= :fromDate', { fromDate }); } if (monthTo) { toDate = moment .utc({ year: currentYear, month: monthTo - 1, date: 1 }) .add(1, 'months') .toDate(); queryBuilder.andWhere('auditLog.createdAt < :toDate', { toDate }); } queryBuilder.orderBy('auditLog.createdAt', order); const response = await queryBuilder.getMany(); return response.map((el) => new ReportAuditLogDto(el)); } }