CzRger hai 2 semanas
pai
achega
1285d7c84a

+ 4 - 2
.env.development

@@ -8,5 +8,7 @@ VITE_LOGIN_MUST = Y
 VITE_TOKEN = bmwToken
 # 基础路径
 VITE_BASE = big-model-web
-# 基础路径
-VITE_BASE_API_PROXY = /bmw-api
+# 基础代理
+VITE_BASE_API_PROXY = /bmw-api
+# 工作流代理
+VITE_WORKFLOW_API_PROXY = /bmw-workflow-api

+ 4 - 2
.env.production

@@ -8,5 +8,7 @@ VITE_LOGIN_MUST = Y
 VITE_TOKEN = bmwToken
 # 基础路径
 VITE_BASE = big-model-web
-# 基础路径
-VITE_BASE_API_PROXY = /bmw-api
+# 基础代理
+VITE_BASE_API_PROXY = /bmw-api
+# 工作流代理
+VITE_WORKFLOW_API_PROXY = /bmw-workflow-api

+ 6 - 6
src/api/interceptors.ts

@@ -99,12 +99,12 @@ export class Interceptors {
                 onClick: () =>
                   exportLog(
                     [
-                      '错误日期:' + YMDHms(res.headers.date),
-                      '接口地址:' + res.request.responseURL,
-                      '接口状态:' + res.status + '_' + res.statusText,
-                      '请求Token:' + res.config.headers.Authorization,
-                      '请求参数:' + res.config.data,
-                      '返回结果:' + res.request.response,
+                      `错误日期:${YMDHms(res.headers.date)}`,
+                      `接口地址:${res.config.method.toUpperCase()} ${res.request.responseURL}`,
+                      `接口状态:${res.status} ${res.statusText}`,
+                      `请求Token:${res.config.headers.Authorization}`,
+                      `请求参数:${res.config.data}`,
+                      `返回结果:${res.request.response}`,
                     ],
                     YMDHms(res.headers.date),
                   ),

+ 12 - 17
src/api/modules/model/index.ts

@@ -1,19 +1,14 @@
 import { del, get, post, put } from '@/api/request'
 
-// 知识库分页
-export const datasetsGetAllByPage = (params) =>
-  post('/datasets/getAllByPage', params, {})
-// 知识库绑定标签
-export const datasetsTagsBinding = (params) =>
-  post('/datasets/tags/binding', params, {})
-// 创建知识库
-export const datasetsCreate = (params) => post('/datasets/create', params, {})
-// 编辑知识库
-export const datasetsUpdate = (params) => put('/datasets/update', params, {})
-// 删除知识库
-export const datasetsDel = (id) => del(`/datasets/${id}`, {}, {})
-// 知识库详情
-export const datasetsDetail = (id) => get(`/datasets/${id}`, {}, {})
-// 知识库取消收藏
-export const datasetsCancelCollect = (datasetId) =>
-  post(`/datasets/cancelCollect/${datasetId}`, {}, {})
+const proxy = (import.meta as any).env.VITE_WORKFLOW_API_PROXY
+// 模型纳管分页
+export const pluginGetInstanceList = (params) =>
+  post('/plugin/get-instance-list', params, {}, proxy)
+// 获取模型类型
+export const pluginGetModelTypeList = () =>
+  get('/plugin/get-model-type-list', {}, {}, proxy)
+// 获取模型供应商
+export const pluginConfigs = () => get('/plugin/configs', {}, {}, proxy)
+// 根据类型获取对应模型
+export const pluginGetListByType = (params) =>
+  get('/plugin/get-list-by-type', params, {}, proxy)

+ 36 - 26
src/api/request.ts

@@ -2,75 +2,85 @@ import { Interceptors } from '@/api/interceptors'
 
 const request: any = new Interceptors().getInterceptors()
 
-export const get = (url = '', params: any = {}, config: any = {}) => {
+export const get = (
+  url = '',
+  params: any = {},
+  config: any = {},
+  proxy = '',
+) => {
   return new Promise((resolve, reject) => {
-    const rUrl = (import.meta as any).env.VITE_BASE_API_PROXY + url
+    const rUrl = (proxy || (import.meta as any).env.VITE_BASE_API_PROXY) + url
     request
       .get(rUrl, {
         params,
         ...config,
       })
       .then((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        resolve(res)
       })
       .catch((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        reject(res)
       })
   })
 }
-export const del = (url = '', params: any = {}, config: any = {}) => {
+export const del = (
+  url = '',
+  params: any = {},
+  config: any = {},
+  proxy = '',
+) => {
   return new Promise((resolve, reject) => {
-    const rUrl = (import.meta as any).env.VITE_BASE_API_PROXY + url
+    const rUrl = (proxy || (import.meta as any).env.VITE_BASE_API_PROXY) + url
     request
       .delete(rUrl, {
         params,
         ...config,
       })
       .then((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        resolve(res)
       })
       .catch((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        reject(res)
       })
   })
 }
-export const post = (url = '', params: any = {}, config: any = {}) => {
+export const post = (
+  url = '',
+  params: any = {},
+  config: any = {},
+  proxy = '',
+) => {
   return new Promise((resolve, reject) => {
-    const rUrl = (import.meta as any).env.VITE_BASE_API_PROXY + url
+    const rUrl = (proxy || (import.meta as any).env.VITE_BASE_API_PROXY) + url
     request
       .post(rUrl, params, {
         ...config,
       })
       .then((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        resolve(res)
       })
       .catch((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        reject(res)
       })
   })
 }
-export const put = (url = '', params: any = {}, config: any = {}) => {
+export const put = (
+  url = '',
+  params: any = {},
+  config: any = {},
+  proxy = '',
+) => {
   return new Promise((resolve, reject) => {
-    const rUrl = (import.meta as any).env.VITE_BASE_API_PROXY + url
+    const rUrl = (proxy || (import.meta as any).env.VITE_BASE_API_PROXY) + url
     request
       .put(rUrl, params, {
         ...config,
       })
       .then((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        resolve(res)
       })
       .catch((res: any) => {
-        resultHandle(res, resolve, reject, rUrl)
+        reject(res)
       })
   })
 }
-
-const resultHandle = (res: any, resolve: any, reject: any, url: string) => {
-  if (res) {
-    if (res.code === 200) {
-      resolve(res)
-    } else {
-      reject(res)
-    }
-  }
-}

+ 7 - 0
src/components/czr-ui/CzrFormColumn.vue

@@ -16,6 +16,7 @@
         ['link_' + link + ($attrs.type ? '_' + $attrs.type : '')]: true,
         required: required !== false,
         'no-label': labelWidth === '0px' && !isValue(label) && !$slots.label,
+        'no-label-fit': !labelFit,
         'is-error': !!state.errorMessage,
         [`layout-${layout || formLayout}`]: true,
       }"
@@ -310,6 +311,7 @@ const props = defineProps({
   layout: {},
   transparent: { default: false },
   width: { default: '' },
+  labelFit: { default: true },
 })
 const attrs = (getCurrentInstance() as ComponentInternalInstance).attrs
 const state = reactive({
@@ -476,6 +478,11 @@ defineExpose({
         display: none;
       }
     }
+    &.no-label-fit {
+      .el-form-item__label-wrap {
+        margin-left: 0 !important;
+      }
+    }
     &.layout-y {
       .el-form-item__label {
         justify-content: flex-start;

+ 46 - 32
src/stores/modules/dictionary.ts

@@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
 import { tagsTenant } from '@/api/modules/knowledge/tags'
 import { ElMessage } from 'element-plus'
 import { datasetGroupsGetAllByTenantId } from '@/api/modules/knowledge/group'
+import { pluginConfigs, pluginGetModelTypeList } from '@/api/modules/model'
 
 const listToMap = ({
   list,
@@ -29,13 +30,13 @@ export const useDictionaryStore = defineStore('dictionary', {
       map: new Map(),
       objMap: new Map(),
     },
-    rerankModels: {
+    modelProvides: {
       waiting: false,
       list: [],
       map: new Map(),
       objMap: new Map(),
     },
-    embeddingModels: {
+    modelTypes: {
       waiting: false,
       list: [],
       map: new Map(),
@@ -93,40 +94,53 @@ 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: String(i),
+    initModelTypes() {
+      if (!this.modelTypes.waiting) {
+        this.modelTypes.waiting = true
+        pluginGetModelTypeList()
+          .then(({ data }: any) => {
+            const arr: any = data.map((v) => {
+              v.label = v.label
+              v.value = v.code
+              return v
             })
-          }
-          this.rerankModels.list = arr
-          this.rerankModels.map = listToMap({ list: arr })
-          this.rerankModels.objMap = listToMap({ list: arr, isObj: true })
-          this.rerankModels.waiting = false
-        }, 1000)
+            this.modelTypes.list = arr
+            this.modelTypes.map = listToMap({ list: arr })
+            this.modelTypes.objMap = listToMap({ list: arr, isObj: true })
+          })
+          .catch(({ message }: any) => {
+            ElMessage.error(message)
+          })
+          .finally(() => {
+            this.modelTypes.waiting = false
+          })
       }
     },
-    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: String(i),
+    initModelProvides() {
+      if (!this.modelProvides.waiting) {
+        this.modelProvides.waiting = true
+        pluginConfigs()
+          .then(({ data }: any) => {
+            const arr: any = []
+            Object.values(data).forEach((v: any) => {
+              arr.push(
+                ...v.map((v) => {
+                  v.label = v.providerName
+                  v.value = v.providerName
+                  return v
+                }),
+              )
             })
-          }
-          this.embeddingModels.list = arr
-          this.embeddingModels.map = listToMap({ list: arr })
-          this.embeddingModels.objMap = listToMap({ list: arr, isObj: true })
-          this.embeddingModels.waiting = false
-        }, 1000)
+            this.modelProvides.list = arr
+            this.modelProvides.map = listToMap({ list: arr })
+            this.modelProvides.objMap = listToMap({ list: arr, isObj: true })
+          })
+          .catch(({ message }: any) => {
+            ElMessage.error(message)
+          })
+          .finally(() => {
+            this.modelProvides.waiting = false
+          })
       }
     },
   },

+ 73 - 16
src/views/manage/knowledge/model-config.vue

@@ -71,7 +71,7 @@
       label="模型类型"
       v-model:param="state.embedding.value"
       link="select"
-      :options="DictionaryStore.embeddingModels.list"
+      :options="state.optionsEmbedding"
       :clearable="false"
     />
   </template>
@@ -131,7 +131,7 @@
                   state.searchMethod[SearchMethodType.Vector].rerank
                 "
                 link="select"
-                :options="DictionaryStore.rerankModels.list"
+                :options="state.optionsRerank"
                 :clearable="false"
                 default-error-msg="请选择Rerank模型"
               />
@@ -247,7 +247,7 @@
                   state.searchMethod[SearchMethodType.Global].rerank
                 "
                 link="select"
-                :options="DictionaryStore.rerankModels.list"
+                :options="state.optionsRerank"
                 :clearable="false"
                 default-error-msg="请选择Rerank模型"
               />
@@ -451,7 +451,7 @@
                 label-width="0px"
                 v-model:param="state.searchMethod[SearchMethodType.Mix].rerank"
                 link="select"
-                :options="DictionaryStore.rerankModels.list"
+                :options="state.optionsRerank"
                 :clearable="false"
                 default-error-msg="请选择Rerank模型"
               />
@@ -520,8 +520,17 @@
 </template>
 
 <script setup lang="ts">
-import { getCurrentInstance, onMounted, reactive, ref, watch } from 'vue'
+import {
+  computed,
+  getCurrentInstance,
+  onMounted,
+  reactive,
+  ref,
+  watch,
+} from 'vue'
 import { useDictionaryStore } from '@/stores'
+import { pluginGetListByType, pluginInstanceByType } from '@/api/modules/model'
+import { ElMessage } from 'element-plus'
 
 const DictionaryStore = useDictionaryStore()
 const emit = defineEmits([])
@@ -533,6 +542,8 @@ enum SearchMethodType {
   Mix = 'HYBRID',
 }
 const state: any = reactive({
+  optionsEmbedding: [],
+  optionsRerank: [],
   indexMethod: {
     show: true,
     value: '高质量',
@@ -568,6 +579,20 @@ const state: any = reactive({
     },
   },
 })
+const optionsEmbeddingMapCpt = computed(() => {
+  const map = new Map()
+  state.optionsEmbedding.forEach((v) => {
+    map.set(v.value, v)
+  })
+  return map
+})
+const optionsRerankMapCpt = computed(() => {
+  const map = new Map()
+  state.optionsRerank.forEach((v) => {
+    map.set(v.value, v)
+  })
+  return map
+})
 const reset = () => {
   state.indexMethod = {
     show: true,
@@ -608,9 +633,8 @@ const getData = () => {
   const result = {
     indexingTechnique: state.indexMethod.value,
     embeddingModelId: state.embedding.value,
-    embeddingModel: DictionaryStore.embeddingModels.map.get(
-      state.embedding.value,
-    ),
+    embeddingModel: optionsEmbeddingMapCpt.value.get(state.embedding.value)
+      .label,
     indexConfig: {
       type: state.searchMethod.value,
     },
@@ -620,8 +644,11 @@ const getData = () => {
       {
         result.indexConfig.isRerank =
           state.searchMethod[SearchMethodType.Vector].isRerank
-        result.indexConfig.rerankType =
+        result.indexConfig.rerankTypeId =
           state.searchMethod[SearchMethodType.Vector].rerank
+        result.indexConfig.rerankType = optionsRerankMapCpt.value.get(
+          state.searchMethod[SearchMethodType.Vector].rerank,
+        ).label
         result.indexConfig.topK =
           state.searchMethod[SearchMethodType.Vector].topK
         result.indexConfig.isScore =
@@ -634,8 +661,11 @@ const getData = () => {
       {
         result.indexConfig.isRerank =
           state.searchMethod[SearchMethodType.Global].isRerank
-        result.indexConfig.rerankType =
+        result.indexConfig.rerankTypeId =
           state.searchMethod[SearchMethodType.Global].rerank
+        result.indexConfig.rerankType = optionsRerankMapCpt.value.get(
+          state.searchMethod[SearchMethodType.Global].rerank,
+        ).label
         result.indexConfig.topK =
           state.searchMethod[SearchMethodType.Global].topK
         result.indexConfig.isScore =
@@ -652,8 +682,11 @@ const getData = () => {
           state.searchMethod[SearchMethodType.Mix].weight
         result.indexConfig.keyword =
           1 - state.searchMethod[SearchMethodType.Mix].weight
-        result.indexConfig.rerankType =
+        result.indexConfig.rerankTypeId =
           state.searchMethod[SearchMethodType.Mix].rerank
+        result.indexConfig.rerankType = optionsRerankMapCpt.value.get(
+          state.searchMethod[SearchMethodType.Mix].rerank,
+        ).label
         result.indexConfig.topK = state.searchMethod[SearchMethodType.Mix].topK
         result.indexConfig.isScore =
           state.searchMethod[SearchMethodType.Mix].isScore
@@ -676,7 +709,7 @@ const init = ({ indexingTechnique, embeddingModelId, indexConfig }) => {
           indexConfig.isRerank,
         )
         state.searchMethod[SearchMethodType.Vector].rerank =
-          indexConfig.rerankType
+          indexConfig.rerankTypeId
         state.searchMethod[SearchMethodType.Vector].topK = Number(
           indexConfig.topK,
         )
@@ -694,7 +727,7 @@ const init = ({ indexingTechnique, embeddingModelId, indexConfig }) => {
           indexConfig.isRerank,
         )
         state.searchMethod[SearchMethodType.Global].rerank =
-          indexConfig.rerankType
+          indexConfig.rerankTypeId
         state.searchMethod[SearchMethodType.Global].topK = Number(
           indexConfig.topK,
         )
@@ -713,7 +746,8 @@ const init = ({ indexingTechnique, embeddingModelId, indexConfig }) => {
         state.searchMethod[SearchMethodType.Mix].weight = Number(
           indexConfig.semantics,
         )
-        state.searchMethod[SearchMethodType.Mix].rerank = indexConfig.rerankType
+        state.searchMethod[SearchMethodType.Mix].rerank =
+          indexConfig.rerankTypeId
         state.searchMethod[SearchMethodType.Mix].topK = Number(indexConfig.topK)
         state.searchMethod[SearchMethodType.Mix].isScore = Number(
           indexConfig.isScore,
@@ -726,14 +760,37 @@ const init = ({ indexingTechnique, embeddingModelId, indexConfig }) => {
   }
 }
 onMounted(() => {
-  DictionaryStore.initRerankModels()
-  DictionaryStore.initEmbeddingModels()
+  initDictionary()
 })
 defineExpose({
   reset,
   getData,
   init,
 })
+const initDictionary = () => {
+  pluginGetListByType({ type: 'EMBEDDING' })
+    .then(({ data }: any) => {
+      state.optionsEmbedding = data.map((v) => {
+        v.label = v.name
+        v.value = v.id
+        return v
+      })
+    })
+    .catch(({ message }: any) => {
+      ElMessage.error(message)
+    })
+  pluginGetListByType({ type: 'RERANK' })
+    .then(({ data }: any) => {
+      state.optionsRerank = data.map((v) => {
+        v.label = v.name
+        v.value = v.id
+        return v
+      })
+    })
+    .catch(({ message }: any) => {
+      ElMessage.error(message)
+    })
+}
 </script>
 
 <style lang="scss" scoped>

+ 7 - 5
vite.config.ts

@@ -63,13 +63,15 @@ export default defineConfig(({ mode, command }) => {
             return path.replace(/^\/dify-api/, '')
           },
         },
-        '/bmw-api': {
+        [env.VITE_BASE_API_PROXY]: {
           target: 'http://1.95.78.201:18088/',
-          // target: 'http://192.168.4.12:8090/',
           changeOrigin: true,
-          rewrite: (path) => {
-            return path.replace(/^\/bmw-api/, '')
-          },
+          rewrite: (path) => path.replace(env.VITE_BASE_API_PROXY, ''),
+        },
+        [env.VITE_WORKFLOW_API_PROXY]: {
+          target: 'http://1.95.78.201:18087/',
+          changeOrigin: true,
+          rewrite: (path) => path.replace(env.VITE_WORKFLOW_API_PROXY, ''),
         },
       },
     },