Skip to content

Commit c95b69d

Browse files
committed
新增:在提示词组件中引入提示词库数据,优化提示词库的动态更新逻辑,支持从父组件传递数据
1 parent 2b6d845 commit c95b69d

4 files changed

Lines changed: 162 additions & 129 deletions

File tree

frontend/src/components/PromptBadges.vue

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
</div>
2626

2727
<!-- 提示词库 -->
28-
<PromptLibrary @select-prompt="addPromptFromLibrary" />
28+
<PromptLibrary
29+
:promptLibraryData="promptLibraryData"
30+
@select-prompt="addPromptFromLibrary"
31+
/>
2932

3033
<!-- 已拆分的提示词badges -->
3134
<div class="mb-4">
@@ -138,7 +141,15 @@ export default defineComponent({
138141
PromptLibrary
139142
},
140143
141-
setup() {
144+
props: {
145+
promptLibraryData: {
146+
type: Array as () => PromptLibraryItem[],
147+
default: () => [],
148+
required: true
149+
}
150+
},
151+
152+
setup(props) {
142153
// 提示词列表
143154
const prompts = ref<PromptData[]>([]);
144155
let sortableInstance: Sortable | null = null;
@@ -147,6 +158,32 @@ export default defineComponent({
147158
const isTranslating = ref(false); // 全局翻译状态
148159
let translateTimer: number | null = null; // 翻译防抖定时器
149160
161+
// 提示词库数据
162+
const promptLibrary = ref<PromptLibraryItem[]>(props.promptLibraryData);
163+
164+
// 监听提示词库数据变化
165+
watch(() => props.promptLibraryData, (newData) => {
166+
console.log('[PromptBadges] 提示词库数据更新:', newData.length);
167+
promptLibrary.value = newData;
168+
169+
// 如果当前有正在编辑的提示词,尝试更新它们的翻译
170+
if (prompts.value.length > 0) {
171+
prompts.value.forEach((prompt, index) => {
172+
// 查找匹配的库中提示词
173+
const matchingPrompt = newData.find(p => p.text === prompt.text);
174+
if (matchingPrompt) {
175+
// 更新翻译
176+
prompts.value[index] = {
177+
...prompt,
178+
chinese: matchingPrompt.chinese,
179+
english: matchingPrompt.english,
180+
isTranslating: false
181+
};
182+
}
183+
});
184+
}
185+
}, { deep: true, immediate: true });
186+
150187
// 计算属性:将提示词转换为文本
151188
const promptInput = computed({
152189
get: () => {
@@ -270,47 +307,7 @@ export default defineComponent({
270307
return promptData;
271308
};
272309
273-
// 翻译单个提示词
274-
const translatePrompt = async (prompt: PromptData, index: number) => {
275-
if (!prompt.isTranslating) return prompt;
276-
277-
const isEnglish = /^[a-zA-Z0-9\s\-_,.]+$/.test(prompt.text);
278-
console.log(`[开始翻译] 索引: ${index}, 文本: "${prompt.text}", 方向: ${isEnglish ? '英->中' : '中->英'}`);
279-
280-
try {
281-
const result = await PromptsAPI.translateText(
282-
prompt.text,
283-
!isEnglish // 中文->英文 或 英文->中文
284-
);
285-
286-
if (result && result.translated) {
287-
if (isEnglish) {
288-
prompt.chinese = result.translated;
289-
} else {
290-
prompt.english = result.translated;
291-
}
292-
prompt.isTranslating = false;
293-
294-
console.log(`[翻译成功] 文本: "${prompt.text}" -> "${result.translated}"`);
295-
296-
// 更新提示词列表中的数据
297-
const updatedPrompts = [...prompts.value];
298-
updatedPrompts[index] = prompt;
299-
prompts.value = updatedPrompts;
300-
}
301-
} catch (error) {
302-
console.error(`[翻译失败] 文本: "${prompt.text}", 错误:`, error);
303-
if (/^[a-zA-Z0-9\s\-_,.]+$/.test(prompt.text)) {
304-
prompt.chinese = '翻译失败';
305-
} else {
306-
prompt.english = '翻译失败';
307-
}
308-
prompt.isTranslating = false;
309-
}
310-
311-
return prompt;
312-
};
313-
310+
314311
// 批量翻译提示词
315312
const batchTranslatePrompts = async (promptsToTranslate: PromptData[]) => {
316313
if (promptsToTranslate.length === 0) return;
@@ -534,6 +531,14 @@ export default defineComponent({
534531
}, 10);
535532
};
536533
534+
// 从提示词库中查找匹配的提示词
535+
const findMatchingPrompts = (text: string) => {
536+
return promptLibrary.value.filter(item => {
537+
const regex = new RegExp(`\\b${item.text}\\b`, 'i');
538+
return regex.test(text);
539+
});
540+
};
541+
537542
// 组件挂载后初始化
538543
onMounted(() => {
539544
// 初始化拖拽排序
@@ -561,7 +566,8 @@ export default defineComponent({
561566
isTranslating,
562567
handleCommaPress,
563568
translateTimer,
564-
addPromptFromLibrary
569+
addPromptFromLibrary,
570+
findMatchingPrompts
565571
};
566572
}
567573
});

frontend/src/components/PromptLibrary.vue

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,36 @@
6969
</template>
7070

7171
<script lang="ts">
72-
import { defineComponent, ref, computed, onMounted } from 'vue';
73-
import { PromptsAPI } from '../api/prompts';
72+
import { defineComponent, ref, computed, onMounted, watch } from 'vue';
7473
import type { PromptLibraryItem } from '../api/prompts';
7574
7675
export default defineComponent({
7776
name: 'PromptLibrary',
7877
7978
emits: ['select-prompt'],
8079
80+
props: {
81+
promptLibraryData: {
82+
type: Array as () => PromptLibraryItem[],
83+
default: () => [],
84+
required: true
85+
}
86+
},
87+
8188
setup(props, { emit }) {
8289
// 提示词库相关
83-
const promptLibrary = ref<PromptLibraryItem[]>([]);
90+
const promptLibrary = ref<PromptLibraryItem[]>(props.promptLibraryData);
8491
const selectedCategory = ref('');
8592
const selectedSubCategory = ref('');
8693
const isLoading = ref(false);
8794
const errorMessage = ref('');
8895
96+
// 监听提示词库数据变化
97+
watch(() => props.promptLibraryData, (newData) => {
98+
console.log('[PromptLibrary] 提示词库数据更新:', newData.length);
99+
promptLibrary.value = newData;
100+
}, { deep: true, immediate: true });
101+
89102
// 一级分类列表
90103
const categories = computed(() => {
91104
const categorySet = new Set(promptLibrary.value.map(item => item.category));
@@ -131,50 +144,11 @@ export default defineComponent({
131144
isLoading.value = true;
132145
errorMessage.value = '';
133146
134-
// 从后端获取提示词库
135-
const data = await PromptsAPI.getPromptLibrary();
136-
promptLibrary.value = data;
137-
138-
console.log('[提示词库] 加载成功,数量:', data.length);
147+
// 数据现在从父组件传入,不需要再调用API
148+
console.log('[提示词库] 从父组件加载数据,数量:', promptLibrary.value.length);
139149
} catch (error) {
140150
console.error('加载提示词库失败:', error);
141151
errorMessage.value = '加载提示词库失败,请刷新页面重试';
142-
143-
// 加载失败时使用示例数据
144-
promptLibrary.value = [
145-
{
146-
id: '1',
147-
text: '写实风格',
148-
chinese: '写实风格',
149-
english: 'realistic style',
150-
category: '风格',
151-
subCategory: '基础风格'
152-
},
153-
{
154-
id: '2',
155-
text: '水彩画',
156-
chinese: '水彩画',
157-
english: 'watercolor',
158-
category: '风格',
159-
subCategory: '绘画媒介'
160-
},
161-
{
162-
id: '3',
163-
text: '高清',
164-
chinese: '高清',
165-
english: 'high resolution',
166-
category: '质量',
167-
subCategory: '分辨率'
168-
},
169-
{
170-
id: '4',
171-
text: 'masterpiece',
172-
chinese: '杰作',
173-
english: 'masterpiece',
174-
category: '质量',
175-
subCategory: '通用'
176-
}
177-
];
178152
} finally {
179153
isLoading.value = false;
180154
}

frontend/src/components/PromptLibraryEditor.vue

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ export default defineComponent({
143143
promptLibraryData: {
144144
type: Array as () => PromptLibraryItem[],
145145
default: () => []
146+
},
147+
selectedPrompt: {
148+
type: Object as () => PromptLibraryItem | null,
149+
default: null
146150
}
147151
},
148152
@@ -158,10 +162,6 @@ export default defineComponent({
158162
const isSaving = ref(false);
159163
const errorMessage = ref('');
160164
161-
// 本地新增的分类 (尚未保存到服务器的)
162-
const localCategories = ref<string[]>([]);
163-
const localSubCategories = ref<{[category: string]: string[]}>({});
164-
165165
// 新提示词数据
166166
const newPrompt = ref<NewPromptData>({
167167
text: '',
@@ -173,12 +173,8 @@ export default defineComponent({
173173
174174
// 一级分类列表
175175
const categories = computed(() => {
176-
// 获取已有分类
177-
const categorySet = new Set([
178-
...props.promptLibraryData.map(item => item.category),
179-
...localCategories.value
180-
]);
181-
176+
// 直接从props中获取分类
177+
const categorySet = new Set(props.promptLibraryData.map(item => item.category));
182178
return Array.from(categorySet).sort();
183179
});
184180
@@ -195,10 +191,6 @@ export default defineComponent({
195191
filteredItems.forEach(item => {
196192
if (item.subCategory) subCategorySet.add(item.subCategory);
197193
});
198-
199-
// 加入本地新增的二级分类
200-
const localSubs = localSubCategories.value[newPrompt.value.category] || [];
201-
localSubs.forEach(sub => subCategorySet.add(sub));
202194
}
203195
204196
return Array.from(subCategorySet).sort();
@@ -228,8 +220,6 @@ export default defineComponent({
228220
newCategory.value = '';
229221
newSubCategory.value = '';
230222
errorMessage.value = '';
231-
232-
// 注意:不重置localCategories和localSubCategories,因为需要保留用户创建的分类
233223
};
234224
235225
// 添加新一级分类
@@ -242,9 +232,6 @@ export default defineComponent({
242232
return;
243233
}
244234
245-
// 添加到本地分类列表
246-
localCategories.value.push(newCategory.value.trim());
247-
248235
// 设置新分类
249236
newPrompt.value.category = newCategory.value.trim();
250237
showAddCategory.value = false;
@@ -261,14 +248,6 @@ export default defineComponent({
261248
return;
262249
}
263250
264-
// 初始化分类的子分类数组(如果不存在)
265-
if (!localSubCategories.value[newPrompt.value.category]) {
266-
localSubCategories.value[newPrompt.value.category] = [];
267-
}
268-
269-
// 添加到本地二级分类列表
270-
localSubCategories.value[newPrompt.value.category].push(newSubCategory.value.trim());
271-
272251
// 设置新二级分类
273252
newPrompt.value.subCategory = newSubCategory.value.trim();
274253
showAddSubCategory.value = false;
@@ -319,6 +298,23 @@ export default defineComponent({
319298
}
320299
};
321300
301+
// 监听选中的提示词变化
302+
watch(() => props.selectedPrompt, (selected) => {
303+
if (selected) {
304+
// 判断是否为英文
305+
const isEnglish = /^[a-zA-Z0-9\s\-_,.]+$/.test(selected.text);
306+
307+
// 如果有选中的提示词,填充到表单
308+
newPrompt.value = {
309+
text: selected.text,
310+
translated: isEnglish ? selected.chinese : selected.english,
311+
category: selected.category,
312+
subCategory: selected.subCategory,
313+
isEnglish: isEnglish
314+
};
315+
}
316+
}, { immediate: true });
317+
322318
// 保存到提示词库
323319
const saveToLibrary = async () => {
324320
if (!canSaveToLibrary.value) return;
@@ -335,6 +331,11 @@ export default defineComponent({
335331
subCategory: newPrompt.value.subCategory || '默认' // 未选择时使用默认分类
336332
};
337333
334+
// 如果是在编辑已有提示词,添加ID
335+
if (props.selectedPrompt) {
336+
(newItem as any).id = props.selectedPrompt.id;
337+
}
338+
338339
// 保存到后端
339340
const savedItem = await PromptsAPI.savePromptToLibrary(newItem);
340341
@@ -345,7 +346,7 @@ export default defineComponent({
345346
emit('saved', savedItem);
346347
347348
// 显示成功消息
348-
alert('提示词已成功添加到提示词库');
349+
alert('提示词已成功' + (props.selectedPrompt ? '更新' : '添加') + '到提示词库');
349350
} catch (error) {
350351
console.error('保存提示词失败:', error);
351352
errorMessage.value = '保存提示词失败,请重试';
@@ -377,8 +378,6 @@ export default defineComponent({
377378
subCategories,
378379
canSaveToLibrary,
379380
errorMessage,
380-
localCategories,
381-
localSubCategories,
382381
383382
// 方法
384383
addNewCategory,

0 commit comments

Comments
 (0)