mirror of
https://github.com/JefferyHcool/BiliNote.git
synced 2026-05-17 05:27:36 +08:00
feat: 新增模型管理和供应商配置功能
### v1.1.0 - #### Added - 新增 AI 笔记风格选择 - 新增 AI 笔记返回格式选择 - 添加 AI 自定义笔记备注 Prompt - 添加任务失败重试 - 添加全局设置页,可在设置页进行模型设置 - #### Optimize - 优化前端样式,优化用户体验 - 增加生成中间产物,可用于失败后加快生成速度 - #### Fix - 修复视频截图视频过早删除错误
This commit is contained in:
25
BillNote_frontend/src/store/configStore/index.ts
Normal file
25
BillNote_frontend/src/store/configStore/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
interface SystemState {
|
||||
showFeatureHint: boolean // ✅ 是否显示功能提示
|
||||
setShowFeatureHint: (value: boolean) => void
|
||||
|
||||
// 后续如果有其他全局状态,可以继续加
|
||||
sidebarCollapsed: boolean // ✅ 侧边栏是否收起
|
||||
setSidebarCollapsed: (value: boolean) => void
|
||||
}
|
||||
// 暂不启用
|
||||
export const useSystemStore = create<SystemState>()(
|
||||
persist(
|
||||
set => ({
|
||||
showFeatureHint: true,
|
||||
setShowFeatureHint: value => set({ showFeatureHint: value }),
|
||||
|
||||
sidebarCollapsed: false,
|
||||
setSidebarCollapsed: value => set({ sidebarCollapsed: value }),
|
||||
}),
|
||||
{
|
||||
name: 'system-store', // 本地存储的 key
|
||||
}
|
||||
)
|
||||
)
|
||||
101
BillNote_frontend/src/store/modelStore/index.ts
Normal file
101
BillNote_frontend/src/store/modelStore/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { create } from 'zustand'
|
||||
import { devtools } from 'zustand/middleware'
|
||||
import { fetchModels, addModel, fetchEnableModels } from '@/services/model.ts'
|
||||
|
||||
interface IModel {
|
||||
id: string
|
||||
created: number
|
||||
object: string
|
||||
owned_by: string
|
||||
permission: string
|
||||
root: string
|
||||
}
|
||||
|
||||
interface ModelStore {
|
||||
models: IModel[]
|
||||
modelList: []
|
||||
loading: boolean
|
||||
selectedModel: string
|
||||
loadModels: (providerId: string) => Promise<void>
|
||||
loadEnabledModels: () => Promise<void>
|
||||
addNewModel: (providerId: string, modelId: string) => Promise<void>
|
||||
setSelectedModel: (modelId: string) => void
|
||||
clearModels: () => void
|
||||
}
|
||||
|
||||
export const useModelStore = create<ModelStore>()(
|
||||
devtools(set => ({
|
||||
models: [],
|
||||
loading: false,
|
||||
selectedModel: '',
|
||||
modelList: [],
|
||||
|
||||
loadEnabledModels: async () => {
|
||||
try {
|
||||
set({ loading: true })
|
||||
const res = await fetchEnableModels()
|
||||
if (res.data.code === 0 && res.data.data.length > 0) {
|
||||
set({ modelList: res.data.data })
|
||||
} else {
|
||||
set({ modelList: [] })
|
||||
console.error('模型列表加载失败')
|
||||
}
|
||||
} catch (error) {
|
||||
set({ modelList: [] })
|
||||
console.error('加载模型出错', error)
|
||||
}
|
||||
},
|
||||
// 加载模型列表
|
||||
loadModels: async (providerId: string) => {
|
||||
try {
|
||||
set({ loading: true })
|
||||
const res = await fetchModels(providerId)
|
||||
if (res.data.code === 0 && res.data.data.models.data.length > 0) {
|
||||
set({ models: res.data.data.models.data })
|
||||
} else {
|
||||
set({ models: [] })
|
||||
console.error('模型列表加载失败')
|
||||
}
|
||||
} catch (error) {
|
||||
set({ models: [] })
|
||||
console.error('加载模型出错', error)
|
||||
} finally {
|
||||
set({ loading: false })
|
||||
}
|
||||
},
|
||||
|
||||
// 新增模型
|
||||
addNewModel: async (providerId: string, modelId: string) => {
|
||||
try {
|
||||
const res = await addModel({ provider_id: providerId, model_name: modelId })
|
||||
if (res.code === 0) {
|
||||
console.log('新增模型成功:', modelId)
|
||||
// ✅ 新增成功以后,前端直接追加一条到 models 列表
|
||||
set(state => ({
|
||||
models: [
|
||||
...state.models,
|
||||
{
|
||||
id: modelId,
|
||||
created: Date.now(),
|
||||
object: 'model',
|
||||
owned_by: '',
|
||||
permission: '',
|
||||
root: '',
|
||||
},
|
||||
],
|
||||
}))
|
||||
} else {
|
||||
console.error('新增模型失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加模型出错', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 设置选中的模型
|
||||
setSelectedModel: modelId => set({ selectedModel: modelId }),
|
||||
|
||||
// 清空
|
||||
clearModels: () => set({ models: [], selectedModel: '' }),
|
||||
}))
|
||||
)
|
||||
@@ -1,6 +1,11 @@
|
||||
import { create } from 'zustand'
|
||||
import { IProvider } from '@/types'
|
||||
import { getProviderList } from '@/services/model.ts'
|
||||
import {
|
||||
addProvider,
|
||||
getProviderById,
|
||||
getProviderList,
|
||||
updateProviderById,
|
||||
} from '@/services/model.ts'
|
||||
|
||||
interface ProviderStore {
|
||||
provider: IProvider[]
|
||||
@@ -9,12 +14,14 @@ interface ProviderStore {
|
||||
getProviderById: (id: number) => IProvider | undefined
|
||||
getProviderList: () => IProvider[]
|
||||
fetchProviderList: () => Promise<void>
|
||||
loadProviderById: (id: string) => Promise<void>
|
||||
addNewProvider: (provider: IProvider) => Promise<void>
|
||||
updateProvider: (provider: IProvider) => Promise<void>
|
||||
}
|
||||
|
||||
export const useProviderStore = create<ProviderStore>((set, get) => ({
|
||||
provider: [],
|
||||
|
||||
|
||||
// 添加或更新一个 provider
|
||||
setProvider: newProvider =>
|
||||
set(state => {
|
||||
@@ -30,10 +37,60 @@ export const useProviderStore = create<ProviderStore>((set, get) => ({
|
||||
|
||||
// 设置整个 provider 列表
|
||||
setAllProviders: providers => set({ provider: providers }),
|
||||
|
||||
loadProviderById: async (id: string) => {
|
||||
const res = await getProviderById(id)
|
||||
if (res.data.code === 0) {
|
||||
const item = res.data.data
|
||||
console.log('Provider ', item)
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
logo: item.logo,
|
||||
apiKey: item.api_key,
|
||||
baseUrl: item.base_url,
|
||||
type: item.type,
|
||||
enabled: item.enabled,
|
||||
}
|
||||
} else {
|
||||
console.log('Provider not found')
|
||||
}
|
||||
},
|
||||
addNewProvider: async (provider: IProvider) => {
|
||||
const payload = {
|
||||
...provider,
|
||||
api_key: provider.apiKey,
|
||||
base_url: provider.baseUrl,
|
||||
}
|
||||
try {
|
||||
const res = await addProvider(payload)
|
||||
if (res.data.code === 0) {
|
||||
const item = res.data.data
|
||||
console.log('Provider ', item)
|
||||
await get().fetchProviderList()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching provider:', error)
|
||||
}
|
||||
},
|
||||
// 按 id 获取单个 provider
|
||||
getProviderById: id => get().provider.find(p => p.id === id),
|
||||
|
||||
updateProvider: async (provider: IProvider) => {
|
||||
try {
|
||||
const data = {
|
||||
...provider,
|
||||
api_key: provider.apiKey,
|
||||
base_url: provider.baseUrl,
|
||||
}
|
||||
const res = await updateProviderById(data)
|
||||
if (res.data.code === 0) {
|
||||
const item = res.data.data
|
||||
console.log('Provider ', item)
|
||||
await get().fetchProviderList()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching provider:', error)
|
||||
}
|
||||
},
|
||||
getProviderList: () => get().provider,
|
||||
fetchProviderList: async () => {
|
||||
try {
|
||||
@@ -55,6 +112,7 @@ export const useProviderStore = create<ProviderStore>((set, get) => ({
|
||||
apiKey: item.api_key,
|
||||
baseUrl: item.base_url,
|
||||
type: item.type,
|
||||
enabled: item.enabled,
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { delete_task } from '@/services/note.ts'
|
||||
import { delete_task, generateNote } from '@/services/note.ts'
|
||||
|
||||
export type TaskStatus = 'PENDING' | 'RUNNING' | 'SUCCESS' | 'FAILD'
|
||||
|
||||
@@ -34,6 +34,15 @@ export interface Task {
|
||||
status: TaskStatus
|
||||
audioMeta: AudioMeta
|
||||
createdAt: string
|
||||
formData: {
|
||||
video_url: string
|
||||
link: undefined | boolean
|
||||
screenshot: undefined | boolean
|
||||
platform: string
|
||||
quality: string
|
||||
model_name: string
|
||||
provider_id: string
|
||||
}
|
||||
}
|
||||
|
||||
interface TaskStore {
|
||||
@@ -45,6 +54,7 @@ interface TaskStore {
|
||||
clearTasks: () => void
|
||||
setCurrentTask: (taskId: string | null) => void
|
||||
getCurrentTask: () => Task | null
|
||||
retryTask: (id: string) => void
|
||||
}
|
||||
|
||||
export const useTaskStore = create<TaskStore>()(
|
||||
@@ -53,10 +63,11 @@ export const useTaskStore = create<TaskStore>()(
|
||||
tasks: [],
|
||||
currentTaskId: null,
|
||||
|
||||
addPendingTask: (taskId: string, platform: string) =>
|
||||
addPendingTask: (taskId: string, platform: string, formData: any) =>
|
||||
set(state => ({
|
||||
tasks: [
|
||||
{
|
||||
formData: formData,
|
||||
id: taskId,
|
||||
status: 'PENDING',
|
||||
markdown: '',
|
||||
@@ -91,6 +102,17 @@ export const useTaskStore = create<TaskStore>()(
|
||||
const currentTaskId = get().currentTaskId
|
||||
return get().tasks.find(task => task.id === currentTaskId) || null
|
||||
},
|
||||
retryTask: async (id: string) => {
|
||||
const task = get().tasks.find(task => task.id === id).formData
|
||||
await generateNote({
|
||||
task_id: id,
|
||||
...task,
|
||||
})
|
||||
set(state => ({
|
||||
tasks: state.tasks.map(task => (task.id === id ? { ...task, status: 'PENDING' } : task)),
|
||||
}))
|
||||
},
|
||||
|
||||
removeTask: async id => {
|
||||
const task = get().tasks.find(t => t.id === id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user