feat: 新增模型管理和供应商配置功能

### v1.1.0
- #### Added
  - 新增 AI 笔记风格选择
  - 新增 AI 笔记返回格式选择
  - 添加 AI 自定义笔记备注 Prompt
  - 添加任务失败重试
  - 添加全局设置页,可在设置页进行模型设置

- #### Optimize
  - 优化前端样式,优化用户体验
  - 增加生成中间产物,可用于失败后加快生成速度
- #### Fix
  - 修复视频截图视频过早删除错误
This commit is contained in:
思诺特
2025-04-26 23:40:17 +08:00
parent 1323cfd1ec
commit 171dea5e0d
51 changed files with 2511 additions and 414 deletions

View File

@@ -1,45 +1,59 @@
// hooks/useTaskPolling.ts
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'
import { useTaskStore } from '@/store/taskStore'
import { get_task_status } from '@/services/note.ts'
import toast from 'react-hot-toast'
export const useTaskPolling = (interval = 3000) => {
const tasks = useTaskStore(state => state.tasks)
const updateTaskContent = useTaskStore(state => state.updateTaskContent)
const updateTaskStatus = useTaskStore(state => state.updateTaskStatus)
const removeTask = useTaskStore(state => state.removeTask)
const tasksRef = useRef(tasks)
// 每次 tasks 更新,把最新的 tasks 同步进去
useEffect(() => {
tasksRef.current = tasks
}, [tasks])
useEffect(() => {
const timer = setInterval(async () => {
const pendingTasks = tasks.filter(
task => task.status === 'PENDING' || task.status === 'running'
const pendingTasks = tasksRef.current.filter(
task => task.status != 'SUCCESS' && task.status != 'FAILED'
)
for (const task of pendingTasks) {
try {
console.log(task)
console.log('🔄 正在轮询任务:', task.id)
const res = await get_task_status(task.id)
const { status } = res.data
if (status && status !== task.status) {
if (status === 'SUCCESS') {
const { markdown, transcript, audio_meta } = res.data.result
toast.success('笔记生成成功')
updateTaskContent(task.id, {
status,
markdown,
transcript,
audioMeta: audio_meta,
})
} else if (status === 'FAILED') {
updateTaskContent(task.id, { status })
console.warn(`⚠️ 任务 ${task.id} 失败`)
} else {
updateTaskStatus(task.id, status)
updateTaskContent(task.id, { status })
}
}
} catch (e) {
console.error('❌ 任务轮询失败:', e)
removeTask(task.id)
toast.error(`生成失败 ${e.message || e}`)
updateTaskContent(task.id, { status: 'FAILED' })
// removeTask(task.id)
}
}
}, interval)
return () => clearInterval(timer)
}, [interval, tasks])
}, [interval])
}