| <template> | 
|   <div class="container"> | 
|     <Breadcrumb :items="['大模型', '模型管理']" /> | 
|   | 
|     <a-row :gutter="20" align="stretch"> | 
|       <a-col :span="24"> | 
|         <a-card | 
|           class="general-card" | 
|           style="min-height: 130px" | 
|           :title="$t('大模型管理')" | 
|         > | 
|           <a-row justify="space-between"> | 
|             <a-col :span="24" class="table_add_clore" v-if="loading"> | 
|               <a-tabs | 
|                 :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) in tabData" | 
|                   :key="index" | 
|                   :title="index" | 
|                   :closable="Object.keys(tabData).length >= 4" | 
|                 > | 
|                   <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%', | 
|                               }" | 
|                               alt="暂无图片" | 
|                               :src="item.logo" | 
|                             /> | 
|                           </div> | 
|                           <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 | 
|                                 type="primary" | 
|                                 @click="handleEditModel(item, 1)" | 
|                               > | 
|                                 编辑 | 
|                               </a-button> | 
|                             </a-space> | 
|                           </div> | 
|                         </div> | 
|                       </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" | 
|                             /> | 
|                             <!--   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> | 
|                       </div> | 
|                     </div> | 
|                   </a-scrollbar> | 
|                 </a-tab-pane> | 
|               </a-tabs> | 
|             </a-col> | 
|             <div> </div> | 
|             <div class="box_right"> | 
|               <!-- <div class="search_input"> | 
|                 <a-input-search | 
|                   :placeholder="$t('cardList.searchInput.placeholder')" | 
|                   style="width: 240px" | 
|                 /> | 
|               </div> --> | 
|               <div> | 
|                 <!-- <addModel></addModel> --> | 
|                 <a-button type="primary" @click="handleAddModel"> | 
|                   <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, | 
|   } from '@/api/model'; | 
|   import { Modal, Message } from '@arco-design/web-vue'; | 
|   | 
|   let count = 5; | 
|   const activeKey = ref(1); | 
|   const data = ref([ | 
|     { | 
|       key: 1, | 
|       title: 'key', | 
|       content: 'Content of Tab Panel 1', | 
|     }, | 
|     { | 
|       key: 2, | 
|       title: 'Ollama', | 
|       content: 'Content of Tab Panel 2', | 
|     }, | 
|     { | 
|       key: 3, | 
|       title: 'Xinference', | 
|       content: 'Content of Tab Panel 3', | 
|     }, | 
|   ]); | 
|   const tabData = ref({ | 
|     key: { | 
|       tags: '添加key', | 
|       id: 1, | 
|     }, | 
|   }); | 
|   | 
|   const isDeleteDialogVisible = ref(false); //删除提醒 | 
|   | 
|   const modalList = ref({}); | 
|   const tabKey = ref('key'); | 
|   const changeTabs = (val) => { | 
|     tabKey.value = val; | 
|   }; | 
|   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({ 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) => { | 
|     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.code == 200) { | 
|         Reflect.deleteProperty(tabData.value, key); | 
|         queryModel(); | 
|       } | 
|     } | 
|   }; | 
|   | 
|   const visible = ref(false); | 
|   const formRef = ref(null); | 
|   | 
|   const form = reactive({ | 
|     size: 'medium', | 
|     name: '', | 
|   }); | 
|   const handleOk = () => { | 
|     count += 1; | 
|     formRef.value?.validate().then((res) => { | 
|       if (res) { | 
|         return; | 
|       } | 
|       data.value = data.value.concat({ | 
|         key: count, | 
|         title: `${form.name}`, | 
|         content: ``, | 
|       }); | 
|       visible.value = false; | 
|       activeKey.value = count; | 
|     }); | 
|     nextTick(() => { | 
|       visible.value = true; | 
|     }); | 
|     return 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); | 
|   }; | 
|   queryModel(); | 
|   | 
|   const refreshParentMethod = () => { | 
|     queryModel(); | 
|     // 这里执行需要的操作 | 
|   }; | 
| </script> | 
|   | 
| <script lang="ts"> | 
|   export default { | 
|     name: 'Card', | 
|   }; | 
| </script> | 
|   | 
| <style scoped lang="less"> | 
|   .container { | 
|     padding: 0 20px 20px 20px; | 
|     :deep(.arco-list-content) { | 
|       overflow-x: hidden; | 
|     } | 
|   | 
|     :deep(.arco-card-meta-title) { | 
|       font-size: 14px; | 
|     } | 
|   } | 
|   | 
|   :deep(.arco-list-col) { | 
|     display: flex; | 
|     flex-direction: row; | 
|     flex-wrap: wrap; | 
|     justify-content: space-between; | 
|   } | 
|   | 
|   :deep(.arco-list-item) { | 
|     width: 33%; | 
|   } | 
|   | 
|   :deep(.block-title) { | 
|     margin: 0 0 12px 0; | 
|     font-size: 14px; | 
|   } | 
|   :deep(.list-wrap) { | 
|     // min-height: 140px; | 
|     .list-row { | 
|       align-items: stretch; | 
|       .list-col { | 
|         margin-bottom: 16px; | 
|       } | 
|     } | 
|     :deep(.arco-space) { | 
|       width: 100%; | 
|       .arco-space-item { | 
|         &:last-child { | 
|           flex: 1; | 
|         } | 
|       } | 
|     } | 
|   } | 
|   :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 .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; | 
|       img { | 
|         max-height: 190px; | 
|       } | 
|     } | 
|     .card_wrap_box { | 
|       // position: relative; | 
|       .arco-btn-group { | 
|         position: absolute; | 
|         right: 10px; | 
|         top: 87%; | 
|       } | 
|     } | 
|   } | 
|   | 
|   .card-wrap { | 
|     width: 320px; | 
|     height: 350px; | 
|     margin: 20px 30px; | 
|     transition: all 0.3s; | 
|     border: 1px solid var(--color-neutral-3); | 
|     border-radius: 4px; | 
|     position: relative; | 
|     &:hover { | 
|       transform: translateY(-4px); | 
|       // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); | 
|     } | 
|     :deep(.arco-card) { | 
|       height: 100%; | 
|       border-radius: 4px; | 
|       .arco-card-body { | 
|         height: 100%; | 
|         .arco-space { | 
|           width: 100%; | 
|           height: 100%; | 
|           .arco-space-item { | 
|             height: 100%; | 
|             &:last-child { | 
|               flex: 1; | 
|             } | 
|             .arco-card-meta { | 
|               height: 100%; | 
|               display: flex; | 
|               flex-flow: column; | 
|               .arco-card-meta-content { | 
|                 flex: 1; | 
|                 .arco-card-meta-description { | 
|                   margin-top: 8px; | 
|                   color: rgb(var(--gray-6)); | 
|                   line-height: 20px; | 
|                   font-size: 12px; | 
|                 } | 
|               } | 
|               .arco-card-meta-footer { | 
|                 margin-top: 0; | 
|               } | 
|             } | 
|           } | 
|         } | 
|       } | 
|     } | 
|     :deep(.arco-card-meta-title) { | 
|       display: flex; | 
|       align-items: center; | 
|   | 
|       // To prevent the shaking | 
|       line-height: 28px; | 
|     } | 
|     :deep(.arco-skeleton-line) { | 
|       &:last-child { | 
|         display: flex; | 
|         justify-content: flex-end; | 
|         margin-top: 20px; | 
|       } | 
|     } | 
|   } | 
| </style> |