Skip to content

Commit bfa16a3

Browse files
committed
新增:实现提示词库功能,包括提示词的创建、读取、更新和删除,集成相关API,更新前端组件和页面布局
1 parent 85cb198 commit bfa16a3

8 files changed

Lines changed: 954 additions & 115 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,6 @@ models_info.json
7171

7272
static/images/
7373

74-
version_info.txt
74+
version_info.txt
75+
76+
data/

frontend/src/api/prompts.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ export interface TranslationResult {
6060
translated: string;
6161
}
6262

63+
// 提示词库项目接口
64+
export interface PromptLibraryItem {
65+
id: string;
66+
text: string;
67+
chinese: string;
68+
english: string;
69+
category: string;
70+
subCategory: string;
71+
}
72+
73+
// 创建提示词库项目请求参数
74+
export interface CreatePromptLibraryItemParams {
75+
text: string;
76+
chinese: string;
77+
english: string;
78+
category: string;
79+
subCategory: string;
80+
}
81+
6382
// 提示词API服务
6483
export const PromptsAPI = {
6584
// 获取所有提示词
@@ -131,5 +150,30 @@ export const PromptsAPI = {
131150
params: { to_english: toEnglish }
132151
});
133152
return response.data.results;
153+
},
154+
155+
// 提示词库相关API
156+
157+
// 获取提示词库列表
158+
getPromptLibrary: async (): Promise<PromptLibraryItem[]> => {
159+
const response = await apiClient.get('/prompt-library');
160+
return response.data.items;
161+
},
162+
163+
// 保存提示词到库
164+
savePromptToLibrary: async (item: CreatePromptLibraryItemParams): Promise<PromptLibraryItem> => {
165+
const response = await apiClient.post('/prompt-library', item);
166+
return response.data;
167+
},
168+
169+
// 更新提示词库项目
170+
updatePromptLibraryItem: async (id: string, item: Partial<CreatePromptLibraryItemParams>): Promise<PromptLibraryItem> => {
171+
const response = await apiClient.put(`/prompt-library/${id}`, item);
172+
return response.data;
173+
},
174+
175+
// 删除提示词库项目
176+
deletePromptLibraryItem: async (id: string): Promise<void> => {
177+
await apiClient.delete(`/prompt-library/${id}`);
134178
}
135179
};

frontend/src/components/PromptBadges.vue

Lines changed: 42 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,8 @@
2424
</div>
2525
</div>
2626

27-
<!-- 示例提示词 -->
28-
<div class="mb-4">
29-
<label class="block text-sm font-medium mb-2">示例提示词</label>
30-
<div class="flex flex-wrap gap-2">
31-
<button
32-
v-for="(category, index) in exampleCategories"
33-
:key="index"
34-
class="btn btn-sm btn-outline"
35-
@click="loadExamplePrompts(category.id)"
36-
:disabled="isTranslating"
37-
>
38-
{{ category.name }}
39-
</button>
40-
</div>
41-
</div>
27+
<!-- 提示词库 -->
28+
<PromptLibrary @select-prompt="addPromptFromLibrary" />
4229

4330
<!-- 已拆分的提示词badges -->
4431
<div class="mb-4">
@@ -89,9 +76,11 @@
8976
</template>
9077

9178
<script lang="ts">
92-
import { defineComponent, ref, onMounted, nextTick, computed, onBeforeUnmount } from 'vue';
79+
import { defineComponent, ref, onMounted, nextTick, computed, onBeforeUnmount, watch } from 'vue';
9380
import Sortable from 'sortablejs';
9481
import { PromptsAPI } from '../api/prompts'; // 导入API
82+
import type { PromptLibraryItem } from '../api/prompts'; // 从API文件导入类型
83+
import PromptLibrary from './PromptLibrary.vue'; // 导入提示词库组件
9584
9685
// 提示词数据结构
9786
interface PromptData {
@@ -101,42 +90,6 @@ interface PromptData {
10190
isTranslating?: boolean; // 是否正在翻译
10291
}
10392
104-
// 示例提示词数据
105-
interface ExampleCategory {
106-
id: string;
107-
name: string;
108-
prompts: string[];
109-
}
110-
111-
// 各类示例提示词
112-
const examplePromptsData: Record<string, ExampleCategory> = {
113-
style: {
114-
id: 'style',
115-
name: '风格类',
116-
prompts: ['写实风格', '动漫风格', '水彩画', '油画', '素描', '赛博朋克', '未来主义', '极简主义']
117-
},
118-
quality: {
119-
id: 'quality',
120-
name: '质量类',
121-
prompts: ['高清', '8K', '高质量', '细节丰富', '精细', 'masterpiece', 'best quality', 'ultra detailed']
122-
},
123-
scene: {
124-
id: 'scene',
125-
name: '场景类',
126-
prompts: ['夜景', '黎明', '黄昏', '雨天', '雪景', '海边', '森林', '城市', '星空']
127-
},
128-
camera: {
129-
id: 'camera',
130-
name: '相机参数',
131-
prompts: ['广角镜头', '长焦镜头', '鱼眼镜头', '微距', '景深', '散景', '低角度', '航拍']
132-
},
133-
lighting: {
134-
id: 'lighting',
135-
name: '光照类',
136-
prompts: ['逆光', '侧光', '柔光', '硬光', '聚光', '霓虹灯', '金色光芒', '蓝色调']
137-
}
138-
};
139-
14093
// 简单的中英文映射字典
14194
const translationMap: Record<string, string> = {
14295
'写实风格': 'realistic style',
@@ -181,10 +134,13 @@ const translationMap: Record<string, string> = {
181134
export default defineComponent({
182135
name: 'PromptBadges',
183136
137+
components: {
138+
PromptLibrary
139+
},
140+
184141
setup() {
185142
// 提示词列表
186143
const prompts = ref<PromptData[]>([]);
187-
const exampleCategories = ref<ExampleCategory[]>(Object.values(examplePromptsData));
188144
let sortableInstance: Sortable | null = null;
189145
let isUpdatingFromTextarea = false; // 标记是否从文本框更新,避免循环
190146
const rawInputValue = ref(''); // 保存原始输入值,解决末尾逗号问题
@@ -449,62 +405,36 @@ export default defineComponent({
449405
}, 0);
450406
};
451407
452-
// 加载示例提示词
453-
const loadExamplePrompts = (categoryId: string) => {
454-
const category = examplePromptsData[categoryId];
455-
if (category) {
456-
// 将字符串转换为PromptData对象
457-
const promptDataList = category.prompts.map(createPromptData);
458-
459-
// 如果已有提示词,询问是否替换
460-
if (prompts.value.length > 0) {
461-
if (confirm('是否要替换当前的提示词列表?点击确定替换,点击取消则添加到现有列表')) {
462-
// 替换现有列表
463-
prompts.value = [...promptDataList];
464-
// 更新输入框,但不触发计算属性的set方法
465-
isUpdatingFromTextarea = true;
466-
rawInputValue.value = promptDataList.map(p => p.text).join(', ');
467-
setTimeout(() => {
468-
isUpdatingFromTextarea = false;
469-
}, 0);
470-
} else {
471-
// 添加到现有列表,避免重复
472-
const currentTexts = prompts.value.map(p => p.text);
473-
const newPrompts = promptDataList.filter(p => !currentTexts.includes(p.text));
474-
475-
if (newPrompts.length > 0) {
476-
prompts.value = [...prompts.value, ...newPrompts];
477-
478-
// 更新输入框,但不触发计算属性的set方法
479-
isUpdatingFromTextarea = true;
480-
rawInputValue.value = prompts.value.map(p => p.text).join(', ');
481-
setTimeout(() => {
482-
isUpdatingFromTextarea = false;
483-
}, 0);
484-
}
485-
}
486-
} else {
487-
prompts.value = [...promptDataList];
488-
489-
// 更新输入框,但不触发计算属性的set方法
490-
isUpdatingFromTextarea = true;
491-
rawInputValue.value = promptDataList.map(p => p.text).join(', ');
492-
setTimeout(() => {
493-
isUpdatingFromTextarea = false;
494-
}, 0);
495-
}
496-
497-
// 重新初始化拖拽排序
498-
nextTick(() => {
499-
initSortable();
500-
501-
// 批量翻译需要翻译的提示词
502-
const needTranslation = promptDataList.filter(p => p.isTranslating);
503-
if (needTranslation.length > 0) {
504-
batchTranslatePrompts(prompts.value);
505-
}
506-
});
408+
// 从提示词库添加提示词
409+
const addPromptFromLibrary = (libraryItem: PromptLibraryItem) => {
410+
// 检查是否已存在
411+
const exists = prompts.value.some(p => p.text === libraryItem.text);
412+
if (exists) {
413+
return; // 已存在则不添加
507414
}
415+
416+
// 创建新提示词对象
417+
const newPromptData: PromptData = {
418+
text: libraryItem.text,
419+
chinese: libraryItem.chinese,
420+
english: libraryItem.english,
421+
isTranslating: false // 直接使用库中的翻译,不需要翻译
422+
};
423+
424+
// 添加到提示词列表
425+
prompts.value.push(newPromptData);
426+
427+
// 更新输入框
428+
isUpdatingFromTextarea = true;
429+
rawInputValue.value = prompts.value.map(p => p.text).join(', ');
430+
setTimeout(() => {
431+
isUpdatingFromTextarea = false;
432+
}, 0);
433+
434+
// 重新初始化拖拽排序
435+
nextTick(() => {
436+
initSortable();
437+
});
508438
};
509439
510440
// 初始化Sortable.js
@@ -604,8 +534,9 @@ export default defineComponent({
604534
}, 10);
605535
};
606536
607-
// 组件挂载后初始化Sortable.js
537+
// 组件挂载后初始化
608538
onMounted(() => {
539+
// 初始化拖拽排序
609540
nextTick(() => {
610541
if (prompts.value.length > 0) {
611542
initSortable();
@@ -624,14 +555,13 @@ export default defineComponent({
624555
return {
625556
promptInput,
626557
prompts,
627-
exampleCategories,
628558
removePrompt,
629-
loadExamplePrompts,
630559
copyToClipboard,
631560
clearAll,
632561
isTranslating,
633562
handleCommaPress,
634-
translateTimer
563+
translateTimer,
564+
addPromptFromLibrary
635565
};
636566
}
637567
});

0 commit comments

Comments
 (0)