diff --git a/electron/main.ts b/electron/main.ts index 6ac7211..c0a6aa6 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -2825,6 +2825,8 @@ app.whenReady().then(async () => { // 启动时检测更新(不阻塞启动) checkForUpdatesOnStartup() + await httpService.autoStart() + app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { mainWindow = createWindow() diff --git a/electron/services/config.ts b/electron/services/config.ts index 97c733b..47939bf 100644 --- a/electron/services/config.ts +++ b/electron/services/config.ts @@ -52,6 +52,8 @@ interface ConfigSchema { notificationFilterMode: 'all' | 'whitelist' | 'blacklist' notificationFilterList: string[] messagePushEnabled: boolean + httpApiEnabled: boolean + httpApiPort: number httpApiToken: string windowCloseBehavior: 'ask' | 'tray' | 'quit' quoteLayout: 'quote-top' | 'quote-bottom' @@ -121,6 +123,8 @@ export class ConfigService { notificationFilterMode: 'all', notificationFilterList: [], httpApiToken: '', + httpApiEnabled: false, + httpApiPort: 5031, messagePushEnabled: false, windowCloseBehavior: 'ask', quoteLayout: 'quote-top', @@ -664,11 +668,9 @@ export class ConfigService { // 即使 authEnabled 被删除/篡改,如果密钥是 lock: 格式,说明曾开启过应用锁 const rawDecryptKey: any = this.store.get('decryptKey') - if (typeof rawDecryptKey === 'string' && rawDecryptKey.startsWith(LOCK_PREFIX)) { - return true - } + return typeof rawDecryptKey === 'string' && rawDecryptKey.startsWith(LOCK_PREFIX); + - return false } // === 工具方法 === diff --git a/electron/services/httpService.ts b/electron/services/httpService.ts index 78b4162..c67770e 100644 --- a/electron/services/httpService.ts +++ b/electron/services/httpService.ts @@ -246,6 +246,19 @@ class HttpService { } } + async autoStart(): Promise { + const enabled = this.configService.get('httpApiEnabled') + if (enabled) { + const port = Number(this.configService.get('httpApiPort')) || 5031 + try { + await this.start(port) + console.log(`[HttpService] Auto-started on port ${port}`) + } catch (err) { + console.error('[HttpService] Auto-start failed:', err) + } + } + } + /** * 解析 POST 请求的 JSON Body */ @@ -282,9 +295,9 @@ class HttpService { if (queryToken && queryToken.trim() === expectedToken) return true const bodyToken = body['access_token'] - if (bodyToken && String(bodyToken).trim() === expectedToken) return true + return !!(bodyToken && String(bodyToken).trim() === expectedToken); + - return false } /** diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 696b799..de8d6f7 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -130,6 +130,8 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { showMessage('已清除 Access Token,API 将允许无鉴权访问', true) } + + const [autoTranscribeVoice, setAutoTranscribeVoice] = useState(false) const [transcribeLanguages, setTranscribeLanguages] = useState(['zh']) @@ -344,6 +346,9 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { const savedHttpApiToken = await configService.getHttpApiToken() if (savedHttpApiToken) setHttpApiToken(savedHttpApiToken) + const savedApiPort = await configService.getHttpApiPort() + if (savedApiPort) setHttpApiPort(savedApiPort) + setAuthEnabled(savedAuthEnabled) setAuthUseHello(savedAuthUseHello) setIsLockMode(savedIsLockMode) @@ -386,6 +391,8 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { const savedAnalyticsConsent = await configService.getAnalyticsConsent() setAnalyticsConsent(savedAnalyticsConsent ?? false) + + // 如果语言列表为空,保存默认值 if (!savedTranscribeLanguages || savedTranscribeLanguages.length === 0) { const defaultLanguages = ['zh'] @@ -1850,6 +1857,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { try { await window.electronAPI.http.stop() setHttpApiRunning(false) + await configService.setHttpApiEnabled(false) showMessage('API 服务已停止', true) } catch (e: any) { showMessage(`操作失败: ${e}`, false) @@ -1867,6 +1875,10 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { if (result.success) { setHttpApiRunning(true) if (result.port) setHttpApiPort(result.port) + + await configService.setHttpApiEnabled(true) + await configService.setHttpApiPort(result.port || httpApiPort) + showMessage(`API 服务已启动,端口 ${result.port}`, true) } else { showMessage(`启动失败: ${result.error}`, false) @@ -1915,14 +1927,18 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { API 服务监听的端口号(1024-65535) setHttpApiPort(parseInt(e.target.value, 10) || 5031)} - disabled={httpApiRunning} - style={{ width: 120 }} - min={1024} - max={65535} + type="number" + className="field-input" + value={httpApiPort} + onChange={(e) => { + const port = parseInt(e.target.value, 10) || 5031 + setHttpApiPort(port) + scheduleConfigSave('httpApiPort', () => configService.setHttpApiPort(port)) + }} + disabled={httpApiRunning} + style={{ width: 120 }} + min={1024} + max={65535} /> diff --git a/src/services/config.ts b/src/services/config.ts index a80ecf2..7e184f4 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -65,6 +65,8 @@ export const CONFIG_KEYS = { NOTIFICATION_FILTER_MODE: 'notificationFilterMode', NOTIFICATION_FILTER_LIST: 'notificationFilterList', HTTP_API_TOKEN: 'httpApiToken', + HTTP_API_ENABLED: 'httpApiEnabled', + HTTP_API_PORT: 'httpApiPort', MESSAGE_PUSH_ENABLED: 'messagePushEnabled', WINDOW_CLOSE_BEHAVIOR: 'windowCloseBehavior', QUOTE_LAYOUT: 'quoteLayout', @@ -1484,3 +1486,26 @@ export async function getAnalyticsDenyCount(): Promise { export async function setAnalyticsDenyCount(count: number): Promise { await config.set(CONFIG_KEYS.ANALYTICS_DENY_COUNT, count) } + + +// 获取 HTTP API 自动启动状态 +export async function getHttpApiEnabled(): Promise { + const value = await config.get(CONFIG_KEYS.HTTP_API_ENABLED) + return value === true +} + +// 设置 HTTP API 自动启动状态 +export async function setHttpApiEnabled(enabled: boolean): Promise { + await config.set(CONFIG_KEYS.HTTP_API_ENABLED, enabled) +} + +// 获取 HTTP API 端口 +export async function getHttpApiPort(): Promise { + const value = await config.get(CONFIG_KEYS.HTTP_API_PORT) + return typeof value === 'number' ? value : 5031 +} + +// 设置 HTTP API 端口 +export async function setHttpApiPort(port: number): Promise { + await config.set(CONFIG_KEYS.HTTP_API_PORT, port) +}