Prmbr/src/app/api/prompts/[id]/versions/compare/route.ts

119 lines
3.1 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
interface RouteParams {
params: Promise<{ id: string }>
}
// GET /api/prompts/[id]/versions/compare - 比较两个版本
export async function GET(request: NextRequest, { params }: RouteParams) {
try {
const { id } = await params
const { searchParams } = new URL(request.url)
const userId = searchParams.get('userId')
const fromVersionId = searchParams.get('from')
const toVersionId = searchParams.get('to')
if (!userId) {
return NextResponse.json({ error: 'User ID is required' }, { status: 401 })
}
if (!fromVersionId || !toVersionId) {
return NextResponse.json(
{ error: 'Both from and to version IDs are required' },
{ status: 400 }
)
}
// 验证 prompt 是否存在且属于用户
const prompt = await prisma.prompt.findFirst({
where: { id, userId }
})
if (!prompt) {
return NextResponse.json({ error: 'Prompt not found' }, { status: 404 })
}
// 获取两个版本
const [fromVersion, toVersion] = await Promise.all([
prisma.promptVersion.findFirst({
where: { id: fromVersionId, promptId: id }
}),
prisma.promptVersion.findFirst({
where: { id: toVersionId, promptId: id }
})
])
if (!fromVersion || !toVersion) {
return NextResponse.json(
{ error: 'One or both versions not found' },
{ status: 404 }
)
}
// 简单的文本差异计算
const diff = calculateTextDiff(fromVersion.content, toVersion.content)
return NextResponse.json({
fromVersion,
toVersion,
diff
})
} catch (error) {
console.error('Error comparing prompt versions:', error)
return NextResponse.json(
{ error: 'Failed to compare prompt versions' },
{ status: 500 }
)
}
}
// 简单的文本差异计算函数
function calculateTextDiff(oldText: string, newText: string) {
const oldLines = oldText.split('\n')
const newLines = newText.split('\n')
const changes = []
const maxLines = Math.max(oldLines.length, newLines.length)
for (let i = 0; i < maxLines; i++) {
const oldLine = oldLines[i] || ''
const newLine = newLines[i] || ''
if (oldLine !== newLine) {
if (oldLine && newLine) {
changes.push({
type: 'modified',
lineNumber: i + 1,
oldContent: oldLine,
newContent: newLine
})
} else if (oldLine && !newLine) {
changes.push({
type: 'deleted',
lineNumber: i + 1,
oldContent: oldLine,
newContent: null
})
} else if (!oldLine && newLine) {
changes.push({
type: 'added',
lineNumber: i + 1,
oldContent: null,
newContent: newLine
})
}
}
}
return {
changes,
stats: {
additions: changes.filter(c => c.type === 'added').length,
deletions: changes.filter(c => c.type === 'deleted').length,
modifications: changes.filter(c => c.type === 'modified').length
}
}
}