fix:模型加载慢,错误热重载
This commit is contained in:
@@ -138,7 +138,7 @@ function ModelConfigPageContent() {
|
|||||||
const { triggerRestart, isRestarting } = useRestart()
|
const { triggerRestart, isRestarting } = useRestart()
|
||||||
|
|
||||||
// 自动保存 (使用 hook 封装的逻辑)
|
// 自动保存 (使用 hook 封装的逻辑)
|
||||||
const { clearTimers: clearAutoSaveTimers, initialLoadRef } = useModelAutoSave({
|
const { clearTimers: clearAutoSaveTimers, initialLoadRef, resetSnapshots } = useModelAutoSave({
|
||||||
models,
|
models,
|
||||||
taskConfig,
|
taskConfig,
|
||||||
onSavingChange: setAutoSaving,
|
onSavingChange: setAutoSaving,
|
||||||
@@ -200,6 +200,7 @@ function ModelConfigPageContent() {
|
|||||||
|
|
||||||
const taskConf = (config.model_task_config as ModelTaskConfig) || null
|
const taskConf = (config.model_task_config as ModelTaskConfig) || null
|
||||||
setTaskConfig(taskConf)
|
setTaskConfig(taskConf)
|
||||||
|
resetSnapshots(modelList, taskConf)
|
||||||
|
|
||||||
// 解析 model_task_config 的 schema
|
// 解析 model_task_config 的 schema
|
||||||
if (schemaResult.success && schemaResult.data) {
|
if (schemaResult.success && schemaResult.data) {
|
||||||
@@ -220,7 +221,7 @@ function ModelConfigPageContent() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}, [initialLoadRef, checkTaskConfigIssues])
|
}, [initialLoadRef, checkTaskConfigIssues, resetSnapshots])
|
||||||
|
|
||||||
// 初始加载
|
// 初始加载
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -343,6 +344,7 @@ function ModelConfigPageContent() {
|
|||||||
setSaving(false)
|
setSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
resetSnapshots(config.models as ModelInfo[], taskConfig)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
toast({
|
toast({
|
||||||
title: '保存成功',
|
title: '保存成功',
|
||||||
@@ -392,6 +394,7 @@ function ModelConfigPageContent() {
|
|||||||
setSaving(false)
|
setSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
resetSnapshots(config.models as ModelInfo[], taskConfig)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
toast({
|
toast({
|
||||||
title: '保存成功',
|
title: '保存成功',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ interface UseModelAutoSaveReturn {
|
|||||||
clearTimers: () => void
|
clearTimers: () => void
|
||||||
/** 初始加载状态标记引用 (用于设置初始加载完成) */
|
/** 初始加载状态标记引用 (用于设置初始加载完成) */
|
||||||
initialLoadRef: RefObject<boolean>
|
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 modelsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
const taskConfigTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
const taskConfigTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
const initialLoadRef = useRef(true)
|
const initialLoadRef = useRef(true)
|
||||||
|
const modelsSnapshotRef = useRef<string | null>(null)
|
||||||
|
const taskConfigSnapshotRef = useRef<string | null>(null)
|
||||||
|
|
||||||
// 清除定时器
|
// 清除定时器
|
||||||
const clearTimers = useCallback(() => {
|
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[]) => {
|
const autoSaveModels = useCallback(async (newModels: ModelInfo[]) => {
|
||||||
try {
|
try {
|
||||||
onSavingChange?.(true)
|
onSavingChange?.(true)
|
||||||
@@ -92,6 +108,7 @@ export function useModelAutoSave(
|
|||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
|
modelsSnapshotRef.current = JSON.stringify(cleanedModels)
|
||||||
onUnsavedChange?.(false)
|
onUnsavedChange?.(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('自动保存模型列表失败:', error)
|
console.error('自动保存模型列表失败:', error)
|
||||||
@@ -109,6 +126,7 @@ export function useModelAutoSave(
|
|||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
|
taskConfigSnapshotRef.current = JSON.stringify(newTaskConfig)
|
||||||
onUnsavedChange?.(false)
|
onUnsavedChange?.(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('自动保存任务配置失败:', error)
|
console.error('自动保存任务配置失败:', error)
|
||||||
@@ -122,6 +140,13 @@ export function useModelAutoSave(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialLoadRef.current) return
|
if (initialLoadRef.current) return
|
||||||
|
|
||||||
|
const snapshot = snapshotModels(models)
|
||||||
|
if (modelsSnapshotRef.current === null) {
|
||||||
|
modelsSnapshotRef.current = snapshot
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (snapshot === modelsSnapshotRef.current) return
|
||||||
|
|
||||||
onUnsavedChange?.(true)
|
onUnsavedChange?.(true)
|
||||||
|
|
||||||
if (modelsTimerRef.current) {
|
if (modelsTimerRef.current) {
|
||||||
@@ -137,12 +162,19 @@ export function useModelAutoSave(
|
|||||||
clearTimeout(modelsTimerRef.current)
|
clearTimeout(modelsTimerRef.current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [models, autoSaveModels, debounceMs, onUnsavedChange])
|
}, [models, autoSaveModels, debounceMs, onUnsavedChange, snapshotModels])
|
||||||
|
|
||||||
// 监听 taskConfig 变化
|
// 监听 taskConfig 变化
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialLoadRef.current || !taskConfig) return
|
if (initialLoadRef.current || !taskConfig) return
|
||||||
|
|
||||||
|
const snapshot = snapshotTaskConfig(taskConfig)
|
||||||
|
if (taskConfigSnapshotRef.current === null) {
|
||||||
|
taskConfigSnapshotRef.current = snapshot
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (snapshot === taskConfigSnapshotRef.current) return
|
||||||
|
|
||||||
onUnsavedChange?.(true)
|
onUnsavedChange?.(true)
|
||||||
|
|
||||||
if (taskConfigTimerRef.current) {
|
if (taskConfigTimerRef.current) {
|
||||||
@@ -158,7 +190,7 @@ export function useModelAutoSave(
|
|||||||
clearTimeout(taskConfigTimerRef.current)
|
clearTimeout(taskConfigTimerRef.current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [taskConfig, autoSaveTaskConfig, debounceMs, onUnsavedChange])
|
}, [taskConfig, autoSaveTaskConfig, debounceMs, onUnsavedChange, snapshotTaskConfig])
|
||||||
|
|
||||||
// 组件卸载时清除定时器
|
// 组件卸载时清除定时器
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -170,5 +202,6 @@ export function useModelAutoSave(
|
|||||||
return {
|
return {
|
||||||
clearTimers,
|
clearTimers,
|
||||||
initialLoadRef,
|
initialLoadRef,
|
||||||
|
resetSnapshots,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ function ModelProviderConfigPageContent() {
|
|||||||
|
|
||||||
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
const initialLoadRef = useRef(true)
|
const initialLoadRef = useRef(true)
|
||||||
|
const providersSnapshotRef = useRef<string | null>(null)
|
||||||
const prevTourStepRef = useRef(tourState.stepIndex)
|
const prevTourStepRef = useRef(tourState.stepIndex)
|
||||||
|
|
||||||
// 注册 Tour
|
// 注册 Tour
|
||||||
@@ -161,7 +162,9 @@ function ModelProviderConfigPageContent() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const config = unwrapModelConfig(result.data)
|
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)
|
setHasUnsavedChanges(false)
|
||||||
initialLoadRef.current = false
|
initialLoadRef.current = false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -231,6 +234,7 @@ function ModelProviderConfigPageContent() {
|
|||||||
setSaving(false)
|
setSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
toast({
|
toast({
|
||||||
title: '保存成功',
|
title: '保存成功',
|
||||||
@@ -356,6 +360,7 @@ function ModelProviderConfigPageContent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setProviders(deleteConfirmState.pendingProviders)
|
setProviders(deleteConfirmState.pendingProviders)
|
||||||
|
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
@@ -431,6 +436,7 @@ function ModelProviderConfigPageContent() {
|
|||||||
setHasUnsavedChanges(true)
|
setHasUnsavedChanges(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('自动保存失败:', error)
|
console.error('自动保存失败:', error)
|
||||||
@@ -448,6 +454,13 @@ function ModelProviderConfigPageContent() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialLoadRef.current) return
|
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)
|
setHasUnsavedChanges(true)
|
||||||
|
|
||||||
if (autoSaveTimerRef.current) {
|
if (autoSaveTimerRef.current) {
|
||||||
@@ -529,6 +542,7 @@ function ModelProviderConfigPageContent() {
|
|||||||
setSaving(false)
|
setSaving(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
providersSnapshotRef.current = JSON.stringify(cleanedProviders)
|
||||||
setHasUnsavedChanges(false)
|
setHasUnsavedChanges(false)
|
||||||
toast({
|
toast({
|
||||||
title: '保存成功',
|
title: '保存成功',
|
||||||
|
|||||||
Reference in New Issue
Block a user