fix: 修复前端代码质量问题

- 创建 Toast 通知组件,替换所有 alert() 调用
- 修复 useReview hook 内存泄漏(setInterval 清理)
- 移除所有 console.error 和 console.log 语句
- 为复制操作失败添加用户友好的 toast 提示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-02-09 12:48:22 +08:00
co-authored by Claude Opus 4.5
parent a5a005db0c
commit 37ac749071
33 changed files with 519 additions and 91 deletions
+29 -7
View File
@@ -1,6 +1,6 @@
'use client'
import { useState, useCallback, useEffect } from 'react'
import { useState, useCallback, useEffect, useRef } from 'react'
import { api } from '@/lib/api'
import type {
VideoReviewRequest,
@@ -24,6 +24,7 @@ export function useReview(options: UseReviewOptions = {}) {
const [isPolling, setIsPolling] = useState(false)
const [task, setTask] = useState<ReviewTask | null>(null)
const [error, setError] = useState<Error | null>(null)
const intervalRef = useRef<NodeJS.Timeout | null>(null)
/**
* 提交审核
@@ -97,10 +98,22 @@ export function useReview(options: UseReviewOptions = {}) {
}
}, [task?.createdAt])
/**
* 清除轮询定时器
*/
const clearPollingInterval = useCallback(() => {
if (intervalRef.current) {
clearInterval(intervalRef.current)
intervalRef.current = null
}
}, [])
/**
* 开始轮询进度
*/
const startPolling = useCallback((reviewId: string) => {
// 清除之前的轮询(如果有)
clearPollingInterval()
setIsPolling(true)
const poll = async () => {
@@ -108,36 +121,45 @@ export function useReview(options: UseReviewOptions = {}) {
const progress = await fetchProgress(reviewId)
if (progress.status === 'completed') {
clearPollingInterval()
setIsPolling(false)
const result = await fetchResult(reviewId)
onComplete?.(result)
} else if (progress.status === 'failed') {
clearPollingInterval()
setIsPolling(false)
const error = new Error('审核失败')
setError(error)
onError?.(error)
}
} catch (err) {
} catch {
// 继续轮询,忽略单次错误
console.error('Polling error:', err)
}
}
const intervalId = setInterval(poll, pollingInterval)
intervalRef.current = setInterval(poll, pollingInterval)
poll() // 立即执行一次
return () => {
clearInterval(intervalId)
clearPollingInterval()
setIsPolling(false)
}
}, [fetchProgress, fetchResult, pollingInterval, onComplete, onError])
}, [fetchProgress, fetchResult, pollingInterval, onComplete, onError, clearPollingInterval])
/**
* 停止轮询
*/
const stopPolling = useCallback(() => {
clearPollingInterval()
setIsPolling(false)
}, [])
}, [clearPollingInterval])
// 组件卸载时清除定时器,防止内存泄漏
useEffect(() => {
return () => {
clearPollingInterval()
}
}, [clearPollingInterval])
/**
* 重置状态