feat: add knowledge management functionality with CRUD operations and database schema
- Implemented KnowledgeHandler for managing knowledge groups and items, including listing, creating, updating, and deleting operations. - Added database migration scripts to create necessary tables for knowledge management, including knowledge_groups, knowledge_items, knowledge_parse_tasks, and knowledge_chunks_meta. - Introduced prompt_rule_knowledge_groups table to associate prompt rules with knowledge groups.
This commit is contained in:
@@ -19,6 +19,7 @@ import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
import KnowledgeGroupSelect from "@/components/KnowledgeGroupSelect.vue";
|
||||
import { articlesApi, brandsApi, normalizeInputParams, templatesApi } from "@/lib/api";
|
||||
import { formatError } from "@/lib/errors";
|
||||
import { getTemplateMeta } from "@/lib/display";
|
||||
@@ -170,6 +171,7 @@ const selectedTitle = ref("");
|
||||
const customTitle = ref("");
|
||||
const reviewIntroHook = ref("");
|
||||
const keyPoints = ref("");
|
||||
const selectedKnowledgeGroupIds = ref<number[]>([]);
|
||||
const outlineSections = ref<string[]>([]);
|
||||
const customOutlineSections = ref<ResolvedOutlineOption[]>([]);
|
||||
const outlineOptionOrder = ref<string[]>([]);
|
||||
@@ -424,6 +426,7 @@ function resetWizardState(detail: NonNullable<typeof templateDetail.value>): voi
|
||||
customTitle.value = "";
|
||||
reviewIntroHook.value = "";
|
||||
keyPoints.value = "";
|
||||
selectedKnowledgeGroupIds.value = [];
|
||||
customOutlineSections.value = [];
|
||||
customOutlineInput.value = "";
|
||||
generatedOutline.value = [];
|
||||
@@ -481,6 +484,7 @@ function applyDraftArticleState(detail: ArticleDetail): void {
|
||||
customTitle.value = stringFromUnknown(draftState.custom_title) || "";
|
||||
reviewIntroHook.value = stringFromUnknown(draftState.review_intro_hook) || "";
|
||||
keyPoints.value = stringFromUnknown(draftState.key_points) || "";
|
||||
selectedKnowledgeGroupIds.value = numberListFromUnknown(draftState.knowledge_group_ids) ?? [];
|
||||
customOutlineSections.value = parseCustomOutlineSections(draftState.custom_outline_sections);
|
||||
outlineOptionOrder.value = stringListFromUnknown(draftState.outline_option_order) ?? outlineOptionOrder.value;
|
||||
outlineSections.value = stringListFromUnknown(draftState.outline_sections) ?? outlineSections.value;
|
||||
@@ -989,6 +993,8 @@ function buildPayload(): Record<string, JsonValue> {
|
||||
primary_keyword: primaryKeyword.value || undefined,
|
||||
keywords: keywordDrafts.value.length > 0 ? dedupeStrings(keywordDrafts.value) : undefined,
|
||||
[reviewIntroHookFieldName.value]: reviewIntroHookPromptValue.value || undefined,
|
||||
knowledge_group_ids:
|
||||
selectedKnowledgeGroupIds.value.length > 0 ? selectedKnowledgeGroupIds.value : undefined,
|
||||
competitors: competitorInputValue,
|
||||
};
|
||||
|
||||
@@ -1031,6 +1037,7 @@ function buildDraftState(): Record<string, JsonValue> {
|
||||
custom_title: customTitle.value,
|
||||
title: finalTitle.value || selectedTitle.value || "",
|
||||
review_intro_hook: reviewIntroHook.value,
|
||||
knowledge_group_ids: selectedKnowledgeGroupIds.value,
|
||||
outline_sections: outlineSections.value,
|
||||
outline_option_order: outlineOptionOrder.value,
|
||||
custom_outline_sections: customOutlineSections.value.map((item) => ({
|
||||
@@ -1524,6 +1531,16 @@ function numberFromUnknown(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
|
||||
function numberListFromUnknown(value: unknown): number[] | undefined {
|
||||
if (!Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
const items = value
|
||||
.map((item) => (typeof item === "number" && Number.isFinite(item) ? item : NaN))
|
||||
.filter((item) => Number.isFinite(item) && item > 0);
|
||||
return items.length > 0 ? items : undefined;
|
||||
}
|
||||
|
||||
function clampStep(value: number | undefined): number {
|
||||
if (typeof value !== "number" || Number.isNaN(value)) {
|
||||
return 0;
|
||||
@@ -2415,6 +2432,14 @@ function onStructureDragEnd(): void {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field-item field-item--compact">
|
||||
<label>引用知识库</label>
|
||||
<KnowledgeGroupSelect
|
||||
v-model="selectedKnowledgeGroupIds"
|
||||
placeholder="可选,用于补充文章内容和事实背景"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<a-alert
|
||||
type="info"
|
||||
show-icon
|
||||
|
||||
Reference in New Issue
Block a user