- 反编译 app/api/materials/route.ts (素材列表和删除API) - 反编译 app/api/materials/stats/route.ts (统计API) - 新增 lib/material-log.ts (素材操作日志工具) - 新增 lib/utils.ts (URL规范化工具) 这是从生产系统2.2.0版本编译代码反编译恢复的第一批文件
112 lines
2.6 KiB
TypeScript
112 lines
2.6 KiB
TypeScript
import { prisma } from '@/lib/prisma';
|
||
|
||
/**
|
||
* 素材操作日志表是否已初始化
|
||
*/
|
||
let isInitialized = false;
|
||
|
||
/**
|
||
* 执行原始 SQL(用于创建表和索引)
|
||
*/
|
||
async function executeRawSQL(sql: string) {
|
||
try {
|
||
await prisma.$executeRawUnsafe(sql);
|
||
} catch (error) {
|
||
console.error('[MaterialLog] Failed to execute SQL:', error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 初始化素材日志表
|
||
* 如果表不存在,则创建表和索引
|
||
*/
|
||
async function initializeMaterialLogTable() {
|
||
if (isInitialized) return;
|
||
|
||
// 创建表
|
||
await executeRawSQL(`
|
||
CREATE TABLE IF NOT EXISTS "material_logs" (
|
||
"id" TEXT PRIMARY KEY,
|
||
"materialId" TEXT NOT NULL,
|
||
"userId" TEXT NOT NULL,
|
||
"action" TEXT NOT NULL,
|
||
"changes" JSONB,
|
||
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
)
|
||
`);
|
||
|
||
// 创建索引
|
||
await executeRawSQL(
|
||
'CREATE INDEX IF NOT EXISTS "material_logs_materialId_idx" ON "material_logs" ("materialId")'
|
||
);
|
||
await executeRawSQL(
|
||
'CREATE INDEX IF NOT EXISTS "material_logs_userId_idx" ON "material_logs" ("userId")'
|
||
);
|
||
await executeRawSQL(
|
||
'CREATE INDEX IF NOT EXISTS "material_logs_timestamp_idx" ON "material_logs" ("timestamp")'
|
||
);
|
||
|
||
// 添加外键约束
|
||
await executeRawSQL(`
|
||
DO $
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM pg_constraint WHERE conname = 'material_logs_materialId_fkey'
|
||
) THEN
|
||
ALTER TABLE "material_logs"
|
||
ADD CONSTRAINT "material_logs_materialId_fkey"
|
||
FOREIGN KEY ("materialId") REFERENCES "materials"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||
END IF;
|
||
END
|
||
$;
|
||
`);
|
||
|
||
await executeRawSQL(`
|
||
DO $
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM pg_constraint WHERE conname = 'material_logs_userId_fkey'
|
||
) THEN
|
||
ALTER TABLE "material_logs"
|
||
ADD CONSTRAINT "material_logs_userId_fkey"
|
||
FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||
END IF;
|
||
END
|
||
$;
|
||
`);
|
||
|
||
isInitialized = true;
|
||
}
|
||
|
||
/**
|
||
* 创建素材操作日志
|
||
*/
|
||
export async function createMaterialLog({
|
||
materialId,
|
||
userId,
|
||
action,
|
||
changes = null,
|
||
}: {
|
||
materialId: string;
|
||
userId: string;
|
||
action: string;
|
||
changes?: any;
|
||
}) {
|
||
try {
|
||
// 确保表已初始化
|
||
await initializeMaterialLogTable();
|
||
|
||
// 创建日志记录
|
||
await prisma.materialLog.create({
|
||
data: {
|
||
materialId,
|
||
userId,
|
||
action,
|
||
changes: changes ? JSON.stringify(changes) : null,
|
||
},
|
||
});
|
||
} catch (error) {
|
||
console.error('[MaterialLog] Failed to create log:', error);
|
||
}
|
||
}
|