|
@@ -1,15 +1,290 @@
|
|
<template>
|
|
<template>
|
|
- 模型纳管
|
|
|
|
|
|
+ <div class="bm-main-box">
|
|
|
|
+ <div class="flex items-center">
|
|
|
|
+ <div class="bm-main-box-title">{{$route.meta.title}}</div>
|
|
|
|
+ <div class="ml-auto flex items-center gap-[var(--czr-gap)]">
|
|
|
|
+ <CzrForm class="bm-filter" label-width="0px" @handleEnter="onSearch">
|
|
|
|
+ <CzrFormColumn
|
|
|
|
+ width="6.68rem"
|
|
|
|
+ class="__czr-table-form-column"
|
|
|
|
+ :span="24"
|
|
|
|
+ label-width="0px"
|
|
|
|
+ v-model:param="state.query.form.group"
|
|
|
|
+ link="select"
|
|
|
|
+ :options="DictionaryStore.knowledgeGroups.list"
|
|
|
|
+ placeholder="模型类型"
|
|
|
|
+ />
|
|
|
|
+ <CzrFormColumn
|
|
|
|
+ width="6.68rem"
|
|
|
|
+ class="__czr-table-form-column"
|
|
|
|
+ :span="24"
|
|
|
|
+ label-width="0px"
|
|
|
|
+ v-model:param="state.query.form.tag"
|
|
|
|
+ link="select"
|
|
|
|
+ :options="DictionaryStore.knowledgeTags.list"
|
|
|
|
+ placeholder="模型状态"
|
|
|
|
+ />
|
|
|
|
+ <CzrFormColumn
|
|
|
|
+ width="15.63rem"
|
|
|
|
+ class="__czr-table-form-column"
|
|
|
|
+ :span="24"
|
|
|
|
+ label-width="0px"
|
|
|
|
+ v-model:param="state.text"
|
|
|
|
+ placeholder="输入关键词以检索"
|
|
|
|
+ :prefix-icon="Search"
|
|
|
|
+ />
|
|
|
|
+ <CzrButton type="add"/>
|
|
|
|
+ </CzrForm>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="overflow-hidden flex-1 mt-[1rem]" v-loading="state.query.loading">
|
|
|
|
+ <CzrTableCard
|
|
|
|
+ class="table-card"
|
|
|
|
+ :page="state.query.page.pageNum"
|
|
|
|
+ :pageSize="state.query.page.pageSize"
|
|
|
|
+ :total="state.query.result.total"
|
|
|
|
+ :data="state.query.result.data"
|
|
|
|
+ @handlePage="onPage"
|
|
|
|
+ :col="2"
|
|
|
|
+ >
|
|
|
|
+ <template #model="{ row, index }">
|
|
|
|
+ <div class="model">
|
|
|
|
+ <div class="flex">
|
|
|
|
+ <img src="@/assets/images/model-default-logo.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
|
|
|
|
+ <div class="flex flex-1 flex-col justify-around overflow-hidden">
|
|
|
|
+ <div class="text-[1.25rem] text-[#2E3238] font-bold" v-title>模型名称</div>
|
|
|
|
+ <div class="flex">
|
|
|
|
+ <div class="h-[1.25rem] rounded-[0.13rem] px-[0.38rem] flex justify-center items-center text-[0.63rem] text-[#ffffff] font-bold bg-gradient-to-r from-[#FF9E2D] to-[#FFB92D]">大预言模型</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="ml-auto mt-[0.25rem]">
|
|
|
|
+ <div v-if="row.enable" class="w-[3.75rem] h-[1.56rem] rounded-[1.25rem] flex justify-center items-center text-[0.75rem] text-[#1E3F92] font-bold bg-gradient-to-r from-[#D5F9FE] to-[#E0DAFF]">
|
|
|
|
+ 已启用
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="text-[0.88rem] text-[#606266] mb-auto mt-[var(--czr-gap)]" style="line-height: 1.4rem" v-title="{lines: 2}">{{row.p3}}</div>
|
|
|
|
+ <div class="flex items-center text-[0.75rem] text-[#6F7889] gap-[var(--czr-gap)]">
|
|
|
|
+ <div>(模型厂商)</div>
|
|
|
|
+ <div>|</div>
|
|
|
|
+ <div>上下文长度:{{row.p5}}</div>
|
|
|
|
+ <div>|</div>
|
|
|
|
+ <div>(创建单位)</div>
|
|
|
|
+ <div>|</div>
|
|
|
|
+ <div>(创建人)</div>
|
|
|
|
+ <div>|</div>
|
|
|
|
+ <div>(更新时间)</div>
|
|
|
|
+ <div class="ml-auto">
|
|
|
|
+ <a-switch
|
|
|
|
+ v-model:checked="row.enable"
|
|
|
|
+ checked-children="启用"
|
|
|
|
+ un-checked-children="停用"
|
|
|
|
+ size="small"
|
|
|
|
+ @click="onSwitch(row)"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ <!-- <el-switch-->
|
|
|
|
+<!-- v-model="row.enable"-->
|
|
|
|
+<!-- class="ml-auto"-->
|
|
|
|
+<!-- width="50"-->
|
|
|
|
+<!-- inline-prompt-->
|
|
|
|
+<!-- active-text="启用"-->
|
|
|
|
+<!-- inactive-text="停用"-->
|
|
|
|
+<!-- size="small"-->
|
|
|
|
+<!-- :change="onSwitch(row)"-->
|
|
|
|
+<!-- />-->
|
|
|
|
+ <el-tooltip content="编辑" effect="light" placement="top">
|
|
|
|
+ <SvgIcon name="czr_edit" size="14" class="__hover" @click.stop="onEdit(row)"/>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <el-tooltip content="删除" effect="light" placement="top">
|
|
|
|
+ <SvgIcon name="czr_del" size="16" class="__hover" @click.stop="onDel(row)"/>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </CzrTableCard>
|
|
|
|
+ </div>
|
|
|
|
+<!-- <detailCom v-model:show="state.detail.show" :transfer="state.detail.transfer" @refresh="onSearch"/>-->
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import {getCurrentInstance, reactive, ref} from "vue";
|
|
|
|
|
|
+import {getCurrentInstance, onMounted, reactive, ref, watch} from "vue";
|
|
|
|
+import { Search } from '@element-plus/icons-vue'
|
|
|
|
+import {debounce} from "lodash";
|
|
|
|
+import {useDialogStore, useDictionaryStore} from "@/stores";
|
|
|
|
+import {ElMessage} from "element-plus";
|
|
|
|
+import {v4} from "uuid";
|
|
|
|
+// import tagsSelect from './tags-select.vue'
|
|
|
|
+// import detailCom from './detail.vue'
|
|
|
|
|
|
|
|
+const DialogStore = useDialogStore();
|
|
|
|
+const DictionaryStore = useDictionaryStore();
|
|
const emit = defineEmits([])
|
|
const emit = defineEmits([])
|
|
const props = defineProps({})
|
|
const props = defineProps({})
|
|
const {proxy}: any = getCurrentInstance()
|
|
const {proxy}: any = getCurrentInstance()
|
|
-const state: any = reactive({})
|
|
|
|
|
|
+const state: any = reactive({
|
|
|
|
+ text: '',
|
|
|
|
+ query: {
|
|
|
|
+ loading: false,
|
|
|
|
+ page: {
|
|
|
|
+ pageNum: 1,
|
|
|
|
+ pageSize: 20
|
|
|
|
+ },
|
|
|
|
+ form: {},
|
|
|
|
+ formReal: {},
|
|
|
|
+ result: {
|
|
|
|
+ total: 0,
|
|
|
|
+ data: []
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ detail: {
|
|
|
|
+ show: false,
|
|
|
|
+ transfer: {}
|
|
|
|
+ },
|
|
|
|
+})
|
|
|
|
+const setText = debounce((v) => {
|
|
|
|
+ state.query.form.name = v
|
|
|
|
+}, 1000)
|
|
|
|
+watch(() => state.text, (n) => {
|
|
|
|
+ setText(n)
|
|
|
|
+})
|
|
|
|
+watch(() => state.query.form, (n) => {
|
|
|
|
+ onSearch()
|
|
|
|
+}, {deep: true})
|
|
|
|
+const onPage = (pageNum, pageSize) => {
|
|
|
|
+ state.query.page = {
|
|
|
|
+ pageNum: pageNum,
|
|
|
|
+ pageSize: pageSize,
|
|
|
|
+ }
|
|
|
|
+ const params = {
|
|
|
|
+ pageNum: state.query.page.pageNum,
|
|
|
|
+ pageSize: 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
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ state.query.result.total = 100
|
|
|
|
+ const arr: any = []
|
|
|
|
+ for (let i = 1; i <= params.pageSize; i++) {
|
|
|
|
+ const n = (params.pageNum - 1) * params.pageSize + i
|
|
|
|
+ arr.push({
|
|
|
|
+ p1: '部门知识库-部门知识库-部门知识库-' + n,
|
|
|
|
+ p2: '王一鸣',
|
|
|
|
+ p3: '只是一个政务服务事项办事指南只是一个政务服务事项办事指南只是一个政务服务事项办事指南只是一个政务服务事项办事指南只是一个政务服务事项办事指南只是一个政务服务事项办事指南',
|
|
|
|
+ p4: n,
|
|
|
|
+ p5: '2980k',
|
|
|
|
+ p6: n % 4,
|
|
|
|
+ p7: n % 2,
|
|
|
|
+ tags: n % 2 ? '1,2,3,41,2,3,41,2,3,41,2,3,41,2,3,4' : '',
|
|
|
|
+ enable: true
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ state.query.result.data = arr
|
|
|
|
+ state.query.loading = false
|
|
|
|
+ }, 1000)
|
|
|
|
+ // state.query.loading = true
|
|
|
|
+ // listRuleLogisticsDataSubscribeInfo(params).then(res => {
|
|
|
|
+ // if (res.code == 200) {
|
|
|
|
+ // state.query.result.total = res.total
|
|
|
|
+ // state.query.result.data = res.rows
|
|
|
|
+ // state.query.loading = false
|
|
|
|
+ // } else {
|
|
|
|
+ // ElMessage.error(res.msg)
|
|
|
|
+ // }
|
|
|
|
+ // }).catch(() => {
|
|
|
|
+ // state.query.loading = false
|
|
|
|
+ // })
|
|
|
|
+}
|
|
|
|
+const onSearch = () => {
|
|
|
|
+ state.query.formReal = JSON.parse(JSON.stringify(state.query.form))
|
|
|
|
+ onPage(1, state.query.page.pageSize)
|
|
|
|
+}
|
|
|
|
+const onReset = () => {
|
|
|
|
+ state.query.page = {
|
|
|
|
+ pageNum: 1,
|
|
|
|
+ pageSize: 20
|
|
|
|
+ }
|
|
|
|
+ state.query.form = {}
|
|
|
|
+ onSearch()
|
|
|
|
+}
|
|
|
|
+const onAdd = () => {
|
|
|
|
+ state.detail.transfer = {
|
|
|
|
+ mode: 'add'
|
|
|
|
+ }
|
|
|
|
+ state.detail.show = true
|
|
|
|
+}
|
|
|
|
+const onEdit = (row) => {
|
|
|
|
+ state.detail.transfer = {
|
|
|
|
+ mode: 'edit',
|
|
|
|
+ id: row.id
|
|
|
|
+ }
|
|
|
|
+ state.detail.show = true
|
|
|
|
+}
|
|
|
|
+const onDel = (row: any) => {
|
|
|
|
+ DialogStore.confirm({
|
|
|
|
+ title: '删除确认',
|
|
|
|
+ content: `${row.p6}个应用正在使用该大模型,删除将导致不可用,请确认是否删除`,
|
|
|
|
+ onSubmit: () => {
|
|
|
|
+ ElMessage.success('删除成功!')
|
|
|
|
+ onSearch()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+const onSwitch = (row) => {
|
|
|
|
+ if (!row.enable) {
|
|
|
|
+ DialogStore.confirm({
|
|
|
|
+ title: '停用确认',
|
|
|
|
+ content: `${row.p6}个应用正在使用该大模型,停用将导致不可用,请确认是否停用`,
|
|
|
|
+ onSubmit: () => {
|
|
|
|
+ ElMessage.success('停用成功!')
|
|
|
|
+ onSearch()
|
|
|
|
+ },
|
|
|
|
+ onCancel: () => {
|
|
|
|
+ row.enable = !row.enable
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage.success('启用成功!')
|
|
|
|
+ onSearch()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+onMounted(() => {
|
|
|
|
+ initDictionary()
|
|
|
|
+ onReset()
|
|
|
|
+})
|
|
|
|
+const initDictionary = () => {
|
|
|
|
+ DictionaryStore.initKnowledgeGroups()
|
|
|
|
+}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
|
+.model {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 10.56rem;
|
|
|
|
+ background-image: url("@/assets/images/model-icon-7.png");
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
+ padding: 1rem 1.5rem;
|
|
|
|
+ border-radius: var(--czr-gap);
|
|
|
|
+ box-shadow: 0rem 0.25rem 0.63rem 0rem rgba(40,83,247,0.05);
|
|
|
|
+ border: var(--czr-border);
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ :deep(.ant-switch-inner) {
|
|
|
|
+ .ant-switch-inner-checked {
|
|
|
|
+ margin-top: 2px;
|
|
|
|
+ }
|
|
|
|
+ .ant-switch-inner-unchecked {
|
|
|
|
+ margin-top: -12px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|