feat: Enhance Kol Generation Service with web search and knowledge group support

- Added `EnableWebSearch` and `KnowledgeGroupIDs` fields to `KolGenerationSubmitRequest`.
- Updated `Submit` method in `KolGenerationService` to handle new request fields.
- Integrated web search and knowledge group validation based on card configuration.
- Introduced caching mechanisms in `KolPackageService`, `KolPromptService`, and `KolSubscriptionAdminService` to improve performance.
- Implemented knowledge context resolution in `KolGenerationWorker` to enrich prompts with relevant knowledge snippets.
- Added utility functions for handling card configuration in both backend and frontend.
- Created tests for knowledge extraction and rendering to ensure accuracy and reliability.
This commit is contained in:
2026-04-18 13:47:32 +08:00
parent 3ef0807456
commit b2605abd6a
27 changed files with 2051 additions and 171 deletions
+49 -1
View File
@@ -29,6 +29,7 @@ const editingPackage = ref<KolPackageSummary | null>(null);
const promptModalOpen = ref(false);
const editingPromptId = ref<number | null>(null);
const togglingPromptId = ref<number | null>(null);
const deletingPromptId = ref<number | null>(null);
const { data: packages, isPending: packagesPending } = useQuery({
queryKey: ["kol", "packages"],
@@ -124,6 +125,28 @@ const togglePromptStatusMutation = useMutation({
},
});
const deletePromptMutation = useMutation({
mutationFn: (id: number) => kolManageApi.deletePrompt(id),
onMutate: (id) => {
deletingPromptId.value = id;
},
onSuccess: (_, id) => {
message.success(t("common.delete") + "成功");
void queryClient.invalidateQueries({ queryKey: ["kol", "packages"] });
void queryClient.invalidateQueries({
queryKey: ["kol", "packages", selectedPackageId.value, "prompts"],
});
void queryClient.invalidateQueries({ queryKey: ["kol", "prompt", id] });
if (editingPromptId.value === id) {
editingPromptId.value = null;
}
},
onError: (error) => message.error(formatError(error)),
onSettled: () => {
deletingPromptId.value = null;
},
});
const packageInitialValue = computed<Partial<CreateKolPackageRequest> | undefined>(() => {
if (!editingPackage.value) return undefined;
return {
@@ -175,6 +198,14 @@ function handleCloseEditor() {
editingPromptId.value = null;
}
function handleDeletePrompt(id: number) {
Modal.confirm({
title: t("common.delete") + "?",
content: "确定要删除这个提示词吗?",
onOk: () => deletePromptMutation.mutate(id),
});
}
function promptStatusLabel(status: string) {
if (status === "active") return t("kol.manage.status.active");
if (status === "archived") return t("kol.manage.status.archived");
@@ -268,7 +299,7 @@ function promptStatusLabel(status: string) {
{ title: t('common.title'), dataIndex: 'name', key: 'name' },
{ title: t('tracking.columns.platform'), dataIndex: 'platform_hint', key: 'platform_hint' },
{ title: t('common.status'), dataIndex: 'status', key: 'status' },
{ title: t('common.actions'), key: 'actions', align: 'right', width: 112 },
{ title: t('common.actions'), key: 'actions', align: 'right', width: 156 },
]"
:data-source="prompts"
:loading="promptsPending"
@@ -318,6 +349,18 @@ function promptStatusLabel(status: string) {
<PlayCircleOutlined v-else />
</a-button>
</a-tooltip>
<a-tooltip :title="t('common.delete')">
<a-button
type="text"
shape="circle"
size="small"
class="action-btn action-delete"
:loading="deletePromptMutation.isPending.value && deletingPromptId === record.id"
@click="handleDeletePrompt(record.id)"
>
<DeleteOutlined />
</a-button>
</a-tooltip>
</div>
</template>
</template>
@@ -467,4 +510,9 @@ function promptStatusLabel(status: string) {
color: #fa8c16;
background: #fff7e6;
}
.action-delete.ant-btn:hover:not(:disabled) {
color: #ff4d4f;
background: #fff1f0;
}
</style>