feat: 添加自定义系统提示词和风格选项,优化AI摘要功能

This commit is contained in:
ILoveBingLu
2026-03-02 03:29:40 +08:00
parent ee4f580ebf
commit e5b74c8afd
15 changed files with 266 additions and 23 deletions
+6 -6
View File
@@ -12,7 +12,7 @@ function WhatsNewModal({ onClose, version }: WhatsNewModalProps) {
{
icon: <Package size={20} />,
title: '优化',
desc: '优化图片密钥获取。'
desc: '优化AI摘要。'
},
// {
// icon: <Image size={20} />,
@@ -29,11 +29,11 @@ function WhatsNewModal({ onClose, version }: WhatsNewModalProps) {
// title: '分类导出',
// desc: '导出时可按群聊或个人聊天筛选,支持日期范围过滤。'
// }
// {
// icon: <Aperture size={20} />,
// title: '朋友圈',
// desc: '评论内的表情包已完成解密!'
// }
{
icon: <Aperture size={20} />,
title: '朋友圈',
desc: '评论内的图片已完成解密!'
}
]
const handleTelegram = () => {
+19
View File
@@ -238,6 +238,25 @@
}
}
.custom-system-prompt-textarea {
width: 100%;
min-height: 160px;
resize: vertical;
padding: 12px 14px;
border: 1px solid var(--border-color);
border-radius: 12px;
background: var(--bg-primary);
color: var(--text-primary);
font-size: 13px;
line-height: 1.6;
outline: none;
transition: border-color 0.2s;
&:focus {
border-color: var(--primary);
}
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
+46
View File
@@ -103,6 +103,10 @@ interface AISummarySettingsProps {
setDefaultTimeRange: (val: number) => void
summaryDetail: 'simple' | 'normal' | 'detailed'
setSummaryDetail: (val: 'simple' | 'normal' | 'detailed') => void
systemPromptPreset: 'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom'
setSystemPromptPreset: (val: 'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom') => void
customSystemPrompt: string
setCustomSystemPrompt: (val: string) => void
enableThinking: boolean
setEnableThinking: (val: boolean) => void
messageLimit: number
@@ -121,6 +125,10 @@ function AISummarySettings({
setDefaultTimeRange,
summaryDetail,
setSummaryDetail,
systemPromptPreset,
setSystemPromptPreset,
customSystemPrompt,
setCustomSystemPrompt,
enableThinking,
setEnableThinking,
messageLimit,
@@ -331,6 +339,13 @@ function AISummarySettings({
{ value: 7, label: '最近 7 天' },
{ value: 30, label: '最近 30 天' }
]
const systemPromptPresetOptions = [
{ value: 'default', label: '通用平衡(默认)' },
{ value: 'decision-focus', label: '决策优先(重点提炼结论)' },
{ value: 'action-focus', label: '行动优先(重点提炼待办)' },
{ value: 'risk-focus', label: '风险优先(重点识别阻塞与风险)' },
{ value: 'custom', label: '自定义系统提示词' }
]
return (
<div className="tab-content ai-summary-settings">
@@ -558,6 +573,37 @@ function AISummarySettings({
</div>
</div>
<h3 className="section-title"></h3>
<div className="settings-form" style={{ marginTop: '8px' }}>
<div className="form-group">
<label></label>
<CustomSelect
value={systemPromptPreset}
onChange={setSystemPromptPreset}
options={systemPromptPresetOptions}
/>
<div className="form-hint">
使
</div>
</div>
{systemPromptPreset === 'custom' && (
<div className="form-group">
<label></label>
<textarea
className="custom-system-prompt-textarea"
placeholder="例如:你是一名项目经理助手。请优先输出任务清单,按负责人和截止时间分组。"
value={customSystemPrompt}
onChange={(e) => setCustomSystemPrompt(e.target.value)}
rows={8}
/>
<div className="form-hint">
退
</div>
</div>
)}
</div>
{/* 4. 使用统计 */}
{usageStats && (
<>
+6 -2
View File
@@ -143,7 +143,7 @@ function AISummaryWindow() {
try {
// 检查 API 配置 - 使用新的配置服务
const { getAiApiKey, getAiProvider, getAiModel, getAiSummaryDetail, getAiEnableThinking } = await import('../services/config')
const { getAiApiKey, getAiProvider, getAiModel, getAiSummaryDetail, getAiEnableThinking, getAiSystemPromptPreset, getAiCustomSystemPrompt } = await import('../services/config')
const apiKey = await getAiApiKey()
console.log('[AISummaryWindow] 当前 API Key:', apiKey ? '已配置' : '未配置', '长度:', apiKey?.length)
@@ -159,8 +159,10 @@ function AISummaryWindow() {
const model = await getAiModel()
const detail = await getAiSummaryDetail()
const enableThinking = await getAiEnableThinking()
const systemPromptPreset = await getAiSystemPromptPreset()
const customSystemPrompt = await getAiCustomSystemPrompt()
console.log('[AISummaryWindow] 配置信息:', { provider, model, detail, enableThinking })
console.log('[AISummaryWindow] 配置信息:', { provider, model, detail, enableThinking, systemPromptPreset })
// 监听流式输出
let internalThinkMode = false
@@ -225,6 +227,8 @@ function AISummaryWindow() {
apiKey: apiKey as string,
model: model || 'glm-4.5-flash',
detail: detail || 'normal',
systemPromptPreset,
customSystemPrompt,
customRequirement: customRequirement,
sessionName: sessionName,
enableThinking: enableThinking !== false // 默认启用
+12
View File
@@ -132,6 +132,8 @@ function SettingsPage() {
const [aiModel, setAiModelState] = useState('')
const [aiDefaultTimeRange, setAiDefaultTimeRangeState] = useState<number>(7)
const [aiSummaryDetail, setAiSummaryDetailState] = useState<'simple' | 'normal' | 'detailed'>('normal')
const [aiSystemPromptPreset, setAiSystemPromptPresetState] = useState<'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom'>('default')
const [aiCustomSystemPrompt, setAiCustomSystemPromptState] = useState<string>('')
const [aiEnableThinking, setAiEnableThinkingState] = useState<boolean>(true)
const [aiMessageLimit, setAiMessageLimitState] = useState<number>(3000)
@@ -205,6 +207,8 @@ function SettingsPage() {
const savedAiModel = await configService.getAiModel()
const savedAiDefaultTimeRange = await configService.getAiDefaultTimeRange()
const savedAiSummaryDetail = await configService.getAiSummaryDetail()
const savedAiSystemPromptPreset = await configService.getAiSystemPromptPreset()
const savedAiCustomSystemPrompt = await configService.getAiCustomSystemPrompt()
const savedAiEnableThinking = await configService.getAiEnableThinking()
const savedAiMessageLimit = await configService.getAiMessageLimit()
@@ -213,6 +217,8 @@ function SettingsPage() {
setAiModelState(savedAiModel)
setAiDefaultTimeRangeState(savedAiDefaultTimeRange)
setAiSummaryDetailState(savedAiSummaryDetail)
setAiSystemPromptPresetState(savedAiSystemPromptPreset)
setAiCustomSystemPromptState(savedAiCustomSystemPrompt)
setAiEnableThinkingState(savedAiEnableThinking)
setAiMessageLimitState(savedAiMessageLimit)
} catch (e) {
@@ -722,6 +728,8 @@ function SettingsPage() {
await configService.setAiModel(aiModel)
await configService.setAiDefaultTimeRange(aiDefaultTimeRange)
await configService.setAiSummaryDetail(aiSummaryDetail)
await configService.setAiSystemPromptPreset(aiSystemPromptPreset)
await configService.setAiCustomSystemPrompt(aiCustomSystemPrompt)
await configService.setAiEnableThinking(aiEnableThinking)
await configService.setAiMessageLimit(aiMessageLimit)
@@ -2593,6 +2601,10 @@ function SettingsPage() {
setDefaultTimeRange={setAiDefaultTimeRangeState}
summaryDetail={aiSummaryDetail}
setSummaryDetail={setAiSummaryDetailState}
systemPromptPreset={aiSystemPromptPreset}
setSystemPromptPreset={setAiSystemPromptPresetState}
customSystemPrompt={aiCustomSystemPrompt}
setCustomSystemPrompt={setAiCustomSystemPromptState}
enableThinking={aiEnableThinking}
setEnableThinking={setAiEnableThinkingState}
messageLimit={aiMessageLimit}
+35 -3
View File
@@ -342,7 +342,15 @@ export async function setAiProvider(provider: string): Promise<void> {
export async function getAiProviderConfig(providerId: string): Promise<{ apiKey: string; model: string; baseURL?: string } | null> {
const configs = await config.get('aiProviderConfigs')
const allConfigs = (configs as any) || {}
return allConfigs[providerId] || null
const providerConfig = allConfigs[providerId]
if (!providerConfig) return null
// 兼容旧字段 baseUrl
if (!providerConfig.baseURL && providerConfig.baseUrl) {
providerConfig.baseURL = providerConfig.baseUrl
}
return providerConfig
}
// 设置指定提供商的配置
@@ -372,7 +380,8 @@ export async function setAiApiKey(key: string): Promise<void> {
const existingConfig = await getAiProviderConfig(currentProvider)
await setAiProviderConfig(currentProvider, {
apiKey: key,
model: existingConfig?.model || ''
model: existingConfig?.model || '',
baseURL: existingConfig?.baseURL
})
}
@@ -389,7 +398,8 @@ export async function setAiModel(model: string): Promise<void> {
const existingConfig = await getAiProviderConfig(currentProvider)
await setAiProviderConfig(currentProvider, {
apiKey: existingConfig?.apiKey || '',
model: model
model: model,
baseURL: existingConfig?.baseURL
})
}
@@ -415,6 +425,28 @@ export async function setAiSummaryDetail(detail: 'simple' | 'normal' | 'detailed
await config.set('aiSummaryDetail', detail)
}
// 获取系统提示词模板
export async function getAiSystemPromptPreset(): Promise<'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom'> {
const value = await config.get('aiSystemPromptPreset')
return (value as 'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom') || 'default'
}
// 设置系统提示词模板
export async function setAiSystemPromptPreset(preset: 'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom'): Promise<void> {
await config.set('aiSystemPromptPreset', preset)
}
// 获取自定义系统提示词
export async function getAiCustomSystemPrompt(): Promise<string> {
const value = await config.get('aiCustomSystemPrompt')
return (value as string) || ''
}
// 设置自定义系统提示词
export async function setAiCustomSystemPrompt(prompt: string): Promise<void> {
await config.set('aiCustomSystemPrompt', prompt || '')
}
// 获取是否启用思考模式
export async function getAiEnableThinking(): Promise<boolean> {
const value = await config.get('aiEnableThinking')
+8 -1
View File
@@ -1,6 +1,6 @@
import { create } from 'zustand'
export type ThemeId = 'cloud-dancer' | 'corundum-blue' | 'kiwi-green' | 'spicy-red' | 'teal-water' | 'new-year'
export type ThemeId = 'cloud-dancer' | 'corundum-blue' | 'kiwi-green' | 'spicy-red' | 'teal-water' | 'new-year' | 'sakura-mist'
export type ThemeMode = 'light' | 'dark' | 'system'
export type AppIcon = 'default' | 'xinnian'
@@ -54,6 +54,13 @@ export const themes: ThemeInfo[] = [
description: 'Happy New Year 2026',
primaryColor: '#E60012',
bgColor: '#FFF0F0'
},
{
id: 'sakura-mist',
name: '樱雾粉',
description: '温柔、治愈的高级粉',
primaryColor: '#D86A8A',
bgColor: '#FFF2F7'
}
]
+40 -1
View File
@@ -164,6 +164,26 @@
--logo-invert: 0;
}
// 樱雾粉主题
[data-theme="sakura-mist"][data-mode="light"],
[data-theme="sakura-mist"]:not([data-mode]) {
--primary: #D86A8A;
--primary-hover: #C55B7A;
--primary-light: rgba(216, 106, 138, 0.12);
--bg-primary: #FFF2F7;
--bg-secondary: rgba(255, 255, 255, 0.82);
--bg-tertiary: rgba(216, 106, 138, 0.05);
--bg-hover: rgba(216, 106, 138, 0.08);
--text-primary: #4B2D38;
--text-secondary: #7A5865;
--text-tertiary: #A78492;
--border-color: rgba(216, 106, 138, 0.16);
--bg-gradient: linear-gradient(135deg, #FFF2F7 0%, #FFE6F0 100%);
--primary-gradient: linear-gradient(135deg, #D86A8A 0%, #F08FB1 100%);
--card-bg: rgba(255, 255, 255, 0.82);
--logo-invert: 0;
}
// ==================== 深色主题 ====================
// 云上舞白 - 深色
@@ -280,6 +300,25 @@
--logo-invert: 1;
}
// 樱雾粉 - 深色
[data-theme="sakura-mist"][data-mode="dark"] {
--primary: #F08FB1;
--primary-hover: #F6A3C0;
--primary-light: rgba(240, 143, 177, 0.18);
--bg-primary: #24161D;
--bg-secondary: rgba(44, 30, 38, 0.92);
--bg-tertiary: rgba(255, 255, 255, 0.06);
--bg-hover: rgba(255, 255, 255, 0.1);
--text-primary: #FFEAF2;
--text-secondary: #DDBAC8;
--text-tertiary: #AC8796;
--border-color: rgba(255, 255, 255, 0.12);
--bg-gradient: linear-gradient(135deg, #24161D 0%, #34212A 100%);
--primary-gradient: linear-gradient(135deg, #D86A8A 0%, #F08FB1 100%);
--card-bg: rgba(44, 30, 38, 0.92);
--logo-invert: 1;
}
// 重置样式
* {
margin: 0;
@@ -384,4 +423,4 @@ img {
&:hover {
text-decoration: underline;
}
}
}
+2
View File
@@ -780,6 +780,8 @@ export interface ElectronAPI {
apiKey: string
model: string
detail: 'simple' | 'normal' | 'detailed'
systemPromptPreset?: 'default' | 'decision-focus' | 'action-focus' | 'risk-focus' | 'custom'
customSystemPrompt?: string
customRequirement?: string
sessionName?: string
enableThinking?: boolean