gongxiangp2/lib/material-download-log.ts
2026-03-06 14:14:50 +08:00

60 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { prisma } from '@/lib/prisma'
let downloadLogsTableEnsured = false
async function executeSafely(sql: string) {
try {
await prisma.$executeRawUnsafe(sql)
} catch (error: any) {
const message = error?.message || ''
// 表已存在、扩展已存在等错误可以忽略
if (
message.includes('already exists') ||
message.includes('duplicate key value') ||
message.includes('extension') // pgcrypto 等扩展相关
) {
return
}
console.error('[DownloadLog] Failed to execute SQL safely:', error)
}
}
export async function ensureMaterialDownloadLogsTable() {
if (downloadLogsTableEnsured) return
console.log('[DownloadLog] Ensuring material_download_logs table and indexes...')
// 确保 pgcrypto 扩展存在(用于 gen_random_uuid)
await executeSafely(`CREATE EXTENSION IF NOT EXISTS "pgcrypto"`)
// 创建日志表
await executeSafely(`
CREATE TABLE IF NOT EXISTS "material_download_logs" (
"id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"materialId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"downloadedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
)
`)
// 索引
await executeSafely(
`CREATE INDEX IF NOT EXISTS "material_download_logs_materialId_idx" ON "material_download_logs" ("materialId")`
)
await executeSafely(
`CREATE INDEX IF NOT EXISTS "material_download_logs_userId_idx" ON "material_download_logs" ("userId")`
)
await executeSafely(
`CREATE INDEX IF NOT EXISTS "material_download_logs_downloadedAt_idx" ON "material_download_logs" ("downloadedAt" DESC)`
)
// 审计日志保留策略:删除素材时保留下载日志,不允许 materialId 外键级联删除
await executeSafely('ALTER TABLE "material_download_logs" DROP CONSTRAINT IF EXISTS "material_download_logs_materialId_fkey"')
await executeSafely('ALTER TABLE "material_download_logs" DROP CONSTRAINT IF EXISTS "MaterialDownloadLog_materialId_fkey"')
downloadLogsTableEnsured = true
console.log('[DownloadLog] material_download_logs table ensured.')
}