fix:模型加载慢,错误热重载

This commit is contained in:
SengokuCola
2026-05-05 02:05:02 +08:00
parent e2ff2c8524
commit a4afa58fe9
3 changed files with 55 additions and 5 deletions

View File

@@ -138,7 +138,7 @@ function ModelConfigPageContent() {
const { triggerRestart, isRestarting } = useRestart()
// 自动保存 (使用 hook 封装的逻辑)
const { clearTimers: clearAutoSaveTimers, initialLoadRef } = useModelAutoSave({
const { clearTimers: clearAutoSaveTimers, initialLoadRef, resetSnapshots } = useModelAutoSave({
models,
taskConfig,
onSavingChange: setAutoSaving,
@@ -200,6 +200,7 @@ function ModelConfigPageContent() {
const taskConf = (config.model_task_config as ModelTaskConfig) || null
setTaskConfig(taskConf)
resetSnapshots(modelList, taskConf)
// 解析 model_task_config 的 schema
if (schemaResult.success && schemaResult.data) {
@@ -220,7 +221,7 @@ function ModelConfigPageContent() {
} finally {
setLoading(false)
}
}, [initialLoadRef, checkTaskConfigIssues])
}, [initialLoadRef, checkTaskConfigIssues, resetSnapshots])
// 初始加载
useEffect(() => {
@@ -343,6 +344,7 @@ function ModelConfigPageContent() {
setSaving(false)
return
}
resetSnapshots(config.models as ModelInfo[], taskConfig)
setHasUnsavedChanges(false)
toast({
title: '保存成功',
@@ -392,6 +394,7 @@ function ModelConfigPageContent() {
setSaving(false)
return
}
resetSnapshots(config.models as ModelInfo[], taskConfig)
setHasUnsavedChanges(false)
toast({
title: '保存成功',

View File

@@ -25,6 +25,7 @@ interface UseModelAutoSaveReturn {
clearTimers: () => void
/** 初始加载状态标记引用 (用于设置初始加载完成) */
initialLoadRef: RefObject<boolean>
resetSnapshots: (nextModels: ModelInfo[], nextTaskConfig: ModelTaskConfig | null) => void
}
/**
@@ -45,6 +46,8 @@ export function useModelAutoSave(
const modelsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const taskConfigTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const initialLoadRef = useRef(true)
const modelsSnapshotRef = useRef<string | null>(null)
const taskConfigSnapshotRef = useRef<string | null>(null)
// 清除定时器
const clearTimers = useCallback(() => {
@@ -83,6 +86,19 @@ export function useModelAutoSave(
}, [])
// 自动保存模型列表
const snapshotModels = useCallback((nextModels: ModelInfo[]): string => {
return JSON.stringify(nextModels.map(cleanModelForSave))
}, [cleanModelForSave])
const snapshotTaskConfig = useCallback((nextTaskConfig: ModelTaskConfig | null): string | null => {
return nextTaskConfig ? JSON.stringify(nextTaskConfig) : null
}, [])
const resetSnapshots = useCallback((nextModels: ModelInfo[], nextTaskConfig: ModelTaskConfig | null) => {
modelsSnapshotRef.current = snapshotModels(nextModels)
taskConfigSnapshotRef.current = snapshotTaskConfig(nextTaskConfig)
}, [snapshotModels, snapshotTaskConfig])
const autoSaveModels = useCallback(async (newModels: ModelInfo[]) => {
try {
onSavingChange?.(true)
@@ -92,6 +108,7 @@ export function useModelAutoSave(
if (!result.success) {
throw new Error(result.error)
}
modelsSnapshotRef.current = JSON.stringify(cleanedModels)
onUnsavedChange?.(false)
} catch (error) {
console.error('自动保存模型列表失败:', error)
@@ -109,6 +126,7 @@ export function useModelAutoSave(
if (!result.success) {
throw new Error(result.error)
}
taskConfigSnapshotRef.current = JSON.stringify(newTaskConfig)
onUnsavedChange?.(false)
} catch (error) {
console.error('自动保存任务配置失败:', error)
@@ -122,6 +140,13 @@ export function useModelAutoSave(
useEffect(() => {
if (initialLoadRef.current) return
const snapshot = snapshotModels(models)
if (modelsSnapshotRef.current === null) {
modelsSnapshotRef.current = snapshot
return
}
if (snapshot === modelsSnapshotRef.current) return
onUnsavedChange?.(true)
if (modelsTimerRef.current) {
@@ -137,12 +162,19 @@ export function useModelAutoSave(
clearTimeout(modelsTimerRef.current)
}
}
}, [models, autoSaveModels, debounceMs, onUnsavedChange])
}, [models, autoSaveModels, debounceMs, onUnsavedChange, snapshotModels])
// 监听 taskConfig 变化
useEffect(() => {
if (initialLoadRef.current || !taskConfig) return
const snapshot = snapshotTaskConfig(taskConfig)
if (taskConfigSnapshotRef.current === null) {
taskConfigSnapshotRef.current = snapshot
return
}
if (snapshot === taskConfigSnapshotRef.current) return
onUnsavedChange?.(true)
if (taskConfigTimerRef.current) {
@@ -158,7 +190,7 @@ export function useModelAutoSave(
clearTimeout(taskConfigTimerRef.current)
}
}
}, [taskConfig, autoSaveTaskConfig, debounceMs, onUnsavedChange])
}, [taskConfig, autoSaveTaskConfig, debounceMs, onUnsavedChange, snapshotTaskConfig])
// 组件卸载时清除定时器
useEffect(() => {
@@ -170,5 +202,6 @@ export function useModelAutoSave(
return {
clearTimers,
initialLoadRef,
resetSnapshots,
}
}

View File

@@ -78,6 +78,7 @@ function ModelProviderConfigPageContent() {
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const initialLoadRef = useRef(true)
const providersSnapshotRef = useRef<string | null>(null)
const prevTourStepRef = useRef(tourState.stepIndex)
// 注册 Tour
@@ -161,7 +162,9 @@ function ModelProviderConfigPageContent() {
return
}
const config = unwrapModelConfig(result.data)
setProviders(Array.isArray(config.api_providers) ? config.api_providers as APIProvider[] : [])
const providerList = Array.isArray(config.api_providers) ? config.api_providers as APIProvider[] : []
setProviders(providerList)
providersSnapshotRef.current = JSON.stringify(providerList.map(cleanProviderData))
setHasUnsavedChanges(false)
initialLoadRef.current = false
} catch (error) {
@@ -231,6 +234,7 @@ function ModelProviderConfigPageContent() {
setSaving(false)
return
}
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
setHasUnsavedChanges(false)
toast({
title: '保存成功',
@@ -356,6 +360,7 @@ function ModelProviderConfigPageContent() {
}
setProviders(deleteConfirmState.pendingProviders)
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
setHasUnsavedChanges(false)
toast({
@@ -431,6 +436,7 @@ function ModelProviderConfigPageContent() {
setHasUnsavedChanges(true)
return
}
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
setHasUnsavedChanges(false)
} catch (error) {
console.error('自动保存失败:', error)
@@ -448,6 +454,13 @@ function ModelProviderConfigPageContent() {
useEffect(() => {
if (initialLoadRef.current) return
const snapshot = JSON.stringify(providers.map(cleanProviderData))
if (providersSnapshotRef.current === null) {
providersSnapshotRef.current = snapshot
return
}
if (snapshot === providersSnapshotRef.current) return
setHasUnsavedChanges(true)
if (autoSaveTimerRef.current) {
@@ -529,6 +542,7 @@ function ModelProviderConfigPageContent() {
setSaving(false)
return
}
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
setHasUnsavedChanges(false)
toast({
title: '保存成功',