import { Injectable, NotFoundException } from '@nestjs/common'; import { Prisma } from '@prisma/client'; import { PrismaService } from '../../common/prisma/prisma.module'; import { serializeBigInt } from '../../common/decorators/current-user.decorator'; import type { AdminOssLogsQueryDto } from './dto/admin-query.dto'; function mapOssLogRow(row: { id: bigint; scene: string; refType: string | null; refId: bigint | null; requestBody: unknown; responseBody: unknown; externalNo: string | null; status: string; errorMessage: string | null; createdAt: Date; }) { const req = (row.requestBody ?? {}) as Record; const res = (row.responseBody ?? {}) as Record; return { id: row.id, scene: row.scene, status: row.status, actorType: row.refType, actorId: row.refId, clientApp: (req.clientApp as string | undefined) ?? null, bizType: (req.bizType as string | undefined) ?? null, mediaType: (req.mediaType as string | undefined) ?? null, fileName: (req.fileName as string | undefined) ?? null, fileSize: (req.fileSize as number | undefined) ?? null, mimeType: (req.mimeType as string | undefined) ?? null, ossKey: (res.ossKey as string | undefined) ?? row.externalNo ?? null, url: (res.url as string | undefined) ?? null, bucket: (res.bucket as string | undefined) ?? null, mock: (res.mock as boolean | undefined) ?? null, errorMessage: row.errorMessage, createdAt: row.createdAt, requestBody: row.requestBody, responseBody: row.responseBody, }; } @Injectable() export class AdminOssLogsService { constructor(private readonly prisma: PrismaService) {} async list(query: AdminOssLogsQueryDto) { const page = query.page ?? 1; const pageSize = query.pageSize ?? 20; const where: Prisma.LogThirdPartyWhereInput = { provider: 'ALIYUN_OSS', }; if (query.scene) where.scene = query.scene; if (query.status) where.status = query.status as Prisma.EnumThirdPartyLogStatusFilter['equals']; if (query.refType) where.refType = query.refType; if (query.refId) where.refId = BigInt(query.refId); const andFilters: Prisma.LogThirdPartyWhereInput[] = []; if (query.bizType) { andFilters.push({ requestBody: { string_contains: `"bizType":"${query.bizType}"` }, }); } if (query.clientApp) { andFilters.push({ requestBody: { string_contains: `"clientApp":"${query.clientApp}"` }, }); } if (andFilters.length) { where.AND = andFilters; } const [rows, total] = await Promise.all([ this.prisma.logThirdParty.findMany({ where, orderBy: { createdAt: 'desc' }, skip: (page - 1) * pageSize, take: pageSize, }), this.prisma.logThirdParty.count({ where }), ]); return serializeBigInt({ items: rows.map(mapOssLogRow), total, page, pageSize, }); } async detail(id: bigint) { const row = await this.prisma.logThirdParty.findFirst({ where: { id, provider: 'ALIYUN_OSS' }, }); if (!row) throw new NotFoundException('OSS 上传日志不存在'); return serializeBigInt(mapOssLogRow(row)); } }