Skip to content

Commit 39aff84

Browse files
committed
新增ai过滤功能
1 parent a56d833 commit 39aff84

File tree

9 files changed

+1171
-14
lines changed

9 files changed

+1171
-14
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<template>
2+
<div class="space-y-4">
3+
<!-- 过滤开关 -->
4+
<div class="flex items-center gap-2">
5+
<ToggleSwitch
6+
:modelValue="modelValue?.enable"
7+
@update:modelValue="handleEnableChange"
8+
inputId="filter-enable-switch" />
9+
<label for="filter-enable-switch" class="text-sm text-gray-600 cursor-pointer">
10+
启用信息过滤
11+
</label>
12+
</div>
13+
14+
<!-- 过滤配置详情 -->
15+
<div v-if="modelValue?.enable" class="border rounded-lg p-4 space-y-4">
16+
<!-- 过滤类型选择 -->
17+
<div>
18+
<label class="block text-sm font-medium mb-2">过滤类型</label>
19+
<div class="flex gap-4">
20+
<div class="flex items-center gap-2">
21+
<RadioButton
22+
:modelValue="modelValue?.filterType"
23+
value="js"
24+
inputId="js-filter-type"
25+
@update:modelValue="handleFilterTypeChange" />
26+
<label for="js-filter-type">JavaScript 过滤</label>
27+
</div>
28+
<div class="flex items-center gap-2">
29+
<RadioButton
30+
:modelValue="modelValue?.filterType"
31+
value="ai"
32+
inputId="ai-filter-type"
33+
@update:modelValue="handleFilterTypeChange" />
34+
<label for="ai-filter-type">AI 过滤</label>
35+
</div>
36+
</div>
37+
</div>
38+
39+
<!-- JavaScript 过滤配置 -->
40+
<div v-if="modelValue?.filterType === 'js'">
41+
<label class="block text-sm font-medium mb-2">JavaScript 过滤代码</label>
42+
<Textarea
43+
:modelValue="modelValue?.jsFilter?.code"
44+
@update:modelValue="handleJsCodeChange"
45+
placeholder="// 编写过滤函数,接收数据项作为参数,返回 true 表示保留,false 表示过滤
46+
// 参数: item (单个数据项)
47+
// 返回: boolean (true: 保留, false: 过滤)
48+
function filterItem(item) {
49+
// 示例:只保留包含特定关键词的项
50+
return item.title && item.title.includes('重要');
51+
}"
52+
rows="6"
53+
class="w-full font-mono text-sm" />
54+
<small class="text-gray-500">
55+
编写一个过滤函数,函数接收一个数据项作为参数,返回 true 表示保留该项,false 表示过滤掉该项。
56+
函数名为 filterItem,可以使用 JavaScript 的所有特性。
57+
</small>
58+
</div>
59+
60+
<!-- AI 过滤配置 -->
61+
<div v-if="modelValue?.filterType === 'ai'" class="space-y-4">
62+
<div>
63+
<label class="block text-sm font-medium mb-2">AI 模型</label>
64+
<InputText
65+
:modelValue="modelValue?.aiFilter?.model"
66+
@update:modelValue="handleAiModelChange"
67+
placeholder="例如: qwen2.5:7b, llama3.2:3b"
68+
class="w-full" />
69+
</div>
70+
71+
<div>
72+
<label class="block text-sm font-medium mb-2">过滤提示词</label>
73+
<Textarea
74+
:modelValue="modelValue?.aiFilter?.prompt"
75+
@update:modelValue="handleAiPromptChange"
76+
placeholder="请判断以下内容是否值得保留,请从重要性和相关性角度考虑..."
77+
rows="4"
78+
class="w-full" />
79+
<small class="text-gray-500">
80+
编写用于判断内容是否值得保留的提示词,AI 将根据此提示词对每个数据项进行判断。
81+
让ai回答 "pass" 则会保留对应的数据项
82+
</small>
83+
</div>
84+
85+
<div>
86+
<label class="block text-sm font-medium mb-2">Ollama 服务地址</label>
87+
对于本地的ollama服务,需要配置允许浏览器扩展访问的环境变量:https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-allow-additional-web-origins-to-access-ollama
88+
<InputText
89+
:modelValue="modelValue?.aiFilter?.ollamaUrl"
90+
@update:modelValue="handleAiUrlChange"
91+
placeholder="例如: http://localhost:11434"
92+
class="w-full" />
93+
</div>
94+
</div>
95+
</div>
96+
</div>
97+
</template>
98+
99+
<script setup lang="ts">
100+
import type { FilterConfig } from '@/entrypoints/background/service/dbService';
101+
import { InputText, RadioButton, Textarea, ToggleSwitch } from 'primevue'
102+
103+
interface Props {
104+
modelValue?: FilterConfig;
105+
}
106+
107+
interface Emits {
108+
(e: 'update:modelValue', value: FilterConfig): void;
109+
}
110+
111+
const props = withDefaults(defineProps<Props>(), {
112+
modelValue: undefined,
113+
});
114+
115+
const emit = defineEmits<Emits>();
116+
117+
// 确保配置对象存在
118+
const ensureConfig = (): FilterConfig => {
119+
const current = props.modelValue;
120+
if (!current) {
121+
return {
122+
enable: false,
123+
filterType: 'js',
124+
jsFilter: { code: '' },
125+
aiFilter: { model: '', prompt: '', ollamaUrl: '' },
126+
};
127+
}
128+
129+
// 确保所有必需的子属性都存在
130+
return {
131+
...current,
132+
filterType: current.filterType || 'js',
133+
jsFilter: current.jsFilter || { code: '' },
134+
aiFilter: current.aiFilter || { model: '', prompt: '', ollamaUrl: '' },
135+
};
136+
};
137+
138+
// 处理启用/禁用变化
139+
const handleEnableChange = (enabled: boolean) => {
140+
const config = ensureConfig();
141+
emit('update:modelValue', { ...config, enable: enabled });
142+
};
143+
144+
// 处理过滤类型变化
145+
const handleFilterTypeChange = (filterType: 'js' | 'ai') => {
146+
const config = ensureConfig();
147+
emit('update:modelValue', { ...config, filterType });
148+
};
149+
150+
// 处理 JS 代码变化
151+
const handleJsCodeChange = (code: string | undefined) => {
152+
const config = ensureConfig();
153+
emit('update:modelValue', {
154+
...config,
155+
jsFilter: { ...config.jsFilter, code: code || '' },
156+
});
157+
};
158+
159+
// 处理 AI 模型变化
160+
const handleAiModelChange = (model: string | undefined) => {
161+
const config = ensureConfig();
162+
emit('update:modelValue', {
163+
...config,
164+
aiFilter: {
165+
model: model || '',
166+
prompt: config.aiFilter?.prompt || '',
167+
ollamaUrl: config.aiFilter?.ollamaUrl || ''
168+
},
169+
});
170+
};
171+
172+
// 处理 AI 提示词变化
173+
const handleAiPromptChange = (prompt: string | undefined) => {
174+
const config = ensureConfig();
175+
emit('update:modelValue', {
176+
...config,
177+
aiFilter: {
178+
model: config.aiFilter?.model || '',
179+
prompt: prompt || '',
180+
ollamaUrl: config.aiFilter?.ollamaUrl || ''
181+
},
182+
});
183+
};
184+
185+
// 处理 AI URL 变化
186+
const handleAiUrlChange = (url: string | undefined) => {
187+
const config = ensureConfig();
188+
emit('update:modelValue', {
189+
...config,
190+
aiFilter: {
191+
model: config.aiFilter?.model || '',
192+
prompt: config.aiFilter?.prompt || '',
193+
ollamaUrl: url || ''
194+
},
195+
});
196+
};
197+
</script>

0 commit comments

Comments
 (0)