diff --git a/electron/services/insightService.ts b/electron/services/insightService.ts index 3e9f523..b168951 100644 --- a/electron/services/insightService.ts +++ b/electron/services/insightService.ts @@ -427,17 +427,22 @@ class InsightService { // ── 沉默联系人扫描 ────────────────────────────────────────────────────────── private scheduleSilenceScan(): void { - this.silenceInitialDelayTimer = setTimeout(() => { - void this.runSilenceScan() - // 每次扫描完毕后重新读取间隔配置,允许用户动态调整不需要重启 - const scheduleNext = () => { - const intervalHours = (this.config.get('aiInsightScanIntervalHours') as number) || 4 - const intervalMs = Math.max(0.1, intervalHours) * 60 * 60 * 1000 - insightLog('INFO', `下次沉默扫描将在 ${intervalHours} 小时后执行`) - this.silenceScanTimer = setTimeout(() => { - void this.runSilenceScan().then(scheduleNext) - }, intervalMs) - } + // 等待扫描完成后再安排下一次,避免并发堆积 + const scheduleNext = () => { + if (!this.started) return + const intervalHours = (this.config.get('aiInsightScanIntervalHours') as number) || 4 + const intervalMs = Math.max(0.1, intervalHours) * 60 * 60 * 1000 + insightLog('INFO', `下次沉默扫描将在 ${intervalHours} 小时后执行`) + this.silenceScanTimer = setTimeout(async () => { + this.silenceScanTimer = null + await this.runSilenceScan() + scheduleNext() + }, intervalMs) + } + + this.silenceInitialDelayTimer = setTimeout(async () => { + this.silenceInitialDelayTimer = null + await this.runSilenceScan() scheduleNext() }, SILENCE_SCAN_INITIAL_DELAY_MS) } @@ -711,8 +716,9 @@ class InsightService { const telegramChatIds = (this.config.get('aiInsightTelegramChatIds') as string) || '' if (telegramToken && telegramChatIds) { const chatIds = telegramChatIds.split(',').map((s) => s.trim()).filter(Boolean) + const telegramText = `【WeFlow】 ${notifTitle}\n\n${insight}` for (const chatId of chatIds) { - this.sendTelegram(telegramToken, chatId, `${notifTitle}\n\n${insight}`).catch((e) => { + this.sendTelegram(telegramToken, chatId, telegramText).catch((e) => { insightLog('WARN', `Telegram 推送失败 (chatId=${chatId}): ${(e as Error).message}`) }) } diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 620d38e..35f989f 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -1467,7 +1467,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
- + 选择聊天中引用消息与正文的上下顺序,下方预览会同步展示布局差异。
{[ @@ -2825,6 +2825,10 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { 2. 控制在 80 字以内,直接、具体、一针见血。不要废话。 3. 输出纯文本,不使用 Markdown。 4. 只有在完全没有任何可说的内容时(比如对话只有一条"嗯"),才回复"SKIP"。绝大多数情况下你应该输出见解。` + + // 展示值:有自定义内容时显示自定义内容,否则显示默认值(可直接编辑) + const displayValue = aiInsightSystemPrompt || DEFAULT_SYSTEM_PROMPT + return (
@@ -2833,6 +2837,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { className="button-secondary" style={{ fontSize: 12, padding: '3px 10px' }} onClick={async () => { + // 恢复默认:清空自定义值,UI 回到显示默认内容的状态 setAiInsightSystemPrompt('') await configService.setAiInsightSystemPrompt('') }} @@ -2841,16 +2846,16 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
- 留空则使用内置默认提示词。修改后立即生效,无需重启。可变的统计信息(触发次数、对话内容)会自动附加在用户消息里,无需在此填写。 + 当前显示内置默认提示词,可直接编辑修改。修改后立即生效,无需重启。可变的统计信息(触发次数、对话内容)会自动附加在用户消息里,无需在此填写。