CzRger 3 weeks ago
parent
commit
64662e9bf9

+ 6 - 0
src/api/modules/knowledge/tags.ts

@@ -8,3 +8,9 @@ export const tagsAdd = (params) => post(`/tags`, params, {})
 export const tagsEdit = (params) => put(`/tags`, params, {})
 // 标签删除
 export const tagsDel = (id) => del(`/tags/${id}`, {}, {})
+// 知识库绑定标签
+export const tagsDatasetBanding = (params) =>
+  put(`/tags/dataset/banding`, params, {})
+// 取消知识库绑定标签
+export const tagsDatasetBandingCancel = (params) =>
+  put(`/tags/dataset/banding/cancel`, params, {})

+ 1 - 1
src/stores/modules/app.ts

@@ -25,7 +25,7 @@ export const useAppStore = defineStore('app', {
     loadingStart() {
       const l = document.getElementById('loader')
       if (l) {
-        l.style.display = 'unset'
+        l.style.display = 'flex'
       }
     },
     loadingEnd() {

+ 58 - 4
src/stores/modules/dictionary.ts

@@ -3,10 +3,15 @@ import { tagsTenant } from '@/api/modules/knowledge/tags'
 import { ElMessage } from 'element-plus'
 import { datasetGroupsGetAllByTenantId } from '@/api/modules/knowledge/group'
 
-const listToMap = (list, labelKey = 'label', valueKey = 'value') => {
+const listToMap = ({
+  list,
+  labelKey = 'label',
+  valueKey = 'value',
+  isObj = false,
+}) => {
   const map = new Map()
   list.forEach((v) => {
-    map.set(v[valueKey], v[labelKey])
+    map.set(v[valueKey], isObj ? v : v[labelKey])
   })
   return map
 }
@@ -16,11 +21,25 @@ export const useDictionaryStore = defineStore('dictionary', {
       waiting: false,
       list: [],
       map: new Map(),
+      objMap: new Map(),
     },
     knowledgeGroups: {
       waiting: false,
       list: [],
       map: new Map(),
+      objMap: new Map(),
+    },
+    rerankModels: {
+      waiting: false,
+      list: [],
+      map: new Map(),
+      objMap: new Map(),
+    },
+    embeddingModels: {
+      waiting: false,
+      list: [],
+      map: new Map(),
+      objMap: new Map(),
     },
   }),
   getters: {
@@ -41,7 +60,8 @@ export const useDictionaryStore = defineStore('dictionary', {
               return v
             })
             this.knowledgeTags.list = arr
-            this.knowledgeTags.map = listToMap(arr)
+            this.knowledgeTags.map = listToMap({ list: arr })
+            this.knowledgeTags.objMap = listToMap({ list: arr, isObj: true })
           })
           .catch(({ message }: any) => {
             ElMessage.error(message)
@@ -62,7 +82,8 @@ export const useDictionaryStore = defineStore('dictionary', {
               return v
             })
             this.knowledgeGroups.list = arr
-            this.knowledgeGroups.map = listToMap(arr)
+            this.knowledgeGroups.map = listToMap({ list: arr })
+            this.knowledgeGroups.objMap = listToMap({ list: arr, isObj: true })
           })
           .catch(({ message }: any) => {
             ElMessage.error(message)
@@ -72,5 +93,38 @@ export const useDictionaryStore = defineStore('dictionary', {
           })
       }
     },
+    initRerankModels() {
+      if (!this.rerankModels.waiting) {
+        this.rerankModels.waiting = true
+        setTimeout(() => {
+          const arr: any = []
+          for (let i = 0; i < 10; i++) {
+            arr.push({ label: 'bga-reanskada-v2-sad-m3' + ':' + i, value: i })
+          }
+          this.rerankModels.list = arr
+          this.rerankModels.map = listToMap({ list: arr })
+          this.rerankModels.objMap = listToMap({ list: arr, isObj: true })
+          this.rerankModels.waiting = false
+        }, 1000)
+      }
+    },
+    initEmbeddingModels() {
+      if (!this.embeddingModels.waiting) {
+        this.embeddingModels.waiting = true
+        setTimeout(() => {
+          const arr: any = []
+          for (let i = 0; i < 10; i++) {
+            arr.push({
+              label: 'snowflake-arctic-embed2:568m' + ':' + i,
+              value: i,
+            })
+          }
+          this.embeddingModels.list = arr
+          this.embeddingModels.map = listToMap({ list: arr })
+          this.embeddingModels.objMap = listToMap({ list: arr, isObj: true })
+          this.embeddingModels.waiting = false
+        }, 1000)
+      }
+    },
   },
 })

+ 17 - 19
src/views/manage/knowledge/detail.vue

@@ -65,11 +65,8 @@
           link="select"
           :options="DictionaryStore.knowledgeGroups.list"
         />
+        <modelConfig ref="ref_modelConfig" />
       </CzrForm>
-      <modelConfig
-        :transfer="state.modelConfigTransfer"
-        @refresh="getModelConfig"
-      />
     </div>
   </CzrDialog>
 </template>
@@ -88,6 +85,7 @@ import { useDialogStore, useDictionaryStore } from '@/stores'
 import { useRouter } from 'vue-router'
 import modelConfig from './model-config.vue'
 import { datasetsCreate, datasetsDetail } from '@/api/modules/knowledge'
+import { debounce } from 'lodash'
 
 const router = useRouter()
 const DictionaryStore = useDictionaryStore()
@@ -101,8 +99,8 @@ const props = defineProps({
 const state: any = reactive({
   loading: false,
   form: {},
-  modelConfigTransfer: null,
 })
+const ref_modelConfig = ref()
 const ref_form = ref()
 const titleCpt = computed(() => {
   let t = '知识库'
@@ -126,6 +124,7 @@ watch(
     if (n) {
       initDictionary()
       state.form = {}
+      ref_modelConfig.value?.reset()
       if (props.transfer.mode !== 'add') {
         initData()
       }
@@ -147,20 +146,20 @@ const onSubmit = (isImport) => {
         content: `请确认是否${titleCpt.value}?${isImport ? '创建成功后将自动跳转至文档上传页面!' : ''}`,
         onSubmit: () => {
           state.loading = true
-          datasetsCreate(state.form)
+          datasetsCreate({ ...state.form, ...ref_modelConfig.value.getData() })
             .then(({ data }: any) => {
-              ElMessage.success(`${titleCpt.value}成功!`)
-              if (isImport) {
-                router.push({
-                  name: '18e6009c-a72c-4359-864b-e7725fccca69',
-                  params: {
-                    id: '知识库ID',
-                  },
-                })
-              } else {
-                emit('update:show', false)
-                emit('refresh')
-              }
+              // ElMessage.success(`${titleCpt.value}成功!`)
+              // if (isImport) {
+              //   router.push({
+              //     name: '18e6009c-a72c-4359-864b-e7725fccca69',
+              //     params: {
+              //       id: '知识库ID',
+              //     },
+              //   })
+              // } else {
+              //   emit('update:show', false)
+              //   emit('refresh')
+              // }
             })
             .catch(({ message }: any) => {
               ElMessage.error(message)
@@ -179,7 +178,6 @@ const onSubmit = (isImport) => {
       })
     })
 }
-const getModelConfig = (data) => {}
 </script>
 
 <style lang="scss" scoped></style>

+ 76 - 65
src/views/manage/knowledge/model-config.vue

@@ -65,12 +65,13 @@
   <template v-if="state.embedding.show">
     <div class="__czr-title_1 mb-[0.5rem]">Embedding 模型</div>
     <CzrFormColumn
+      required
       class="__czr-table-form-column"
       :span="24"
       label="模型类型"
       v-model:param="state.embedding.value"
       link="select"
-      :options="[]"
+      :options="DictionaryStore.embeddingModels.list"
       :clearable="false"
     />
   </template>
@@ -107,6 +108,8 @@
               <el-switch
                 size="small"
                 v-model="state.searchMethod[SearchMethodType.Vector].isRerank"
+                :active-value="1"
+                :inactive-value="0"
               />
               Rerank 模型
               <el-tooltip
@@ -120,6 +123,7 @@
               v-if="state.searchMethod[SearchMethodType.Vector].isRerank"
             >
               <CzrFormColumn
+                required
                 class="__czr-table-form-column"
                 :span="24"
                 label-width="0px"
@@ -127,8 +131,9 @@
                   state.searchMethod[SearchMethodType.Vector].rerank
                 "
                 link="select"
-                :options="[{ label: 'bga-reanskada-v2-sad-m3', value: 1 }]"
+                :options="DictionaryStore.rerankModels.list"
                 :clearable="false"
+                default-error-msg="请选择Rerank模型"
               />
             </template>
             <div class="flex gap-[1rem]">
@@ -159,6 +164,8 @@
                     v-model="
                       state.searchMethod[SearchMethodType.Vector].isScore
                     "
+                    :active-value="1"
+                    :inactive-value="0"
                   />
                   Score 阈值
                   <el-tooltip
@@ -218,6 +225,8 @@
               <el-switch
                 size="small"
                 v-model="state.searchMethod[SearchMethodType.Global].isRerank"
+                :active-value="1"
+                :inactive-value="0"
               />
               Rerank 模型
               <el-tooltip
@@ -238,8 +247,9 @@
                   state.searchMethod[SearchMethodType.Global].rerank
                 "
                 link="select"
-                :options="[{ label: 'bga-reanskada-v2-sad-m3', value: 1 }]"
+                :options="DictionaryStore.rerankModels.list"
                 :clearable="false"
+                default-error-msg="请选择Rerank模型"
               />
             </template>
             <div class="flex gap-[1rem]">
@@ -273,6 +283,8 @@
                     v-model="
                       state.searchMethod[SearchMethodType.Global].isScore
                     "
+                    :active-value="1"
+                    :inactive-value="0"
                   />
                   Score 阈值
                   <el-tooltip
@@ -439,8 +451,9 @@
                 label-width="0px"
                 v-model:param="state.searchMethod[SearchMethodType.Mix].rerank"
                 link="select"
-                :options="[{ label: 'bga-reanskada-v2-sad-m3', value: 1 }]"
+                :options="DictionaryStore.rerankModels.list"
                 :clearable="false"
+                default-error-msg="请选择Rerank模型"
               />
             </template>
           </div>
@@ -473,6 +486,8 @@
                   <el-switch
                     size="small"
                     v-model="state.searchMethod[SearchMethodType.Mix].isScore"
+                    :active-value="1"
+                    :inactive-value="0"
                   />
                   Score 阈值
                   <el-tooltip
@@ -505,8 +520,10 @@
 </template>
 
 <script setup lang="ts">
-import { getCurrentInstance, reactive, ref, watch } from 'vue'
+import { getCurrentInstance, onMounted, reactive, ref, watch } from 'vue'
+import { useDictionaryStore } from '@/stores'
 
+const DictionaryStore = useDictionaryStore()
 const emit = defineEmits([])
 const props = defineProps({})
 const { proxy }: any = getCurrentInstance()
@@ -518,35 +535,35 @@ enum SearchMethodType {
 const state: any = reactive({
   indexMethod: {
     show: true,
-    value: 1,
+    value: '高质量',
   },
   embedding: {
     show: true,
-    value: 1,
+    value: '',
   },
   searchMethod: {
     show: true,
     value: SearchMethodType.Vector,
-    vector: {
-      isRerank: true,
+    [SearchMethodType.Vector]: {
+      isRerank: 1,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
-    global: {
-      isRerank: true,
+    [SearchMethodType.Global]: {
+      isRerank: 1,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
-    mix: {
+    [SearchMethodType.Mix]: {
       indexMethod: 1,
       weight: 0.7,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
   },
@@ -554,7 +571,7 @@ const state: any = reactive({
 const reset = () => {
   state.indexMethod = {
     show: true,
-    value: 1,
+    value: '高质量',
   }
   state.embedding = {
     show: true,
@@ -564,17 +581,17 @@ const reset = () => {
     show: true,
     value: SearchMethodType.Vector,
     [SearchMethodType.Vector]: {
-      isRerank: true,
+      isRerank: 1,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
     [SearchMethodType.Global]: {
-      isRerank: true,
+      isRerank: 1,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
     [SearchMethodType.Mix]: {
@@ -582,7 +599,7 @@ const reset = () => {
       weight: 0.7,
       rerank: '',
       topK: 5,
-      isScore: true,
+      isScore: 1,
       score: 0.5,
     },
   }
@@ -591,43 +608,36 @@ const getData = () => {
   const result = {
     indexingTechnique: state.indexMethod.value,
     embeddingModelId: state.embedding.value,
+    embeddingModel: DictionaryStore.embeddingModels.map.get(
+      state.embedding.value,
+    ),
     indexConfig: {},
   }
   switch (state.searchMethod.value) {
     case SearchMethodType.Vector:
       {
-        result.indexConfig.isRerank = state.searchMethod[
-          SearchMethodType.Vector
-        ].isRerank
-          ? 1
-          : 0
+        result.indexConfig.isRerank =
+          state.searchMethod[SearchMethodType.Vector].isRerank
         result.indexConfig.rerankType =
           state.searchMethod[SearchMethodType.Vector].rerank
         result.indexConfig.topK =
           state.searchMethod[SearchMethodType.Vector].topK
-        result.indexConfig.isScore = state.searchMethod[SearchMethodType.Vector]
-          .isScore
-          ? 1
-          : 0
+        result.indexConfig.isScore =
+          state.searchMethod[SearchMethodType.Vector].isScore
         result.indexConfig.score =
           state.searchMethod[SearchMethodType.Vector].score
       }
       break
     case SearchMethodType.Global:
       {
-        result.indexConfig.isRerank = state.searchMethod[
-          SearchMethodType.Global
-        ].isRerank
-          ? 1
-          : 0
+        result.indexConfig.isRerank =
+          state.searchMethod[SearchMethodType.Global].isRerank
         result.indexConfig.rerankType =
           state.searchMethod[SearchMethodType.Global].rerank
         result.indexConfig.topK =
           state.searchMethod[SearchMethodType.Global].topK
-        result.indexConfig.isScore = state.searchMethod[SearchMethodType.Global]
-          .isScore
-          ? 1
-          : 0
+        result.indexConfig.isScore =
+          state.searchMethod[SearchMethodType.Global].isScore
         result.indexConfig.score =
           state.searchMethod[SearchMethodType.Global].score
       }
@@ -643,10 +653,8 @@ const getData = () => {
         result.indexConfig.rerankType =
           state.searchMethod[SearchMethodType.Mix].rerank
         result.indexConfig.topK = state.searchMethod[SearchMethodType.Mix].topK
-        result.indexConfig.isScore = state.searchMethod[SearchMethodType.Mix]
-          .isScore
-          ? 1
-          : 0
+        result.indexConfig.isScore =
+          state.searchMethod[SearchMethodType.Mix].isScore
         result.indexConfig.score =
           state.searchMethod[SearchMethodType.Mix].score
       }
@@ -654,51 +662,54 @@ const getData = () => {
   }
   return result
 }
-const init = ({ indexMethod, embedding, searchMethod }) => {
-  state.indexMethod.value = indexMethod
-  state.embedding.value = embedding
-  switch (searchMethod.type) {
+const init = ({ indexingTechnique, embeddingModelId, indexConfig }) => {
+  reset()
+  state.indexMethod.value = indexingTechnique
+  state.embedding.value = embeddingModelId
+  switch (indexConfig.type) {
     case SearchMethodType.Vector:
       {
         state.searchMethod[SearchMethodType.Vector].isRerank =
-          searchMethod.isRerank == 1
+          indexConfig.isRerank
         state.searchMethod[SearchMethodType.Vector].rerank =
-          searchMethod.rerankType
-        state.searchMethod[SearchMethodType.Vector].topK = searchMethod.topK
+          indexConfig.rerankType
+        state.searchMethod[SearchMethodType.Vector].topK = indexConfig.topK
         state.searchMethod[SearchMethodType.Vector].isScore =
-          searchMethod.isScore == 1
-        state.searchMethod[SearchMethodType.Vector].score = searchMethod.score
+          indexConfig.isScore
+        state.searchMethod[SearchMethodType.Vector].score = indexConfig.score
       }
       break
     case SearchMethodType.Global:
       {
         state.searchMethod[SearchMethodType.Global].isRerank =
-          searchMethod.isRerank == 1
+          indexConfig.isRerank
         state.searchMethod[SearchMethodType.Global].rerank =
-          searchMethod.rerankType
-        state.searchMethod[SearchMethodType.Global].topK = searchMethod.topK
+          indexConfig.rerankType
+        state.searchMethod[SearchMethodType.Global].topK = indexConfig.topK
         state.searchMethod[SearchMethodType.Global].isScore =
-          searchMethod.isScore == 1
-        state.searchMethod[SearchMethodType.Global].score = searchMethod.score
+          indexConfig.isScore
+        state.searchMethod[SearchMethodType.Global].score = indexConfig.score
       }
       break
     case SearchMethodType.Mix:
       {
         state.searchMethod[SearchMethodType.Mix].indexMethod =
-          searchMethod.weightRerank
+          indexConfig.weightRerank
         state.searchMethod[SearchMethodType.Mix].weight = Number(
-          searchMethod.semantics,
+          indexConfig.semantics,
         )
-        state.searchMethod[SearchMethodType.Mix].rerank =
-          searchMethod.rerankType
-        state.searchMethod[SearchMethodType.Mix].topK = searchMethod.topK
-        state.searchMethod[SearchMethodType.Mix].isScore =
-          searchMethod.isScore == 1
-        state.searchMethod[SearchMethodType.Mix].score = searchMethod.score
+        state.searchMethod[SearchMethodType.Mix].rerank = indexConfig.rerankType
+        state.searchMethod[SearchMethodType.Mix].topK = indexConfig.topK
+        state.searchMethod[SearchMethodType.Mix].isScore = indexConfig.isScore
+        state.searchMethod[SearchMethodType.Mix].score = indexConfig.score
       }
       break
   }
 }
+onMounted(() => {
+  DictionaryStore.initRerankModels()
+  DictionaryStore.initEmbeddingModels()
+})
 defineExpose({
   reset,
   getData,