diff --git a/electron/main.ts b/electron/main.ts index 4ec00b7..b91f2ad 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -2372,6 +2372,13 @@ app.whenReady().then(async () => { }) }) +app.on('before-quit', async () => { + // 停止 HTTP 服务器,释放 TCP 端口占用,避免进程无法退出 + try { await httpService.stop() } catch {} + // 终止 wcdb Worker 线程,避免线程阻止进程退出 + try { wcdbService.shutdown() } catch {} +}) + app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() diff --git a/electron/services/cloudControlService.ts b/electron/services/cloudControlService.ts index f1a1c02..9b29ab3 100644 --- a/electron/services/cloudControlService.ts +++ b/electron/services/cloudControlService.ts @@ -35,7 +35,7 @@ class CloudControlService { private async reportOnline() { const data: UsageStats = { appVersion: app.getVersion(), - platform: process.platform, + platform: this.getPlatformVersion(), deviceId: this.deviceId, timestamp: Date.now(), online: true, @@ -46,6 +46,29 @@ class CloudControlService { this.pages.clear() } + private getPlatformVersion(): string { + const os = require('os') + const platform = process.platform + + if (platform === 'win32') { + const release = os.release() + const parts = release.split('.') + const major = parseInt(parts[0]) + const minor = parseInt(parts[1] || '0') + const build = parseInt(parts[2] || '0') + + // Windows 11 是 10.0.22000+,且主版本必须是 10.0 + if (major === 10 && minor === 0 && build >= 22000) { + return 'Windows 11' + } else if (major === 10) { + return 'Windows 10' + } + return `Windows ${release}` + } + + return platform + } + recordPage(pageName: string) { this.pages.add(pageName) } diff --git a/src/App.tsx b/src/App.tsx index 9d040d2..137ba7b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -179,7 +179,9 @@ function App() { } else { // 协议已同意,检查数据收集同意状态 const consent = await configService.getAnalyticsConsent() - if (consent === null) { + const denyCount = await configService.getAnalyticsDenyCount() + // 如果未设置同意状态且拒绝次数小于2次,显示弹窗 + if (consent === null && denyCount < 2) { setShowAnalyticsConsent(true) } } @@ -226,8 +228,9 @@ function App() { } const handleAnalyticsDeny = async () => { - await configService.setAnalyticsConsent(false) - window.electronAPI.window.close() + const denyCount = await configService.getAnalyticsDenyCount() + await configService.setAnalyticsDenyCount(denyCount + 1) + setShowAnalyticsConsent(false) } // 监听启动时的更新通知 diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 91b121a..6161d23 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -121,6 +121,9 @@ function SettingsPage() { const [wordCloudExcludeWords, setWordCloudExcludeWords] = useState([]) const [excludeWordsInput, setExcludeWordsInput] = useState('') + // 数据收集同意状态 + const [analyticsConsent, setAnalyticsConsent] = useState(false) + @@ -343,6 +346,9 @@ function SettingsPage() { setWordCloudExcludeWords(savedExcludeWords) setExcludeWordsInput(savedExcludeWords.join('\n')) + const savedAnalyticsConsent = await configService.getAnalyticsConsent() + setAnalyticsConsent(savedAnalyticsConsent ?? false) + // 如果语言列表为空,保存默认值 if (!savedTranscribeLanguages || savedTranscribeLanguages.length === 0) { const defaultLanguages = ['zh'] @@ -2313,6 +2319,24 @@ function SettingsPage() { { e.preventDefault(); window.electronAPI.window.openAgreementWindow() }}>用户协议

© 2025 WeFlow. All rights reserved.

+ +
+ 匿名数据收集 + +
) diff --git a/src/services/config.ts b/src/services/config.ts index b5a25c8..60ed613 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -64,7 +64,8 @@ export const CONFIG_KEYS = { WORD_CLOUD_EXCLUDE_WORDS: 'wordCloudExcludeWords', // 数据收集 - ANALYTICS_CONSENT: 'analyticsConsent' + ANALYTICS_CONSENT: 'analyticsConsent', + ANALYTICS_DENY_COUNT: 'analyticsDenyCount' } as const export interface WxidConfig { @@ -1098,3 +1099,14 @@ export async function getAnalyticsConsent(): Promise { export async function setAnalyticsConsent(consent: boolean): Promise { await config.set(CONFIG_KEYS.ANALYTICS_CONSENT, consent) } + +// 获取数据收集拒绝次数 +export async function getAnalyticsDenyCount(): Promise { + const value = await config.get(CONFIG_KEYS.ANALYTICS_DENY_COUNT) + return typeof value === 'number' ? value : 0 +} + +// 设置数据收集拒绝次数 +export async function setAnalyticsDenyCount(count: number): Promise { + await config.set(CONFIG_KEYS.ANALYTICS_DENY_COUNT, count) +}