feat: WebDAV data backup and restore secondary confirmation #1326
close #1326
This commit is contained in:
parent
38f665e484
commit
50438dd612
@ -1402,11 +1402,7 @@ export function isWebSearchModel(model: Model): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (provider.id === 'aihubmix') {
|
if (provider.id === 'aihubmix') {
|
||||||
const models = [
|
const models = ['gemini-2.0-flash-search', 'gemini-2.0-flash-exp-search', 'gemini-2.0-pro-exp-02-05-search']
|
||||||
'gemini-2.0-flash-search',
|
|
||||||
'gemini-2.0-flash-exp-search',
|
|
||||||
'gemini-2.0-pro-exp-02-05-search'
|
|
||||||
]
|
|
||||||
return models.includes(model?.id)
|
return models.includes(model?.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -433,6 +433,8 @@
|
|||||||
"webdav.noSync": "Waiting for next backup",
|
"webdav.noSync": "Waiting for next backup",
|
||||||
"webdav.syncError": "Backup Error",
|
"webdav.syncError": "Backup Error",
|
||||||
"webdav.lastSync": "Last Backup",
|
"webdav.lastSync": "Last Backup",
|
||||||
|
"webdav.restore.title": "Restore from WebDAV",
|
||||||
|
"webdav.restore.content": "Restore from WebDAV will overwrite the current data, continue?",
|
||||||
"notion.api_key": "Notion API Key",
|
"notion.api_key": "Notion API Key",
|
||||||
"notion.database_id": "Notion Database ID",
|
"notion.database_id": "Notion Database ID",
|
||||||
"notion.title": "Notion Configuration"
|
"notion.title": "Notion Configuration"
|
||||||
|
|||||||
@ -424,6 +424,8 @@
|
|||||||
"webdav.noSync": "次回のバックアップを待っています",
|
"webdav.noSync": "次回のバックアップを待っています",
|
||||||
"webdav.syncError": "バックアップエラー",
|
"webdav.syncError": "バックアップエラー",
|
||||||
"webdav.lastSync": "最終同期",
|
"webdav.lastSync": "最終同期",
|
||||||
|
"webdav.restore.title": "WebDAVから復元",
|
||||||
|
"webdav.restore.content": "WebDAVから復元すると、現在のデータが上書きされます。続行しますか?",
|
||||||
"notion.api_key": "Notion APIキー",
|
"notion.api_key": "Notion APIキー",
|
||||||
"notion.database_id": "Notion データベースID",
|
"notion.database_id": "Notion データベースID",
|
||||||
"notion.title": "Notion 設定"
|
"notion.title": "Notion 設定"
|
||||||
|
|||||||
@ -425,6 +425,8 @@
|
|||||||
"webdav.noSync": "Ожидание следующего резервного копирования",
|
"webdav.noSync": "Ожидание следующего резервного копирования",
|
||||||
"webdav.syncError": "Ошибка резервного копирования",
|
"webdav.syncError": "Ошибка резервного копирования",
|
||||||
"webdav.lastSync": "Последняя синхронизация",
|
"webdav.lastSync": "Последняя синхронизация",
|
||||||
|
"webdav.restore.title": "Восстановление с WebDAV",
|
||||||
|
"webdav.restore.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?",
|
||||||
"notion.api_key": "Ключ API Notion",
|
"notion.api_key": "Ключ API Notion",
|
||||||
"notion.database_id": "ID базы данных Notion",
|
"notion.database_id": "ID базы данных Notion",
|
||||||
"notion.title": "Настройки Notion"
|
"notion.title": "Настройки Notion"
|
||||||
|
|||||||
@ -432,6 +432,8 @@
|
|||||||
"webdav.noSync": "等待下次备份",
|
"webdav.noSync": "等待下次备份",
|
||||||
"webdav.syncError": "备份错误",
|
"webdav.syncError": "备份错误",
|
||||||
"webdav.lastSync": "上次备份时间",
|
"webdav.lastSync": "上次备份时间",
|
||||||
|
"webdav.restore.title": "从 WebDAV 恢复",
|
||||||
|
"webdav.restore.content": "从 WebDAV 恢复将覆盖当前数据,是否继续?",
|
||||||
"notion.api_key": "Notion 密钥",
|
"notion.api_key": "Notion 密钥",
|
||||||
"notion.database_id": "Notion 数据库ID",
|
"notion.database_id": "Notion 数据库ID",
|
||||||
"notion.title": "Notion 配置"
|
"notion.title": "Notion 配置"
|
||||||
|
|||||||
@ -431,6 +431,8 @@
|
|||||||
"webdav.noSync": "等待下次備份",
|
"webdav.noSync": "等待下次備份",
|
||||||
"webdav.syncError": "備份錯誤",
|
"webdav.syncError": "備份錯誤",
|
||||||
"webdav.lastSync": "上次同步時間",
|
"webdav.lastSync": "上次同步時間",
|
||||||
|
"webdav.restore.title": "從 WebDAV 恢復",
|
||||||
|
"webdav.restore.content": "從 WebDAV 恢復將覆蓋當前資料,是否繼續?",
|
||||||
"notion.api_key": "Notion 金鑰",
|
"notion.api_key": "Notion 金鑰",
|
||||||
"notion.database_id": "Notion 資料庫 ID",
|
"notion.database_id": "Notion 資料庫 ID",
|
||||||
"notion.title": "Notion 配置"
|
"notion.title": "Notion 配置"
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { backup, reset, restore } from '@renderer/services/BackupService'
|
|||||||
import { RootState, useAppDispatch } from '@renderer/store'
|
import { RootState, useAppDispatch } from '@renderer/store'
|
||||||
import { setNotionApiKey, setNotionDatabaseID } from '@renderer/store/settings'
|
import { setNotionApiKey, setNotionDatabaseID } from '@renderer/store/settings'
|
||||||
import { AppInfo } from '@renderer/types'
|
import { AppInfo } from '@renderer/types'
|
||||||
import { Button,Modal, Typography } from 'antd'
|
import { Button, Modal, Typography } from 'antd'
|
||||||
import Input from 'antd/es/input/Input'
|
import Input from 'antd/es/input/Input'
|
||||||
import { FC, useEffect, useState } from 'react'
|
import { FC, useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -23,17 +23,16 @@ const NotionSettings: FC = () => {
|
|||||||
|
|
||||||
// 这里可以添加 Notion 相关的状态和逻辑
|
// 这里可以添加 Notion 相关的状态和逻辑
|
||||||
// 例如:
|
// 例如:
|
||||||
const notionApiKey = useSelector((state: RootState) => state.settings.notionApiKey);
|
const notionApiKey = useSelector((state: RootState) => state.settings.notionApiKey)
|
||||||
const notionDatabaseID = useSelector((state: RootState) => state.settings.notionDatabaseID);
|
const notionDatabaseID = useSelector((state: RootState) => state.settings.notionDatabaseID)
|
||||||
|
|
||||||
const handleNotionTokenChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleNotionTokenChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
dispatch(setNotionApiKey(e.target.value))
|
dispatch(setNotionApiKey(e.target.value))
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleNotionDatabaseIdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleNotionDatabaseIdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
dispatch(setNotionDatabaseID(e.target.value))
|
dispatch(setNotionDatabaseID(e.target.value))
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingGroup theme={theme}>
|
<SettingGroup theme={theme}>
|
||||||
@ -42,8 +41,8 @@ const NotionSettings: FC = () => {
|
|||||||
<SettingRow>
|
<SettingRow>
|
||||||
<SettingRowTitle>{t('settings.data.notion.api_key')}</SettingRowTitle>
|
<SettingRowTitle>{t('settings.data.notion.api_key')}</SettingRowTitle>
|
||||||
<HStack alignItems="center" gap="5px">
|
<HStack alignItems="center" gap="5px">
|
||||||
<Input.Password
|
<Input
|
||||||
type="text"
|
type="password"
|
||||||
value={notionApiKey || ''}
|
value={notionApiKey || ''}
|
||||||
onChange={handleNotionTokenChange}
|
onChange={handleNotionTokenChange}
|
||||||
onBlur={handleNotionTokenChange}
|
onBlur={handleNotionTokenChange}
|
||||||
@ -165,7 +164,6 @@ const DataSettings: FC = () => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
|
|
||||||
</SettingContainer>
|
</SettingContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,6 +66,15 @@ const WebDavSettings: FC = () => {
|
|||||||
setRestoring(false)
|
setRestoring(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onPressRestore = () => {
|
||||||
|
window.modal.confirm({
|
||||||
|
title: t('settings.data.webdav.restore.title'),
|
||||||
|
content: t('settings.data.webdav.restore.content'),
|
||||||
|
centered: true,
|
||||||
|
onOk: onRestore
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const onSyncIntervalChange = (value: number) => {
|
const onSyncIntervalChange = (value: number) => {
|
||||||
setSyncInterval(value)
|
setSyncInterval(value)
|
||||||
dispatch(_setWebdavSyncInterval(value))
|
dispatch(_setWebdavSyncInterval(value))
|
||||||
@ -158,7 +167,7 @@ const WebDavSettings: FC = () => {
|
|||||||
<Button onClick={onBackup} icon={<SaveOutlined />} loading={backuping}>
|
<Button onClick={onBackup} icon={<SaveOutlined />} loading={backuping}>
|
||||||
{t('settings.data.webdav.backup.button')}
|
{t('settings.data.webdav.backup.button')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={onRestore} icon={<FolderOpenOutlined />} loading={restoring}>
|
<Button onClick={onPressRestore} icon={<FolderOpenOutlined />} loading={restoring}>
|
||||||
{t('settings.data.webdav.restore.button')}
|
{t('settings.data.webdav.restore.button')}
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@ -161,6 +161,7 @@ export default class OpenAIProvider extends BaseProvider {
|
|||||||
const { contextCount, maxTokens, streamOutput } = getAssistantSettings(assistant)
|
const { contextCount, maxTokens, streamOutput } = getAssistantSettings(assistant)
|
||||||
|
|
||||||
let systemMessage = assistant.prompt ? { role: 'system', content: assistant.prompt } : undefined
|
let systemMessage = assistant.prompt ? { role: 'system', content: assistant.prompt } : undefined
|
||||||
|
|
||||||
if (['o1', 'o1-2024-12-17'].includes(model.id) || model.id.startsWith('o3')) {
|
if (['o1', 'o1-2024-12-17'].includes(model.id) || model.id.startsWith('o3')) {
|
||||||
systemMessage = {
|
systemMessage = {
|
||||||
role: 'developer',
|
role: 'developer',
|
||||||
@ -344,7 +345,7 @@ export default class OpenAIProvider extends BaseProvider {
|
|||||||
// 针对思考类模型的返回,总结仅截取</think>之后的内容
|
// 针对思考类模型的返回,总结仅截取</think>之后的内容
|
||||||
let content = response.choices[0].message?.content || ''
|
let content = response.choices[0].message?.content || ''
|
||||||
content = content.replace(/^<think>(.*?)<\/think>/s, '')
|
content = content.replace(/^<think>(.*?)<\/think>/s, '')
|
||||||
|
|
||||||
return removeSpecialCharacters(content.substring(0, 50))
|
return removeSpecialCharacters(content.substring(0, 50))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user