|  |  | 
 |  |  | <template> | 
 |  |  |   <div class="container"> | 
 |  |  |     <Breadcrumb :items="['大模型', '大模型管理']" /> | 
 |  |  |     <Breadcrumb :items="['大模型', '模型管理']" /> | 
 |  |  |  | 
 |  |  |     <a-row :gutter="20" align="stretch"> | 
 |  |  |       <a-col :span="24"> | 
 |  |  |         <a-card class="general-card" :title="$t('大模型管理')"> | 
 |  |  |         <a-card | 
 |  |  |           class="general-card" | 
 |  |  |           style="min-height: 130px" | 
 |  |  |           :title="$t('大模型管理')" | 
 |  |  |         > | 
 |  |  |           <a-row justify="space-between"> | 
 |  |  |             <a-col :span="24"> | 
 |  |  |             <a-col :span="24" class="table_add_clore" v-if="loading"> | 
 |  |  |               <a-tabs | 
 |  |  |                 :active-key="activeKey" | 
 |  |  |                 :default-active-key="tabKey" | 
 |  |  |                 type="line" | 
 |  |  |                 :editable="true" | 
 |  |  |                 @tab-click="changeTabs" | 
 |  |  |                 @add="handleAdd" | 
 |  |  |                 @delete="handleDelete" | 
 |  |  |                 show-add-button | 
 |  |  |                 auto-switch | 
 |  |  |               > | 
 |  |  |                 <a-tab-pane | 
 |  |  |                   v-for="(item, index) of data" | 
 |  |  |                   :key="item.key" | 
 |  |  |                   :title="item.title" | 
 |  |  |                   :closable="index >= 4" | 
 |  |  |                   v-for="(item, index) in tabData" | 
 |  |  |                   :key="index" | 
 |  |  |                   :title="index" | 
 |  |  |                   :closable="Object.keys(tabData).length >= 4" | 
 |  |  |                 > | 
 |  |  |                   <div style="display: flex; flex-wrap: wrap;justify-content: space-between;"> | 
 |  |  |                     <div class="card-wrap"    v-for="(item, index) of data" :key="index"> | 
 |  |  |                       <a-card :bordered="false" hoverable > | 
 |  |  |                         <template #cover> | 
 |  |  |                           <div | 
 |  |  |                           > | 
 |  |  |                   <a-scrollbar | 
 |  |  |                     style="height: calc(100vh - 320px); overflow: auto" | 
 |  |  |                   > | 
 |  |  |                     <div | 
 |  |  |                       style="display: flex; flex-wrap: wrap" | 
 |  |  |                       class="card_content" | 
 |  |  |                     > | 
 |  |  |                       <div class="card-wrap"> | 
 |  |  |                         <div class="card_wrap_box"> | 
 |  |  |                           <div class="card_wrap_box_img"> | 
 |  |  |                             <img | 
 |  |  |                               :style="{ width: '100%', transform: 'translateY(-20px)' }" | 
 |  |  |                               alt="dessert" | 
 |  |  |                               src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" | 
 |  |  |                               :style="{ | 
 |  |  |                                 width: '100%', | 
 |  |  |                               }" | 
 |  |  |                               alt="暂无图片" | 
 |  |  |                               :src="item.logo ? httpUrl + item.logo : pdfImg" | 
 |  |  |                             /> | 
 |  |  |                           </div> | 
 |  |  |                         </template> | 
 |  |  |                         <div class="arco-card-body-content"> | 
 |  |  |                           <div class="arco-card-body-content-title"> | 
 |  |  |                             {{ item.title }} | 
 |  |  |                           <a-card :bordered="false" hoverable> | 
 |  |  |                             <div class="arco-card-body-content"> | 
 |  |  |                               <div | 
 |  |  |                                 class="arco-card-body-content-title" | 
 |  |  |                                 style="word-wrap: break-word" | 
 |  |  |                               > | 
 |  |  |                                 {{ item.tags }} | 
 |  |  |                               </div> | 
 |  |  |                               <!-- <div class="arco-card-body-content-dec">{{ | 
 |  |  |                             list.type | 
 |  |  |                           }}</div> --> | 
 |  |  |                             </div> | 
 |  |  |                           </a-card> | 
 |  |  |                           <div class="arco-btn-group"> | 
 |  |  |                             <a-space class="btn-group"> | 
 |  |  |                               <!-- <editModel></editModel> --> | 
 |  |  |                               <a-button @click="handleDeleteModel(item, 1)"> | 
 |  |  |                                 删除 | 
 |  |  |                               </a-button> | 
 |  |  |                               <a-button | 
 |  |  |                                 type="primary" | 
 |  |  |                                 @click="handleEditModel(item, 1)" | 
 |  |  |                               > | 
 |  |  |                                 编辑 | 
 |  |  |                               </a-button> | 
 |  |  |                             </a-space> | 
 |  |  |                           </div> | 
 |  |  |                         </div> | 
 |  |  |                         <div style="position: absolute; bottom: 1rem; right: 1rem;"> | 
 |  |  |                           <a-space> | 
 |  |  |                             <a-button> | 
 |  |  |                               删除 | 
 |  |  |                             </a-button> | 
 |  |  |                             <editModel></editModel> | 
 |  |  |                           </a-space> | 
 |  |  |                       </div> | 
 |  |  |                       <div | 
 |  |  |                         class="card-wrap" | 
 |  |  |                         v-for="(list, index) of item.llm" | 
 |  |  |                         :key="index" | 
 |  |  |                       > | 
 |  |  |                         <div class="card_wrap_box"> | 
 |  |  |                           <div class="card_wrap_box_img"> | 
 |  |  |                             <img | 
 |  |  |                               :style="{ | 
 |  |  |                                 width: '100%', | 
 |  |  |                               }" | 
 |  |  |                               alt="暂无图片" | 
 |  |  |                               :src="list.logo ? httpUrl + list.logo : pdfImg" | 
 |  |  |                             /> | 
 |  |  |                             <!--   src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" --> | 
 |  |  |                           </div> | 
 |  |  |                           <a-card :bordered="false" hoverable> | 
 |  |  |                             <div class="arco-card-body-content"> | 
 |  |  |                               <div class="arco-card-body-content-title"> | 
 |  |  |                                 {{ list.name }} | 
 |  |  |                               </div> | 
 |  |  |                               <div class="arco-card-body-content-dec">{{ | 
 |  |  |                                 list.type | 
 |  |  |                               }}</div> | 
 |  |  |                             </div> | 
 |  |  |                           </a-card> | 
 |  |  |                           <div class="arco-btn-group"> | 
 |  |  |                             <a-space class="btn-group"> | 
 |  |  |                               <a-button @click="handleDeleteModel(list)"> | 
 |  |  |                                 删除 | 
 |  |  |                               </a-button> | 
 |  |  |                               <!-- <a-button | 
 |  |  |                                 type="primary" | 
 |  |  |                                 @click="handleEditModel(list)" | 
 |  |  |                               > | 
 |  |  |                                 编辑 | 
 |  |  |                               </a-button> --> | 
 |  |  |  | 
 |  |  |                               <!-- <editModel></editModel> --> | 
 |  |  |                             </a-space> | 
 |  |  |                           </div> | 
 |  |  |                         </div> | 
 |  |  |                       </a-card> | 
 |  |  |                       </div> | 
 |  |  |                     </div> | 
 |  |  |                   </div> | 
 |  |  |                   </a-scrollbar> | 
 |  |  |                 </a-tab-pane> | 
 |  |  |               </a-tabs> | 
 |  |  |             </a-col> | 
 |  |  |             <div> </div> | 
 |  |  |             <a-input-search | 
 |  |  |               :placeholder="$t('cardList.searchInput.placeholder')" | 
 |  |  |               style="width: 240px; position: absolute; top: 60px; right: 60px" | 
 |  |  |             /> | 
 |  |  |             <div style="position: absolute; top: 60px; right: 20px"> | 
 |  |  |               <addModel></addModel> | 
 |  |  |             <div class="box_right" v-if="Object.keys(tabData).length > 0"> | 
 |  |  |               <!-- <div class="search_input"> | 
 |  |  |                 <a-input-search | 
 |  |  |                   :placeholder="$t('cardList.searchInput.placeholder')" | 
 |  |  |                   style="width: 240px" | 
 |  |  |                 /> | 
 |  |  |               </div> --> | 
 |  |  |               <div> | 
 |  |  |                 <a-button | 
 |  |  |                   type="primary" | 
 |  |  |                   @click="handleAddModel" | 
 |  |  |                   :disabled="addBtn" | 
 |  |  |                 > | 
 |  |  |                   <template #icon> | 
 |  |  |                     <icon-plus /> | 
 |  |  |                   </template> | 
 |  |  |                   添加 | 
 |  |  |                 </a-button> | 
 |  |  |               </div> | 
 |  |  |             </div> | 
 |  |  |  | 
 |  |  |           </a-row> | 
 |  |  |         </a-card> | 
 |  |  |       </a-col> | 
 |  |  |     </a-row> | 
 |  |  |     <!-- 添加模型 --> | 
 |  |  |     <addPageModel | 
 |  |  |       v-model:show="show" | 
 |  |  |       :task_id="task_id" | 
 |  |  |       :type="modelType" | 
 |  |  |       :title="title" | 
 |  |  |       :editList="editList" | 
 |  |  |       @refresh-parent="refreshParentMethod" | 
 |  |  |       v-if="show" | 
 |  |  |     ></addPageModel> | 
 |  |  |     <!-- 添加tab模式 --> | 
 |  |  |     <addTableName | 
 |  |  |       v-model:tabShow="tabShow" | 
 |  |  |       :nameList="editList" | 
 |  |  |       :title="title" | 
 |  |  |       @refresh-parent="refreshParentMethod" | 
 |  |  |       v-if="tabShow" | 
 |  |  |     ></addTableName> | 
 |  |  |   </div> | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | <script lang="ts" setup> | 
 |  |  |   import { ref, reactive, nextTick } from 'vue'; | 
 |  |  |   import editModel from '@/views/dmx/model/components/editModel.vue'; | 
 |  |  |   import addPageModel from './components/addPageModel.vue'; | 
 |  |  |   import addTableName from './components/addTableName.vue'; | 
 |  |  |   import { | 
 |  |  |     modelList, | 
 |  |  |     modelmyLlms, | 
 |  |  |     deleteLlm, | 
 |  |  |     deleteLlmFactory, | 
 |  |  |     getFactoryDetail, | 
 |  |  |   } from '@/api/model'; | 
 |  |  |   import { Modal, Message } from '@arco-design/web-vue'; | 
 |  |  |   import { userModelState } from '@/store'; | 
 |  |  |  | 
 |  |  |   import QualityInspection from './components/quality-inspection.vue'; | 
 |  |  |   import TheService from './components/the-service.vue'; | 
 |  |  |   import RulesPreset from './components/rules-preset.vue'; | 
 |  |  |   import CustomSettings from './components/custom-settings.vue'; | 
 |  |  |   import addModel from "@/views/dmx/model/components/addModel.vue"; | 
 |  |  |   import editModel from "@/views/dmx/model/components/editModel.vue"; | 
 |  |  |   import pdfImg from '@/assets/images/icon-chart.png'; | 
 |  |  |  | 
 |  |  |   const modelStore = userModelState(); | 
 |  |  |   let count = 5; | 
 |  |  |   const addBtn = ref(false); | 
 |  |  |   const activeKey = ref(1); | 
 |  |  |   const data = ref([ | 
 |  |  |     { | 
 |  |  |       key: 1, | 
 |  |  |       title: '全部', | 
 |  |  |       title: 'key', | 
 |  |  |       content: 'Content of Tab Panel 1', | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       key: 2, | 
 |  |  |       title: '内容质检', | 
 |  |  |       title: 'Ollama', | 
 |  |  |       content: 'Content of Tab Panel 2', | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       key: 3, | 
 |  |  |       title: '开通服务', | 
 |  |  |       title: 'Xinference', | 
 |  |  |       content: 'Content of Tab Panel 3', | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       key: 4, | 
 |  |  |       title: '规则预置', | 
 |  |  |       content: 'Content of Tab Panel 4', | 
 |  |  |     }, | 
 |  |  |   ]); | 
 |  |  | const changeTabs = (val) => { | 
 |  |  |   activeKey.value = val; | 
 |  |  | } | 
 |  |  |   const handleAdd = () => { | 
 |  |  |     visible.value = true; | 
 |  |  |   const tabData = ref({ | 
 |  |  |     key: { | 
 |  |  |       tags: '添加key', | 
 |  |  |       id: 1, | 
 |  |  |       live: 1, | 
 |  |  |     }, | 
 |  |  |   }); | 
 |  |  |  | 
 |  |  |   const isDeleteDialogVisible = ref(false); //删除提醒 | 
 |  |  |  | 
 |  |  |   const modalList = ref({}); | 
 |  |  |   const tabKey = ref('key'); | 
 |  |  |   const changeTabs = async (val) => { | 
 |  |  |     tabKey.value = val; | 
 |  |  |     await getFactory(); | 
 |  |  |   }; | 
 |  |  |   const handleDelete = (key: any) => { | 
 |  |  |     data.value = data.value.filter((item) => item.key !== key); | 
 |  |  |  | 
 |  |  |   const httpUrl = modelStore.hrefUrl; | 
 |  |  |   const show = ref(false); | 
 |  |  |   const tabShow = ref(false); | 
 |  |  |   const title = ref('添加模式'); | 
 |  |  |   const task_id = ref(1); | 
 |  |  |   const modelType = ref(1); | 
 |  |  |   const handleAdd = () => { | 
 |  |  |     tabShow.value = true; | 
 |  |  |     title.value = '添加模型'; | 
 |  |  |     editList.value.llm_factory = tabKey.value; | 
 |  |  |   }; | 
 |  |  |   const editList = ref<any>({ llm_factory: '' }); | 
 |  |  |   //增加模型子类 | 
 |  |  |   const handleAddModel = () => { | 
 |  |  |     modelType.value = 2; | 
 |  |  |     editList.value = [{ llm_factory: '' }]; | 
 |  |  |     editList.value.llm_factory = tabKey.value; | 
 |  |  |     show.value = true; | 
 |  |  |     title.value = '添加模式'; | 
 |  |  |   }; | 
 |  |  |   //编辑模型子类 | 
 |  |  |   const handleEditModel = (val, type) => { | 
 |  |  |     console.log(val, 6766); | 
 |  |  |     if (type == 1) { | 
 |  |  |       tabShow.value = true; | 
 |  |  |       editList.value = val; | 
 |  |  |       title.value = '编辑模型'; | 
 |  |  |       editList.value.llm_factory = tabKey.value; | 
 |  |  |     } else { | 
 |  |  |       modelType.value = 2; | 
 |  |  |       task_id.value = val.id; | 
 |  |  |       show.value = true; | 
 |  |  |       title.value = '编辑'; | 
 |  |  |       editList.value = val; | 
 |  |  |       editList.value.llm_factory = tabKey.value; | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   //删除模型 | 
 |  |  |   const handleDeleteModel = (val, type) => { | 
 |  |  |     if (type == 1) { | 
 |  |  |       handleDelete(val); | 
 |  |  |     } else { | 
 |  |  |       Modal.confirm({ | 
 |  |  |         title: '警告', | 
 |  |  |         content: '确认删除吗', | 
 |  |  |         okText: '确定', | 
 |  |  |         cancelText: '取消', | 
 |  |  |         onOk: async () => { | 
 |  |  |           const factory = tabKey.value; | 
 |  |  |           const res = await deleteLlm({ | 
 |  |  |             llm_factory: tabKey.value, | 
 |  |  |             llm_name: val.name, | 
 |  |  |           }); | 
 |  |  |  | 
 |  |  |           if ((res as any).code == 0) { | 
 |  |  |             queryModel(); | 
 |  |  |             tabKey.value = factory; | 
 |  |  |           } else { | 
 |  |  |           } | 
 |  |  |         }, | 
 |  |  |         onCancel: () => {}, | 
 |  |  |       }); | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   //父级模型 | 
 |  |  |   const handleDelete = async (key: any) => { | 
 |  |  |     console.log(tabData.value[key]); | 
 |  |  |     if (tabData.value[key].llm.length > 0) { | 
 |  |  |       Message.error('请先删除子模型'); | 
 |  |  |       return; | 
 |  |  |     } | 
 |  |  |     if (key !== 'key') { | 
 |  |  |       const res = await deleteLlmFactory(key); | 
 |  |  |       if ((res as any).code == 200) { | 
 |  |  |         Reflect.deleteProperty(tabData.value, key); | 
 |  |  |         queryModel(); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const visible = ref(false); | 
 |  |  |   const formRef = ref(null); | 
 |  |  |   const formRef = ref(); | 
 |  |  |  | 
 |  |  |   const form = reactive({ | 
 |  |  |     size: 'medium', | 
 |  |  |     name: '', | 
 |  |  |   }); | 
 |  |  |   const handleOk = () => { | 
 |  |  |     count += 1; | 
 |  |  |     formRef.value.validate().then((res) => { | 
 |  |  |     formRef.value?.validate().then((res) => { | 
 |  |  |       if (res) { | 
 |  |  |         return; | 
 |  |  |       } | 
 |  |  | 
 |  |  |     }); | 
 |  |  |     nextTick(() => { | 
 |  |  |       visible.value = true; | 
 |  |  |  | 
 |  |  |     }) | 
 |  |  |     }); | 
 |  |  |     return false; | 
 |  |  |   }; | 
 |  |  |   const handleCancel = () => { | 
 |  |  |     formRef.value.resetFields(); | 
 |  |  |     visible.value = false; | 
 |  |  |  | 
 |  |  |   //获取模型列表 | 
 |  |  |   const loading = ref(false); | 
 |  |  |   const queryModel = async () => { | 
 |  |  |     const res = await modelmyLlms(); | 
 |  |  |     modalList.value = res.data; | 
 |  |  |     loading.value = true; | 
 |  |  |     tabData.value = Object.assign({}, tabData.value, res.data); | 
 |  |  |     tabData.value = filterObject(tabData.value, 1); | 
 |  |  |     tabKey.value = Object.keys(tabData.value)[0]; | 
 |  |  |     await getFactory(); | 
 |  |  |   }; | 
 |  |  |   const handleSubmit = ({ values, errors }) => { | 
 |  |  |     this.$refs.formRef.validate().then((res, a, b) => { | 
 |  |  |       debugger; | 
 |  |  |       console.log('values', values); | 
 |  |  |   queryModel(); | 
 |  |  |   //返回满足条件的对象 | 
 |  |  |   const filterObject = (obj, threshold) => { | 
 |  |  |     return Object.keys(obj) | 
 |  |  |       .filter((key) => obj[key].added == 1) | 
 |  |  |       .reduce((result, key) => { | 
 |  |  |         result[key] = obj[key]; | 
 |  |  |         return result; | 
 |  |  |       }, {}); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const refreshParentMethod = () => { | 
 |  |  |     queryModel(); | 
 |  |  |     // 这里执行需要的操作 | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const getFactory = async () => { | 
 |  |  |     const { data } = await getFactoryDetail({ | 
 |  |  |       factory_name: tabKey.value, | 
 |  |  |     }); | 
 |  |  |  | 
 |  |  |     if (data.set_type == 2) { | 
 |  |  |       addBtn.value = true; | 
 |  |  |     } else { | 
 |  |  |       addBtn.value = false; | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  | </script> | 
 |  |  |  | 
 |  |  | 
 |  |  |       font-size: 14px; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   :deep(.arco-list-col) { | 
 |  |  |     display: flex; | 
 |  |  |     flex-direction: row; | 
 |  |  | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   :deep(.arco-tabs-nav-tab) { | 
 |  |  |     flex: none; | 
 |  |  |     width: 60%; | 
 |  |  |   } | 
 |  |  |   .table_add_clore { | 
 |  |  |     :deep(.arco-tabs-nav-add-btn .arco-icon-hover::before) { | 
 |  |  |       top: 50%; | 
 |  |  |       left: 50%; | 
 |  |  |       width: 20px; | 
 |  |  |       height: 20px; | 
 |  |  |       transform: translate(-50%, -50%); | 
 |  |  |       border-radius: 0; | 
 |  |  |       background-color: #165dff; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     :deep(.arco-tabs-nav-add-btn .arco-icon-hover .arco-icon) { | 
 |  |  |       color: #fff; | 
 |  |  |     } | 
 |  |  |     // :deep(.arco-tabs-nav) { | 
 |  |  |     //   max-width: 60%; | 
 |  |  |     // } | 
 |  |  |  | 
 |  |  |     :deep(.arco-icon-hover::before) { | 
 |  |  |       top: 50%; | 
 |  |  |       left: 50%; | 
 |  |  |       width: 20px; | 
 |  |  |       height: 20px; | 
 |  |  |       transform: translate(-50%, -50%); | 
 |  |  |       // border-radius: 0; | 
 |  |  |       // background-color: #eee; | 
 |  |  |     } | 
 |  |  |     :deep(.arco-tabs-tab-close-btn) { | 
 |  |  |       display: none; | 
 |  |  |     } | 
 |  |  |     :deep(.arco-tabs-tab-close-btn .arco-icon) { | 
 |  |  |       color: #666; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .box_right { | 
 |  |  |     position: absolute; | 
 |  |  |     top: 60px; | 
 |  |  |     right: 20px; | 
 |  |  |     display: flex; | 
 |  |  |     .search_input { | 
 |  |  |       margin-right: 10px; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .arco-card-body-content { | 
 |  |  |     .arco-card-body-content-title { | 
 |  |  |       font-size: 16px; | 
 |  |  |       color: #333; | 
 |  |  |       margin-bottom: 10px; | 
 |  |  |       font-weight: 400; | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |   .card_content { | 
 |  |  |     .card_wrap_box_img { | 
 |  |  |       // min-height: 200px; | 
 |  |  |       height: 200px; | 
 |  |  |       width: 100%; | 
 |  |  |       img { | 
 |  |  |         width: 100%; /* 或者其他固定宽度 */ | 
 |  |  |         height: 100%; /* 或者其他固定高度 */ | 
 |  |  |         object-fit: cover; /* 不会变形,但可能裁剪图片 */ | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |     .card_wrap_box { | 
 |  |  |       // position: relative; | 
 |  |  |       .arco-btn-group { | 
 |  |  |         position: absolute; | 
 |  |  |         right: 10px; | 
 |  |  |         top: 87%; | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   .card-wrap { | 
 |  |  |     width: 320px; | 
 |  |  |     height: 350px; | 
 |  |  |     margin: 30px; | 
 |  |  |     margin: 20px 30px; | 
 |  |  |     transition: all 0.3s; | 
 |  |  |     border: 1px solid var(--color-neutral-3); | 
 |  |  |     border-radius: 4px; |