fix build

This commit is contained in:
songtianlun 2025-07-30 00:25:54 +08:00
parent 921143f6a2
commit 2b2e311c58
10 changed files with 89 additions and 70 deletions

View File

@ -78,7 +78,7 @@ export async function PUT(request: NextRequest, { params }: RouteParams) {
}
// 处理标签
let tagObjects = []
const tagObjects = []
if (tags && tags.length > 0) {
for (const tagName of tags) {
const tag = await prisma.promptTag.upsert({

View File

@ -7,9 +7,10 @@ interface RouteParams {
// POST /api/prompts/[id]/test - 运行 prompt 测试
export async function POST(request: NextRequest, { params }: RouteParams) {
const { id } = await params
const body = await request.json()
try {
const { id } = await params
const body = await request.json()
const {
content,
model = 'gpt-3.5-turbo',
@ -97,8 +98,8 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
async function runAITest({
content,
model,
temperature,
maxTokens
temperature: _temperature,
maxTokens: _maxTokens
}: {
content: string
model: string

View File

@ -43,18 +43,17 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
])
// 计算统计信息
const stats = await prisma.promptTestRun.aggregate({
where: { promptId: id },
_count: {
id: true
},
_sum: {
success: true
}
})
const [totalCount, successCount] = await Promise.all([
prisma.promptTestRun.count({
where: { promptId: id }
}),
prisma.promptTestRun.count({
where: { promptId: id, success: true }
})
])
const successRate = stats._count.id > 0
? ((stats._sum.success || 0) / stats._count.id * 100).toFixed(1)
const successRate = totalCount > 0
? ((successCount / totalCount) * 100).toFixed(1)
: '0'
return NextResponse.json({
@ -66,8 +65,8 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
totalPages: Math.ceil(total / limit)
},
stats: {
totalRuns: stats._count.id,
successfulRuns: stats._sum.success || 0,
totalRuns: totalCount,
successfulRuns: successCount,
successRate: `${successRate}%`
}
})

View File

@ -110,17 +110,19 @@ export async function POST(request: NextRequest) {
})
// 为所有选中的 prompts 添加标签
result = await prisma.prompt.updateMany({
where: {
id: { in: promptIds },
userId
},
data: {
tags: {
connect: { id: tag.id }
const updatePromises = promptIds.map(promptId =>
prisma.prompt.update({
where: { id: promptId },
data: {
tags: {
connect: { id: tag.id }
}
}
}
})
})
)
await Promise.all(updatePromises)
result = { count: promptIds.length }
break
case 'removeTag':
@ -137,17 +139,19 @@ export async function POST(request: NextRequest) {
})
if (tagToRemove) {
result = await prisma.prompt.updateMany({
where: {
id: { in: promptIds },
userId
},
data: {
tags: {
disconnect: { id: tagToRemove.id }
const updatePromises = promptIds.map(promptId =>
prisma.prompt.update({
where: { id: promptId },
data: {
tags: {
disconnect: { id: tagToRemove.id }
}
}
}
})
})
)
await Promise.all(updatePromises)
result = { count: promptIds.length }
}
break

View File

@ -20,7 +20,19 @@ export async function GET(request: NextRequest) {
const skip = (page - 1) * limit
// 构建查询条件
const where: any = {
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,
}
@ -41,7 +53,7 @@ export async function GET(request: NextRequest) {
}
// 构建排序条件
const orderBy: any = {}
const orderBy: Record<string, string> = {}
orderBy[sortBy] = sortOrder
// 获取总数

View File

@ -12,10 +12,9 @@ import { Textarea } from '@/components/ui/textarea'
import { LoadingSpinner } from '@/components/ui/loading-spinner'
import {
Play,
Save,
Copy,
Settings,
Folder,
Save,
Copy,
Settings,
Plus,
Search,
Filter,
@ -24,10 +23,7 @@ import {
History,
ArrowLeft,
FileText,
Clock,
Tag,
User,
Calendar
Clock
} from 'lucide-react'
interface PromptPageProps {
@ -67,14 +63,6 @@ export default function PromptPage({ params }: PromptPageProps) {
const [isSaving, setIsSaving] = useState(false)
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
if (!loading && !user) {
router.push('/signin')
} else if (user && promptId) {
fetchPrompt()
}
}, [user, loading, router, promptId])
const fetchPrompt = async () => {
if (!user || !promptId) return
@ -97,6 +85,16 @@ export default function PromptPage({ params }: PromptPageProps) {
}
}
useEffect(() => {
if (!loading && !user) {
router.push('/signin')
} else if (user && promptId) {
fetchPrompt()
}
}, [user, loading, router, promptId, fetchPrompt])
const handleRunTest = async () => {
if (!promptContent.trim() || !user || !promptId) return

View File

@ -31,14 +31,6 @@ export default function NewPromptPage() {
const [isSaving, setIsSaving] = useState(false)
const [availableTags, setAvailableTags] = useState<string[]>([])
useEffect(() => {
if (!loading && !user) {
router.push('/signin')
} else if (user) {
fetchAvailableTags()
}
}, [user, loading, router])
const fetchAvailableTags = async () => {
if (!user) return
@ -46,13 +38,23 @@ export default function NewPromptPage() {
const response = await fetch(`/api/tags?userId=${user.id}`)
if (response.ok) {
const tagsData = await response.json()
setAvailableTags(tagsData.map((tag: any) => tag.name))
setAvailableTags(tagsData.map((tag: { name: string }) => tag.name))
}
} catch (error) {
console.error('Error fetching tags:', error)
}
}
useEffect(() => {
if (!loading && !user) {
router.push('/signin')
} else if (user) {
fetchAvailableTags()
}
}, [user, loading, router, fetchAvailableTags])
const handleAddTag = () => {
if (newTag.trim() && !tags.includes(newTag.trim())) {
setTags(prev => [...prev, newTag.trim()])

View File

@ -70,7 +70,7 @@ export default function StudioPage() {
// Pagination
const [currentPage, setCurrentPage] = useState(1)
const [itemsPerPage, setItemsPerPage] = useState(12)
const itemsPerPage = 12
const [pagination, setPagination] = useState<PaginationInfo>({
page: 1,
limit: 12,
@ -85,6 +85,7 @@ export default function StudioPage() {
fetchPrompts()
fetchTags()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user, loading, router])
// Fetch prompts from API
@ -124,7 +125,7 @@ export default function StudioPage() {
const response = await fetch(`/api/tags?userId=${user.id}`)
if (response.ok) {
const tags = await response.json()
setAllTags(tags.map((tag: any) => tag.name))
setAllTags(tags.map((tag: { name: string }) => tag.name))
}
} catch (error) {
console.error('Error fetching tags:', error)
@ -136,6 +137,7 @@ export default function StudioPage() {
if (user) {
fetchPrompts()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPage, itemsPerPage, searchQuery, selectedTag, sortField, sortOrder, user])
// Since filtering and sorting is now done on the server,

View File

@ -11,8 +11,7 @@ import {
X,
Save,
Tag,
Plus,
Trash2
Plus
} from 'lucide-react'
interface Prompt {
@ -57,6 +56,7 @@ export function EditPromptModal({
setTags(prompt.tags)
fetchAvailableTags()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen, prompt])
const fetchAvailableTags = async () => {
@ -64,7 +64,7 @@ export function EditPromptModal({
const response = await fetch(`/api/tags?userId=${userId}`)
if (response.ok) {
const tagsData = await response.json()
setAvailableTags(tagsData.map((tag: any) => tag.name))
setAvailableTags(tagsData.map((tag: { name: string }) => tag.name))
}
} catch (error) {
console.error('Error fetching tags:', error)

View File

@ -45,6 +45,7 @@ export function VersionHistory({
useEffect(() => {
fetchVersions()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [promptId, userId])
const fetchVersions = async () => {