Browse Source

模型选择

CzRger 4 days ago
parent
commit
9d18ac8036

+ 39 - 7
src/views/manage/app/make/index.vue

@@ -92,7 +92,7 @@
                     required
                     label="模型选择"
                     :span="24"
-                    v-model:param="state.form.model"
+                    v-model:param="state.form.model.name"
                     placeholder="点击选择模型"
                     readonly
                     @click="onModel"
@@ -356,7 +356,12 @@
     <knowledgeSelect
       v-model:show="state.knowledgeSelect.show"
       :transfer="state.knowledgeSelect.transfer"
-      @refresh="(v) => (state.form.knowledges = v)"
+      @refresh="getKnowledge"
+    />
+    <modelSelect
+      v-model:show="state.modelSelect.show"
+      :transfer="state.modelSelect.transfer"
+      @refresh="getModel"
     />
   </div>
 </template>
@@ -377,9 +382,7 @@ import { ElMessage } from 'element-plus'
 import { useDictionaryStore } from '@/stores'
 import { Search } from '@element-plus/icons-vue'
 import knowledgeSelect from './knowledge-select.vue'
-import CzrForm from '@/components/czr-ui/CzrForm.vue'
-import SvgIcon from '@/components/SvgIcon/index.vue'
-import CzrFormColumn from '@/components/czr-ui/CzrFormColumn.vue'
+import modelSelect from './model-select.vue'
 import { isValue } from '@/utils/czr-util'
 import Sortable from 'sortablejs'
 
@@ -393,7 +396,7 @@ const state: any = reactive({
   ID: route.params.id,
   form: {
     tips: '',
-    model: '',
+    model: {},
     components: [],
     knowledges: [],
     prologue: '',
@@ -413,6 +416,10 @@ const state: any = reactive({
     show: false,
     transfer: {},
   },
+  modelSelect: {
+    show: false,
+    transfer: {},
+  },
   prologuesAdd: {
     value: '',
   },
@@ -465,6 +472,7 @@ const toBack = () => {
 const onAddKnowledge = () => {
   state.knowledgeSelect.transfer = {
     ids: state.form.knowledges.map((v) => v.id),
+    type: 'knowledge',
   }
   state.knowledgeSelect.show = true
 }
@@ -497,7 +505,31 @@ const onEditPrologue = (row) => {
   }
   row.__edit = false
 }
-const onModel = () => {}
+const getKnowledge = (arr) => {
+  switch (state.knowledgeSelect.transfer.type) {
+    case 'knowledge':
+      {
+        state.form.knowledges.push(...arr)
+      }
+      break
+  }
+}
+const getModel = (val) => {
+  switch (state.modelSelect.transfer.type) {
+    case 'model':
+      {
+        state.form.model = val
+      }
+      break
+  }
+}
+const onModel = () => {
+  state.modelSelect.transfer = {
+    type: 'model',
+    id: state.form.model.id,
+  }
+  state.modelSelect.show = true
+}
 onMounted(() => {
   initDictionary()
   initDetail()

+ 328 - 0
src/views/manage/app/make/model-select.vue

@@ -0,0 +1,328 @@
+<template>
+  <CzrDialog
+    :show="show"
+    title="选择模型"
+    @onClose="$emit('update:show', false)"
+    @onSubmit="onSubmit"
+    width="62.5rem"
+    height="auto"
+  >
+    <div
+      class="flex flex-col rounded-lg bg-[var(--czr-dialog-bg)] p-4"
+      v-loading="state.query.loading"
+    >
+      <div>
+        <CzrForm label-width="80px">
+          <CzrFormColumn
+            class="__czr-table-form-column"
+            :span="8"
+            label="模型类型"
+            v-model:param="state.query.form.modeType"
+            link="select"
+            :options="DictionaryStore.modelTypes.list"
+          />
+          <CzrFormColumn
+            class="__czr-table-form-column"
+            :span="8"
+            label="可用状态"
+            v-model:param="state.query.form.kyStatus"
+            link="select"
+            :options="DictionaryStore.modelStatus"
+          />
+          <CzrFormColumn
+            class="__czr-table-form-column"
+            :span="8"
+            label-width="10px"
+            v-model:param="state.text"
+            placeholder="按名称搜索"
+            :prefix-icon="Search"
+          />
+        </CzrForm>
+      </div>
+      <div
+        class="mt-4 grid max-h-[600px] flex-1 grid-cols-1 gap-4 overflow-y-auto"
+      >
+        <template v-for="row in state.query.result.data">
+          <div
+            class="model cursor-pointer"
+            :class="{
+              active: state.selected?.id == row.id,
+            }"
+            @click="state.selected = row"
+          >
+            <div class="flex">
+              <img
+                src="@/assets/images/model/model-default-logo.png"
+                class="mr-2.5 h-[3.25rem] w-[3.25rem]"
+              />
+              <div class="flex flex-1 flex-col justify-around overflow-hidden">
+                <div class="text-[1.25rem] font-bold text-[#2E3238]" v-title>
+                  {{ row.name }}
+                </div>
+                <div class="flex">
+                  <div
+                    class="flex h-[1.25rem] items-center justify-center rounded-[0.13rem] bg-gradient-to-r from-[#FF9E2D] to-[#FFB92D] px-[0.38rem] text-[0.63rem] font-bold text-[#ffffff]"
+                  >
+                    {{ DictionaryStore.modelTypes.map.get(row.type) }}
+                  </div>
+                </div>
+              </div>
+              <div class="mt-[0.25rem] ml-auto">
+                <div
+                  v-if="row.status == 1"
+                  class="rounded-xs bg-[var(--czr-success-color)] px-2.5 py-1 text-xs text-[#ffffff]"
+                >
+                  可用
+                </div>
+                <div
+                  v-else
+                  class="rounded-xs bg-[#A7ADB9] px-2.5 py-1 text-xs text-[#ffffff]"
+                >
+                  需申请
+                </div>
+              </div>
+            </div>
+            <div
+              class="mt-2.5 mb-auto h-[3rem] text-sm text-[#606266]"
+              style="line-height: 1.4rem"
+              v-title="{ lines: 2 }"
+            >
+              {{ row.description }}
+            </div>
+            <div
+              class="mt-2 flex items-center gap-2.5 text-[0.75rem] text-[#6F7889]"
+            >
+              <div>
+                {{ DictionaryStore.modelProvides.map.get(row.pluginClass) }}
+              </div>
+              <div>|</div>
+              <div>(创建单位)</div>
+              <div>|</div>
+              <div>{{ row.createNickName }}</div>
+              <div>|</div>
+              <div>{{ YMDHms(row.updateTime) }}</div>
+            </div>
+            <div
+              class="mt-2 flex items-center gap-2.5 text-[0.75rem] text-[#6F7889]"
+            >
+              <div
+                class="__hover ml-auto text-xs text-[var(--czr-main-color)]"
+                @click.capture.stop="onSwitch(row)"
+              >
+                查看详情
+              </div>
+            </div>
+            <template v-if="state.selected?.id == row.id">
+              <div
+                class="absolute top-0 right-0 h-[2rem] w-[2rem] bg-[url('@/assets/images/knowledge/checked.png')]"
+              ></div>
+            </template>
+          </div>
+        </template>
+      </div>
+    </div>
+    <CzrDialog
+      :show="state.apply.show"
+      title="模型申请"
+      @onClose="state.apply.show = false"
+      @onSubmit="onApply"
+      width="42.5rem"
+      height="auto"
+    >
+      <div class="bm-form">
+        <CzrForm ref="ref_apply">
+          <div class="__czr-title_1">申请留言</div>
+          <CzrFormColumn
+            required
+            class="__czr-table-form-column"
+            :span="24"
+            label-width="0px"
+            v-model:param="state.apply.text"
+            type="textarea"
+            :rows="8"
+          />
+        </CzrForm>
+      </div>
+    </CzrDialog>
+  </CzrDialog>
+</template>
+
+<script setup lang="ts">
+import {
+  computed,
+  getCurrentInstance,
+  nextTick,
+  onMounted,
+  reactive,
+  ref,
+  watch,
+} from 'vue'
+import { debounce } from 'lodash'
+import { datasetsGetAllByPage } from '@/api/modules/knowledge'
+import { useAppStore, useDialogStore, useDictionaryStore } from '@/stores'
+import { Search } from '@element-plus/icons-vue'
+import { pluginGetInstanceList } from '@/api/modules/model'
+import { YMDHms } from '@/utils/czr-util'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import CzrDialog from '@/components/czr-ui/CzrDialog.vue'
+
+const DialogStore = useDialogStore()
+const DictionaryStore = useDictionaryStore()
+const emit = defineEmits(['update:show', 'refresh'])
+const { proxy } = getCurrentInstance()
+const props = defineProps({
+  show: { default: false },
+  transfer: <any>{},
+})
+const state: any = reactive({
+  selected: null,
+  text: '',
+  query: {
+    init: false,
+    loading: false,
+    page: {
+      pageNum: 1,
+      pageSize: 20,
+    },
+    form: {},
+    formReal: {},
+    result: {
+      total: 0,
+      data: [],
+    },
+  },
+  apply: {
+    show: false,
+    text: '',
+  },
+})
+const ref_apply = ref()
+watch(
+  () => props.show,
+  (n) => {
+    if (n) {
+      state.selected = null
+      onSearch()
+    }
+  },
+)
+const setText = debounce((v) => {
+  state.query.form.keyword = v
+}, 1000)
+watch(
+  () => state.text,
+  (n) => {
+    setText(n)
+  },
+)
+watch(
+  () => state.query.form,
+  (n) => {
+    if (state.query.init) {
+      onSearch()
+    }
+  },
+  { deep: true },
+)
+const onSearch = () => {
+  state.query.formReal = JSON.parse(JSON.stringify(state.query.form))
+  onPage(1, 100000)
+}
+const onPage = (pageNum, pageSize) => {
+  setTimeout(() => {
+    state.query.init = true
+  }, 100)
+  state.query.page = {
+    pageNum: pageNum,
+    pageSize: pageSize,
+  }
+  const params = {
+    page: state.query.page.pageNum,
+    size: state.query.page.pageSize,
+  }
+  //  添加表单参数
+  for (const [k, v] of Object.entries(state.query.formReal)) {
+    if (proxy.$czrUtil.isValue(v)) {
+      params[k] = v
+    }
+  }
+  state.query.loading = true
+  pluginGetInstanceList(params)
+    .then(({ data }: any) => {
+      state.query.result.total = data.total
+      state.query.result.data = data.records
+      state.query.result.data.forEach((v: any) => {
+        if (v.id == props.transfer.id) {
+          state.selected = v
+        }
+      })
+    })
+    .catch(() => {})
+    .finally(() => {
+      state.query.loading = false
+    })
+}
+const onSubmit = () => {
+  if (!state.selected) {
+    ElMessage.warning('请选择模型!')
+    return
+  }
+  if (state.selected.status == 1) {
+    emit('refresh', state.selected)
+    emit('update:show', false)
+  } else {
+    state.apply.text = ''
+    state.apply.show = true
+  }
+}
+const onApply = () => {
+  ref_apply.value
+    .submit()
+    .then(() => {
+      DialogStore.confirm({
+        content: `请确认是否提交?`,
+        onSubmit: () => {
+          state.loading = true
+          state.apply.show = false
+          emit('refresh', state.selected)
+          emit('update:show', false)
+        },
+        onCancel: () => {},
+      })
+    })
+    .catch((e) => {
+      ElMessage({
+        message: e[0].message,
+        grouping: true,
+        type: 'warning',
+      })
+    })
+}
+onMounted(() => {
+  initDictionary()
+})
+const initDictionary = () => {
+  DictionaryStore.initModelTypes()
+  DictionaryStore.initModelProvides()
+}
+</script>
+
+<style lang="scss" scoped>
+.model {
+  width: 100%;
+  background-image: url('@/assets/images/model/model-icon-7.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  padding: 1rem 1.5rem;
+  border-radius: 10px;
+  box-shadow: 0rem 0.25rem 0.63rem 0rem rgba(40, 83, 247, 0.05);
+  border: var(--czr-border);
+  display: flex;
+  flex-direction: column;
+  position: relative;
+  overflow: hidden;
+  &.active {
+    border-color: var(--czr-main-color);
+  }
+}
+</style>

+ 4 - 11
src/views/manage/knowledge/knowledge-card.vue

@@ -21,14 +21,13 @@
         <div
           class="__hover relative col-span-1 flex flex-col overflow-hidden rounded-lg border-1 border-[#E6E8EA] px-6 py-4"
           :class="{
-            active: state.selectedMap.has(item.id),
             'border-[var(--czr-main-color)]': state.selectedMap.has(item.id),
           }"
           @click="onSelect(item)"
         >
           <div class="flex">
             <img
-              src="../../../assets/images/knowledge/knowledge-item-icon-2.png"
+              src="@/assets/images/knowledge/knowledge-item-icon-2.png"
               class="mr-2.5 h-11 w-11"
             />
             <div class="flex flex-1 flex-col justify-around overflow-hidden">
@@ -159,15 +158,9 @@ const onPage = (pageNum, pageSize) => {
   datasetsGetAllByPage(params)
     .then(({ data }: any) => {
       state.query.result.total = data.totalElements
-      state.query.result.data = data.content
-      state.query.result.data.forEach((v) => {
-        if (props.ids.includes(v.id)) {
-          if (!props.multiple) {
-            state.selectedMap.clear()
-          }
-          state.selectedMap.set(v.id, v)
-        }
-      })
+      state.query.result.data = data.content.filter(
+        (v) => !props.ids.includes(v.id),
+      )
     })
     .catch(() => {})
     .finally(() => {

+ 0 - 198
src/views/manage/model/model-card.vue

@@ -1,198 +0,0 @@
-<template>
-  <div
-    class="flex flex-col rounded-lg bg-[var(--czr-dialog-bg)] p-4"
-    v-loading="state.query.loading"
-  >
-    <div>
-      <CzrFormColumn
-        class="__czr-table-form-column"
-        label-width="0px"
-        :span="8"
-        :offset="16"
-        v-model:param="state.text"
-        placeholder="按名称搜索"
-        :prefix-icon="Search"
-      />
-    </div>
-    <div
-      class="mt-2 grid max-h-[600px] flex-1 grid-cols-2 gap-4 overflow-y-auto"
-    >
-      <template v-for="item in state.query.result.data">
-        <div
-          class="__hover relative col-span-1 flex flex-col overflow-hidden rounded-lg border-1 border-[#E6E8EA] px-6 py-4"
-          :class="{
-            active: state.selectedMap.has(item.id),
-            'border-[var(--czr-main-color)]': state.selectedMap.has(item.id),
-          }"
-          @click="onSelect(item)"
-        >
-          <div class="flex">
-            <img
-              src="../../../assets/images/knowledge/knowledge-item-icon-2.png"
-              class="mr-2.5 h-11 w-11"
-            />
-            <div class="flex flex-1 flex-col justify-around overflow-hidden">
-              <div class="flex items-center">
-                <div
-                  class="flex-1 text-[1.25rem] font-bold text-[#2E3238]"
-                  v-title
-                >
-                  {{ item.name }}
-                </div>
-              </div>
-              <div
-                class="flex items-center gap-2.5 text-[0.75rem] text-[#6F7889]"
-              >
-                <div>文档数:{{ item.docCount }}</div>
-                <div>|</div>
-                <div>字符:{{ item.wordCounts }}</div>
-                <div>|</div>
-                <div>创建者:{{ item.userName }}</div>
-              </div>
-            </div>
-          </div>
-          <div
-            class="mt-2.5 mb-auto text-sm text-[#606266]"
-            style="line-height: 1.4rem"
-            v-title="{ lines: 2 }"
-          >
-            {{ item.description }}
-          </div>
-          <template v-if="state.selectedMap.has(item.id)">
-            <div
-              class="absolute top-0 right-0 h-[2rem] w-[2rem] bg-[url('@/assets/images/knowledge/checked.png')]"
-            ></div>
-          </template>
-        </div>
-      </template>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import {
-  computed,
-  getCurrentInstance,
-  nextTick,
-  onMounted,
-  reactive,
-  ref,
-  watch,
-} from 'vue'
-import { useAppStore, useDialogStore, useDictionaryStore } from '@/stores'
-import { useRouter } from 'vue-router'
-import { datasetsGetAllByPage } from '@/api/modules/knowledge'
-import CzrFormColumn from '@/components/czr-ui/CzrFormColumn.vue'
-import { Search } from '@element-plus/icons-vue'
-import { debounce } from 'lodash'
-
-const router = useRouter()
-const DictionaryStore = useDictionaryStore()
-const DialogStore = useDialogStore()
-const AppStore = useAppStore()
-const emit = defineEmits(['update:show', 'refresh'])
-const { proxy } = getCurrentInstance()
-const props = defineProps({
-  multiple: { default: false },
-  ids: { default: () => <any>[] },
-})
-const state: any = reactive({
-  selectedMap: new Map(),
-  text: '',
-  query: {
-    init: false,
-    loading: false,
-    page: {
-      pageNum: 1,
-      pageSize: 20,
-    },
-    form: {},
-    formReal: {},
-    result: {
-      total: 0,
-      data: [],
-    },
-  },
-})
-const setText = debounce((v) => {
-  state.query.form.name = v
-}, 1000)
-watch(
-  () => state.text,
-  (n) => {
-    setText(n)
-  },
-)
-watch(
-  () => state.query.form,
-  (n) => {
-    if (state.query.init) {
-      onSearch()
-    }
-  },
-  { deep: true },
-)
-const onSearch = () => {
-  state.query.formReal = JSON.parse(JSON.stringify(state.query.form))
-  onPage(1, 100000)
-}
-const onPage = (pageNum, pageSize) => {
-  setTimeout(() => {
-    state.query.init = true
-  }, 100)
-  state.query.page = {
-    pageNum: pageNum,
-    pageSize: pageSize,
-  }
-  const params = {
-    tenantId: AppStore.tenantInfo?.id,
-    page: state.query.page.pageNum,
-    size: state.query.page.pageSize,
-  }
-  //  添加表单参数
-  for (const [k, v] of Object.entries(state.query.formReal)) {
-    if (proxy.$czrUtil.isValue(v)) {
-      params[k] = v
-    }
-  }
-  state.query.loading = true
-  datasetsGetAllByPage(params)
-    .then(({ data }: any) => {
-      state.query.result.total = data.totalElements
-      state.query.result.data = data.content
-      state.query.result.data.forEach((v) => {
-        if (props.ids.includes(v.id)) {
-          if (!props.multiple) {
-            state.selectedMap.clear()
-          }
-          state.selectedMap.set(v.id, v)
-        }
-      })
-    })
-    .catch(() => {})
-    .finally(() => {
-      state.query.loading = false
-    })
-}
-const onSelect = (row) => {
-  if (state.selectedMap.has(row.id)) {
-    state.selectedMap.delete(row.id)
-  } else {
-    if (!props.multiple) {
-      state.selectedMap.clear()
-    }
-    state.selectedMap.set(row.id, row)
-  }
-}
-const getData = () => {
-  return Array.from(state.selectedMap.values())
-}
-onMounted(() => {
-  onSearch()
-})
-defineExpose({
-  getData,
-})
-</script>
-
-<style lang="scss" scoped></style>