192 lines
4.7 KiB
TypeScript
192 lines
4.7 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
||
import { prisma } from '@/lib/prisma'
|
||
import { SubscriptionService } from '@/lib/subscription-service'
|
||
|
||
// GET /api/prompts - 获取用户的 prompts 列表
|
||
export async function GET(request: NextRequest) {
|
||
try {
|
||
const { searchParams } = new URL(request.url)
|
||
const page = parseInt(searchParams.get('page') || '1')
|
||
const limit = parseInt(searchParams.get('limit') || '12')
|
||
const search = searchParams.get('search') || ''
|
||
const tag = searchParams.get('tag') || ''
|
||
const sortBy = searchParams.get('sortBy') || 'updatedAt'
|
||
const sortOrder = searchParams.get('sortOrder') || 'desc'
|
||
const userId = searchParams.get('userId')
|
||
|
||
if (!userId) {
|
||
return NextResponse.json({ error: 'User ID is required' }, { status: 401 })
|
||
}
|
||
|
||
const skip = (page - 1) * limit
|
||
|
||
// 构建查询条件
|
||
const where: {
|
||
userId: string
|
||
OR?: Array<{
|
||
name?: { contains: string; mode: 'insensitive' }
|
||
description?: { contains: string; mode: 'insensitive' }
|
||
content?: { contains: string; mode: 'insensitive' }
|
||
}>
|
||
tags?: {
|
||
some: {
|
||
name: string
|
||
}
|
||
}
|
||
} = {
|
||
userId: userId,
|
||
}
|
||
|
||
if (search) {
|
||
where.OR = [
|
||
{ name: { contains: search, mode: 'insensitive' } },
|
||
{ description: { contains: search, mode: 'insensitive' } },
|
||
{ content: { contains: search, mode: 'insensitive' } },
|
||
]
|
||
}
|
||
|
||
if (tag) {
|
||
where.tags = {
|
||
some: {
|
||
name: tag
|
||
}
|
||
}
|
||
}
|
||
|
||
// 构建排序条件
|
||
const orderBy: Record<string, string> = {}
|
||
orderBy[sortBy] = sortOrder
|
||
|
||
// 获取总数
|
||
const total = await prisma.prompt.count({ where })
|
||
|
||
// 获取 prompts
|
||
const prompts = await prisma.prompt.findMany({
|
||
where,
|
||
include: {
|
||
tags: true,
|
||
versions: {
|
||
orderBy: { version: 'desc' },
|
||
take: 1
|
||
},
|
||
tests: {
|
||
orderBy: { createdAt: 'desc' },
|
||
take: 1
|
||
}
|
||
},
|
||
orderBy,
|
||
skip,
|
||
take: limit,
|
||
})
|
||
|
||
// 计算最后使用时间
|
||
const promptsWithLastUsed = prompts.map(prompt => ({
|
||
...prompt,
|
||
lastUsed: prompt.tests[0]?.createdAt || null,
|
||
currentVersion: prompt.versions[0]?.version || 1,
|
||
tags: prompt.tags.map(tag => tag.name)
|
||
}))
|
||
|
||
return NextResponse.json({
|
||
prompts: promptsWithLastUsed,
|
||
pagination: {
|
||
page,
|
||
limit,
|
||
total,
|
||
totalPages: Math.ceil(total / limit)
|
||
}
|
||
})
|
||
|
||
} catch (error) {
|
||
console.error('Error fetching prompts:', error)
|
||
return NextResponse.json(
|
||
{ error: 'Failed to fetch prompts' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|
||
|
||
// POST /api/prompts - 创建新的 prompt
|
||
export async function POST(request: NextRequest) {
|
||
try {
|
||
const body = await request.json()
|
||
const { name, description, content, tags, userId, permissions } = body
|
||
|
||
if (!userId) {
|
||
return NextResponse.json({ error: 'User ID is required' }, { status: 401 })
|
||
}
|
||
|
||
if (!name || !content) {
|
||
return NextResponse.json(
|
||
{ error: 'Name and content are required' },
|
||
{ status: 400 }
|
||
)
|
||
}
|
||
|
||
// 检查用户是否可以创建新的提示词
|
||
const canCreate = await SubscriptionService.canCreatePrompt(userId)
|
||
if (!canCreate) {
|
||
return NextResponse.json(
|
||
{ error: 'Prompt limit reached. Please upgrade your plan to create more prompts.' },
|
||
{ status: 403 }
|
||
)
|
||
}
|
||
|
||
// 创建或获取标签
|
||
const tagObjects = []
|
||
if (tags && tags.length > 0) {
|
||
for (const tagName of tags) {
|
||
const tag = await prisma.promptTag.upsert({
|
||
where: { name: tagName },
|
||
update: {},
|
||
create: { name: tagName }
|
||
})
|
||
tagObjects.push(tag)
|
||
}
|
||
}
|
||
|
||
// 创建 prompt
|
||
const prompt = await prisma.prompt.create({
|
||
data: {
|
||
name,
|
||
description,
|
||
content,
|
||
userId,
|
||
permissions: permissions || 'private',
|
||
tags: {
|
||
connect: tagObjects.map(tag => ({ id: tag.id }))
|
||
}
|
||
},
|
||
include: {
|
||
tags: true,
|
||
versions: true
|
||
}
|
||
})
|
||
|
||
// 创建初始版本
|
||
await prisma.promptVersion.create({
|
||
data: {
|
||
promptId: prompt.id,
|
||
version: 1,
|
||
content,
|
||
changelog: 'Initial version'
|
||
}
|
||
})
|
||
|
||
// 处理返回数据格式,确保tags是字符串数组
|
||
const promptWithMetadata = {
|
||
...prompt,
|
||
tags: prompt.tags.map(tag => tag.name)
|
||
}
|
||
|
||
return NextResponse.json(promptWithMetadata, { status: 201 })
|
||
|
||
} catch (error) {
|
||
console.error('Error creating prompt:', error)
|
||
return NextResponse.json(
|
||
{ error: 'Failed to create prompt' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|