From 8810a41c469daa38a4c43f8333a432f6fcaa4078 Mon Sep 17 00:00:00 2001 From: Frank-whw <2120320012@qq.com> Date: Thu, 4 Sep 2025 18:08:50 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(#427):=20=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=BF=9E=E9=80=9A=E6=80=A7=E6=A3=80=E6=B5=8B=E5=BC=80?= =?UTF-8?q?=E5=85=B3=EF=BC=8C=E5=85=81=E8=AE=B8=E7=94=A8=E6=88=B7=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=20AI=20=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/core/setting/ai/check.tsx | 8 ++++++-- src/app/core/setting/ai/page.tsx | 14 +++++++++++++- src/stores/setting.ts | 13 +++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/app/core/setting/ai/check.tsx b/src/app/core/setting/ai/check.tsx index 65810e84c..34aed4126 100644 --- a/src/app/core/setting/ai/check.tsx +++ b/src/app/core/setting/ai/check.tsx @@ -12,7 +12,7 @@ import { debounce } from "lodash-es" // 检测当前 AI 的可用性 export function AiCheck() { const [state, setState] = useState<'ok' | 'error' | 'checking' | 'init'>('init') - const { currentAi, aiModelList } = useSettingStore() + const { currentAi, aiModelList, aiAutoCheck } = useSettingStore() const t = useTranslations('settings.ai') const abortControllerRef = useRef(null) const debouncedCheckRef = useRef | null>(null) @@ -171,12 +171,16 @@ export function AiCheck() { useEffect(() => { const model = aiModelList.find(item => item.key === currentAi) + if (!aiAutoCheck) { + setState('init') + return + } if (model?.model) { debouncedCheckRef.current?.() } else { setState('init') } - }, [aiModelList, currentAi]) + }, [aiModelList, currentAi, aiAutoCheck]) // 组件卸载时清理资源 useEffect(() => { diff --git a/src/app/core/setting/ai/page.tsx b/src/app/core/setting/ai/page.tsx index 1f4e0548b..693a0151b 100644 --- a/src/app/core/setting/ai/page.tsx +++ b/src/app/core/setting/ai/page.tsx @@ -21,6 +21,7 @@ import { v4 } from 'uuid'; import { confirm } from '@tauri-apps/plugin-dialog'; import { AiCheck } from "./check"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { Switch } from "@/components/ui/switch"; import { Label } from "@/components/ui/label"; import CreateConfig from "./create"; import { Badge } from "@/components/ui/badge"; @@ -34,7 +35,9 @@ export default function AiPage() { currentAi, setCurrentAi, aiModelList, - setAiModelList + setAiModelList, + aiAutoCheck, + setAiAutoCheck } = useSettingStore() const [apiKey, setApiKey] = useState('') const [baseURL, setBaseURL] = useState('') @@ -256,6 +259,15 @@ export default function AiPage() { + {/* 自动连通性检测开关 */} + + +
+ setAiAutoCheck(!!v)} /> + {aiAutoCheck ? t('enabled', { default: '已开启' }) : t('disabled', { default: '已关闭' })} +
+
+
{/* 模型名称 */} diff --git a/src/stores/setting.ts b/src/stores/setting.ts index ed3cd7624..0d47dffef 100644 --- a/src/stores/setting.ts +++ b/src/stores/setting.ts @@ -79,6 +79,10 @@ interface SettingState { tesseractList: string setTesseractList: (tesseractList: string) => void + // AI 设置 - 自动连通性检测 + aiAutoCheck: boolean + setAiAutoCheck: (aiAutoCheck: boolean) => Promise + // Github 相关设置 githubUsername: string setGithubUsername: (githubUsername: string) => Promise @@ -281,6 +285,15 @@ const useSettingStore = create((set, get) => ({ tesseractList: 'eng,chi_sim', setTesseractList: (tesseractList) => set({ tesseractList }), + // AI 设置 - 自动连通性检测(默认开启) + aiAutoCheck: true, + setAiAutoCheck: async (aiAutoCheck: boolean) => { + const store = await Store.load('store.json'); + await store.set('aiAutoCheck', aiAutoCheck) + await store.save() + set({ aiAutoCheck }) + }, + githubUsername: '', setGithubUsername: async (githubUsername) => { set({ githubUsername }) From 44953957b0915bb9cc66f543e284936ab8055f09 Mon Sep 17 00:00:00 2001 From: Frank-whw <2120320012@qq.com> Date: Wed, 17 Sep 2025 20:12:52 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=8A=8A=E8=BF=9E=E9=80=9A?= =?UTF-8?q?=E6=80=A7=E6=B5=8B=E8=AF=95=E7=9A=84=E9=80=BB=E8=BE=91=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/setting/backupSync/webdav-sync.tsx | 25 ++++++++ src/stores/webdav.ts | 61 +------------------ 2 files changed, 27 insertions(+), 59 deletions(-) diff --git a/src/app/core/setting/backupSync/webdav-sync.tsx b/src/app/core/setting/backupSync/webdav-sync.tsx index 8388fc1c5..4bf74a096 100644 --- a/src/app/core/setting/backupSync/webdav-sync.tsx +++ b/src/app/core/setting/backupSync/webdav-sync.tsx @@ -24,6 +24,7 @@ export default function WebdavSync() { syncState, backupState, createWebDAVDir, + testConnection, } = useWebDAVStore(); const { loadFileTree } = useArticleStore() @@ -108,6 +109,15 @@ export default function WebdavSync() { const [isCreating, setIsCreating] = useState(false); + const handleTestConnection = async () => { + const ok = await testConnection(); + if (ok) { + toast({ title: t("success"), description: t("connectionState.success") }); + } else { + toast({ variant: "destructive", title: t("error.testFailed", { default: "Test failed" } as any), description: t("error.connectionTimeOut") }); + } + }; + const handleCreateDirectory = async () => { if (!path.trim()) { toast({ @@ -158,6 +168,21 @@ export default function WebdavSync() { > {t(`connectionState.${connectionState}`)} + {t("description")} diff --git a/src/stores/webdav.ts b/src/stores/webdav.ts index 728e934a8..e71b7d0b9 100644 --- a/src/stores/webdav.ts +++ b/src/stores/webdav.ts @@ -1,5 +1,4 @@ import { create } from 'zustand' -import { Store } from '@tauri-apps/plugin-store' import { invoke } from '@tauri-apps/api/core' export enum WebDAVConnectionState { @@ -37,18 +36,6 @@ interface WebDAVState { syncFromWebDAV: () => Promise } -// 防抖函数 -function simpleDebounce any>( - func: T, - wait: number -): (...args: Parameters) => void { - let timeout: NodeJS.Timeout | null = null - - return (...args: Parameters) => { - if (timeout) clearTimeout(timeout) - timeout = setTimeout(() => func(...args), wait) - } -} const useWebDAVStore = create((set, get) => { let isTestingInProgress = false @@ -101,56 +88,25 @@ const useWebDAVStore = create((set, get) => { } } - // 使用防抖 - const debouncedTest = simpleDebounce(performConnectionTest, 300) - return { url: '', setUrl: async (url: string) => { set({ url }) - try { - const store = await Store.load('store.json') - await store.set('webdavUrl', url) - } catch (error) { - console.error('Failed to save URL:', error) - } - debouncedTest() }, username: '', setUsername: async (username: string) => { set({ username }) - try { - const store = await Store.load('store.json') - await store.set('webdavUsername', username) - } catch (error) { - console.error('Failed to save username:', error) - } - debouncedTest() }, password: '', setPassword: async (password: string) => { set({ password }) - try { - const store = await Store.load('store.json') - await store.set('webdavPassword', password) - } catch (error) { - console.error('Failed to save password:', error) - } - debouncedTest() }, path: '', setPath: async (path: string) => { set({ path }) - try { - const store = await Store.load('store.json') - await store.set('webdavPath', path) - } catch (error) { - console.error('Failed to save path:', error) - } - debouncedTest() }, connectionState: WebDAVConnectionState.fail, @@ -163,21 +119,8 @@ const useWebDAVStore = create((set, get) => { }, initWebDAVData: async () => { - try { - const store = await Store.load('store.json') - const url = await store.get('webdavUrl') || '' - const username = await store.get('webdavUsername') || '' - const password = await store.get('webdavPassword') || '' - const path = await store.get('webdavPath') || '' - - set({ url, username, password, path }) - - if (url && username && password) { - setTimeout(() => performConnectionTest(), 100) - } - } catch (error) { - console.error('Failed to load WebDAV data:', error) - } + // 不再从本地存储加载连接参数,也不做自动连测 + set({ url: '', username: '', password: '', path: '' }) }, backupState: false, From 3e6fe3d110e4ca192743c0d02faae79b72dfdb7e Mon Sep 17 00:00:00 2001 From: Frank-whw <2120320012@qq.com> Date: Wed, 17 Sep 2025 20:14:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0i18n=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- messages/en.json | 2 ++ messages/ja.json | 2 ++ messages/zh.json | 2 ++ 3 files changed, 6 insertions(+) diff --git a/messages/en.json b/messages/en.json index 005c4f7e2..c2ff7b345 100644 --- a/messages/en.json +++ b/messages/en.json @@ -303,6 +303,7 @@ "description": "WebDAV is only used as a backup solution and does not support auto-sync, history rollback, and other features.", "backupTo": "Backup to WebDAV", "syncFrom": "Sync from WebDAV", + "testConnection": "Test Connection", "serverUrl": "WebDAV Server URL", "serverUrlDesc": "Enter the URL of the WebDAV server No path included, e.g: https://dav.example.com http://192.8.8.88:9999", "serverUrlPlaceholder": "https://dav.example.com", @@ -327,6 +328,7 @@ "success": "Success", "failed": "Failed", "error": { + "testFailed": "Connection test failed", "pathNotFound": "Path not found or server inaccessible.", "createDirFailed": "Failed to create directory", "connectionTimeOut": "Connection timed out, please check network or server." diff --git a/messages/ja.json b/messages/ja.json index c4d6ccac0..1e7e0a131 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -301,6 +301,7 @@ "description": "WebDAVはバックアップソリューションとしてのみ使用され、自動同期や履歴ロールバックなどの機能はサポートしていません。", "backupTo": "WebDAVにバックアップ", "syncFrom": "WebDAVから同期", + "testConnection": "接続テスト", "serverUrl": "WebDAVサーバーURL", "serverUrlDesc": "WebDAVサーバーのURLを入力してくださいパスを含まない、例:https://dav.example.com http://192.8.8.88:9999 ", "serverUrlPlaceholder": "https://dav.example.com", @@ -325,6 +326,7 @@ "success": "成功", "failed": "失敗", "error": { + "testFailed": "接続テストに失敗しました", "pathNotFound": "パスが存在しないか、サーバーにアクセスできません。", "createDirFailed": "ディレクトリの作成に失敗しました", "connectionTimeOut": "接続タイムアウト、ネットワークまたはサーバーを確認してください。" diff --git a/messages/zh.json b/messages/zh.json index 7b9e2de71..e9b444014 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -295,6 +295,7 @@ "description": "WebDAV 仅作为备用备份方案,不支持自动同步、历史回滚等功能。", "backupTo": "备份至 WebDAV", "syncFrom": "从 WebDAV 同步", + "testConnection": "测试连接", "serverUrl": "WebDAV 服务器地址", "serverUrlDesc": "输入WebDAV服务器的URL不含路径,例如:https://dav.example.com http://192.8.8.88:9999 ", "serverUrlPlaceholder": "https://dav.example.com", @@ -319,6 +320,7 @@ "success": "成功", "failed": "失败", "error": { + "testFailed": "连接测试失败", "pathNotFound": "路径不存在或服务器无法访问。", "createDirFailed": "创建目录失败", "connectionTimeOut": "连接超时,请检查网络或服务器。"