11<script setup lang="ts">
22import type { DynamicFormValue } from ' ../../type'
3- import { computed , reactive } from ' vue'
3+ import { computed , reactive , ref } from ' vue'
4+ import { CaretBottom } from ' @element-plus/icons-vue'
45import Knowledge from ' ../../items/knowledge/Knowledge.vue'
56import type { FormField } from ' ../../type'
7+ import KnowledgeApi from ' @/api/admin/workspace/knowledge/knowledge'
8+ import type { KnowledgeItem } from ' @/api/types'
9+ import { FOLDER_ENTRY_ID } from ' @/constants'
610
711const props = defineProps <{ modelValue: DynamicFormValue }>()
812
@@ -37,6 +41,46 @@ const render = (formData: DynamicFormValue) => {
3741
3842defineExpose ({ getData , render })
3943
44+ // ── 添加知识库 ─────────────────────────────────────────
45+ const knowledgeDialogVisible = ref (false )
46+ const knowledgeLoading = ref (false )
47+ const knowledgeSearch = ref (' ' )
48+ const knowledgeList = ref <KnowledgeItem []>([])
49+ const selectedKnowledgeIds = ref <Array <string >>([])
50+
51+ const filteredKnowledgeList = computed (() => {
52+ const keyword = knowledgeSearch .value .trim ().toLocaleLowerCase ()
53+ if (! keyword ) return knowledgeList .value
54+ return knowledgeList .value .filter ((item ) => item .name .toLocaleLowerCase ().includes (keyword ))
55+ })
56+
57+ const openAddKnowledgeDialog = async () => {
58+ knowledgeDialogVisible .value = true
59+ selectedKnowledgeIds .value = (formValue .value .knowledge_list || []).map ((k : DynamicFormValue ) => k .id )
60+ knowledgeLoading .value = true
61+ try {
62+ const res = await KnowledgeApi .getKnowledgePage ({ currentPage: 1 , pageSize: 100 }, { folder_id: FOLDER_ENTRY_ID .ALL })
63+ knowledgeList .value = res .records || []
64+ } finally {
65+ knowledgeLoading .value = false
66+ }
67+ }
68+
69+ const handleKnowledgeSelect = () => {
70+ const selectIds = new Set (selectedKnowledgeIds .value )
71+ const currentList = (formValue .value .knowledge_list || []).filter ((k : DynamicFormValue ) => selectIds .has (k .id ))
72+ knowledgeList .value .forEach ((item ) => {
73+ if (selectIds .has (item .id ) && ! currentList .some ((k : DynamicFormValue ) => k .id === item .id )) {
74+ currentList .push ({ id: item .id , name: item .name , type: item .type , embedding_model_id: item .embedding_model_id })
75+ }
76+ })
77+ formValue .value .knowledge_list = currentList
78+ if (formValue .value .default_value ) {
79+ formValue .value .default_value = formValue .value .default_value .filter ((id : string ) => selectIds .has (id ))
80+ }
81+ knowledgeDialogVisible .value = false
82+ }
83+
4084function removeKnowledge(id : string ) {
4185 formValue .value .knowledge_list = formValue .value .knowledge_list .filter ((k : DynamicFormValue ) => k .id !== id )
4286 if (formValue .value .default_value ) {
@@ -48,17 +92,24 @@ function removeKnowledge(id: string) {
4892<template >
4993 <el-form-item prop =" knowledge_list" :rules =" [{ message: '请选择可选知识库', type: 'array', min: 1 }]" >
5094 <template #label >
51- <div class =" flex-between mb-12 cursor" @click =" collapseData.optional_knowledge = !collapseData.optional_knowledge" >
95+ <div class =" flex-between mb-2 cursor" @click =" collapseData.optional_knowledge = !collapseData.optional_knowledge" >
5296 <div class =" flex align-center" >
53- <el-icon class =" mr-8 arrow-icon" :class =" collapseData.optional_knowledge ? 'rotate-90' : ''" >
54- <CaretRight />
55- </el-icon >
97+ <MkIcon
98+ :icon =" CaretBottom "
99+ :size =" 14 "
100+ class="mr-1 text-N600! transition-transform"
101+ :class =" { ' -rotate-90' : ! collapseData .optional_knowledge } "
102+ />
56103 <span class =" lighter"
57104 >可选知识库
58- <span class =" color -danger" >*</span >
105+ <span class =" text -danger" >*</span >
59106 </span >
60- <span class =" ml-4 " v-if =" formValue.knowledge_list?.length" >({{ formValue.knowledge_list.length }})</span >
107+ <span class =" ml-1 " v-if =" formValue.knowledge_list?.length" >({{ formValue.knowledge_list.length }})</span >
61108 </div >
109+ <el-button type =" primary" link @click.stop =" openAddKnowledgeDialog" >
110+ <MkIcon name="icon_add_outlined" class="mr-1" />
111+ 添加
112+ </el-button >
62113 </div >
63114 </template >
64115 <div class =" w-full" v-if =" collapseData.optional_knowledge" >
@@ -90,4 +141,27 @@ function removeKnowledge(id: string) {
90141 <Knowledge v-model =" formValue .default_value " :form-field =" formField " />
91142 </div >
92143 </el-form-item >
144+
145+ <MkDialog v-model =" knowledgeDialogVisible " title="添加知识库" width="600px" append-to-body>
146+ <el-input v-model =" knowledgeSearch" placeholder =" 按名称搜索" clearable class =" mb-3" >
147+ <template #prefix >
148+ <MkIcon name="icon_magnify_outlined" />
149+ </template >
150+ </el-input >
151+ <div v-loading =" knowledgeLoading" class =" max-h-[360px] overflow-auto" >
152+ <el-checkbox-group v-model =" selectedKnowledgeIds" >
153+ <el-checkbox :value =" item.id" class =" -mr-2 w-full mb-2 rounded-md border border-N300 p-2" v-for =" item in filteredKnowledgeList" :key =" item.id" >
154+ <span class =" flex items-center gap-2" >
155+ <KnowledgeIcon :type =" item .type " :size =" 20 " style =" --el-avatar-border-radius : 6px " />
156+ <span class =" truncate" >{{ item.name }}</span >
157+ </span >
158+ </el-checkbox >
159+ </el-checkbox-group >
160+ <el-empty v-if =" !knowledgeLoading && filteredKnowledgeList.length === 0" description =" 暂无知识库" :image-size =" 60" />
161+ </div >
162+ <template #footer >
163+ <el-button @click =" knowledgeDialogVisible = false" >取消</el-button >
164+ <el-button type =" primary" @click =" handleKnowledgeSelect" >确定</el-button >
165+ </template >
166+ </MkDialog >
93167</template >
0 commit comments