import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../../common/prisma/prisma.module'; import { serializeBigInt } from '../../common/decorators/current-user.decorator'; import { hqOperationLogWhere } from '../../common/event/event.helpers'; import { resolveHqOperationLabel } from '../../common/hq-operation/hq-operation.constants'; import type { AdminHqLogsQueryDto } from './dto/admin-query.dto'; @Injectable() export class AdminHqLogsService { constructor(private readonly prisma: PrismaService) {} async list(query: AdminHqLogsQueryDto) { const page = query.page ?? 1; const pageSize = query.pageSize ?? 20; const where = hqOperationLogWhere({ hqAccountId: query.hqAccountId ? BigInt(query.hqAccountId) : undefined, action: query.action, refType: query.refType, from: query.from ? new Date(query.from) : undefined, to: query.to ? new Date(query.to) : undefined, }); const [rows, total] = await Promise.all([ this.prisma.commonEvent.findMany({ where, orderBy: { createdAt: 'desc' }, skip: (page - 1) * pageSize, take: pageSize, }), this.prisma.commonEvent.count({ where }), ]); const hqIds = [...new Set(rows.map((r) => r.actorId).filter((id): id is bigint => id != null))]; const hqAccounts = hqIds.length ? await this.prisma.hqAccount.findMany({ where: { id: { in: hqIds } }, select: { id: true, name: true, phone: true, adminRole: true }, }) : []; const hqMap = new Map(hqAccounts.map((a) => [a.id.toString(), a])); return serializeBigInt({ items: rows.map((row) => { const hq = row.actorId ? hqMap.get(row.actorId.toString()) : undefined; const action = row.param1Desc === 'action' ? row.param1 : row.param1; return { id: row.id, hqAccountId: row.actorId, hqName: hq?.name ?? null, hqPhone: hq?.phone ?? null, hqRole: hq?.adminRole ?? null, action, actionLabel: resolveHqOperationLabel(action, row.refType), refType: row.param2Desc === 'target_type' ? row.param2 : row.refType, refId: row.param3Desc === 'target_id' ? row.param3 : row.refId.toString(), status: row.status, remark: row.remark, detail: row.extraJson, createdAt: row.createdAt, }; }), total, page, pageSize, }); } async detail(id: bigint) { const row = await this.prisma.commonEvent.findFirst({ where: { id, eventType: 'HQ_OPERATION' }, }); if (!row) throw new NotFoundException('操作日志不存在'); const hq = row.actorId ? await this.prisma.hqAccount.findUnique({ where: { id: row.actorId }, select: { id: true, name: true, phone: true, adminRole: true }, }) : null; const action = row.param1Desc === 'action' ? row.param1 : row.param1; return serializeBigInt({ id: row.id, hqAccountId: row.actorId, hqAccount: hq, action, actionLabel: resolveHqOperationLabel(action, row.refType), refType: row.param2Desc === 'target_type' ? row.param2 : row.refType, refId: row.param3Desc === 'target_id' ? row.param3 : row.refId.toString(), status: row.status, remark: row.remark, detail: row.extraJson, createdAt: row.createdAt, }); } }