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) { if (tags && tags.length > 0) {
for (const tagName of tags) { for (const tagName of tags) {
const tag = await prisma.promptTag.upsert({ const tag = await prisma.promptTag.upsert({

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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