import { NextRequest } from 'next/server' import { prisma } from '@/lib/prisma' import { rewriteStorageUrlForClient } from '@/lib/url-rewrite' import { API_ERROR, errorResponse, getApiKeyFromRequest, getClientIp, logApiCall, successResponse, validateApiKey, } from '@/lib/external-api' interface BarcodeImageItem { materialId: string assetId: string taskNo: string | null productModel: string categoryName: string shopName: string sceneName: string skuCode: string | null barcodes: string[] previewUrl: string fileName: string sortOrder: number uploadedAt: string updatedAt: string uploaderName: string isLatest: boolean } export async function GET(request: NextRequest) { const startTime = Date.now() const apiKey = getApiKeyFromRequest(request) const rawBarcode = request.nextUrl.searchParams.get('barcode') const barcode = String(rawBarcode || '').trim() const keyRecord = await validateApiKey(apiKey) if (!keyRecord) { return errorResponse(API_ERROR.INVALID_API_KEY) } if (!barcode) { await logApiCall({ apiKeyId: keyRecord.id, endpoint: '/api/external/product-barcode-images', method: 'GET', queryType: 'barcode', queryValue: rawBarcode || undefined, statusCode: 400, duration: Date.now() - startTime, ipAddress: getClientIp(request), userAgent: request.headers.get('user-agent') || undefined, }) return errorResponse(API_ERROR.INVALID_BARCODE) } try { const matches = await prisma.materialAssetBarcode.findMany({ where: { barcode, asset: { assetType: 'sku-preview', material: { materialType: '任务-详情', taskDetailPrivate: false, deletedAt: null, }, }, }, select: { assetId: true, barcode: true, asset: { select: { id: true, fileUrl: true, fileName: true, sortOrder: true, skuCode: true, createdAt: true, updatedAt: true, barcodes: { select: { barcode: true, }, }, material: { select: { id: true, taskNo: true, productModel: true, categoryName: true, sceneName: true, authorName: true, user: { select: { realName: true, username: true, }, }, }, }, }, }, }, }) const items = matches .map((match): BarcodeImageItem | null => { const asset = match.asset const material = asset?.material if (!asset || !material) { return null } return { materialId: String(material.id), assetId: String(asset.id), taskNo: material.taskNo || null, productModel: String(material.productModel || ''), categoryName: String(material.categoryName || ''), shopName: String(material.categoryName || ''), sceneName: String(material.sceneName || ''), skuCode: asset.skuCode || null, barcodes: Array.from( new Set((asset.barcodes || []).map((item: any) => String(item.barcode || '').trim()).filter(Boolean)), ), previewUrl: rewriteStorageUrlForClient(asset.fileUrl, request) || String(asset.fileUrl || ''), fileName: String(asset.fileName || ''), sortOrder: Number(asset.sortOrder || 0), uploadedAt: asset.createdAt.toISOString(), updatedAt: asset.updatedAt.toISOString(), uploaderName: material.user?.realName || material.user?.username || material.authorName || '', isLatest: false, } }) .filter((item): item is BarcodeImageItem => Boolean(item)) .sort((left, right) => { const uploadedAtDiff = new Date(right.uploadedAt).getTime() - new Date(left.uploadedAt).getTime() if (uploadedAtDiff !== 0) { return uploadedAtDiff } return left.sortOrder - right.sortOrder }) if (items.length === 0) { await logApiCall({ apiKeyId: keyRecord.id, endpoint: '/api/external/product-barcode-images', method: 'GET', queryType: 'barcode', queryValue: barcode, statusCode: 404, duration: Date.now() - startTime, ipAddress: getClientIp(request), userAgent: request.headers.get('user-agent') || undefined, }) return errorResponse(API_ERROR.BARCODE_NOT_FOUND) } const latestAssetId = items[0].assetId const responseData = { barcode, total: items.length, items: items.map((item) => ({ ...item, isLatest: item.assetId === latestAssetId, })), } await logApiCall({ apiKeyId: keyRecord.id, endpoint: '/api/external/product-barcode-images', method: 'GET', taskNo: responseData.items[0]?.taskNo || undefined, queryType: 'barcode', queryValue: barcode, statusCode: 200, duration: Date.now() - startTime, ipAddress: getClientIp(request), userAgent: request.headers.get('user-agent') || undefined, }) return successResponse(responseData) } catch (error) { console.error('[external/product-barcode-images] GET error:', error) await logApiCall({ apiKeyId: keyRecord.id, endpoint: '/api/external/product-barcode-images', method: 'GET', queryType: 'barcode', queryValue: barcode, statusCode: 500, duration: Date.now() - startTime, ipAddress: getClientIp(request), userAgent: request.headers.get('user-agent') || undefined, }) return errorResponse(API_ERROR.SERVER_ERROR) } }