liudong
2024-08-05 25aa31845cebacd5f522dd6fa2fad4ea700e8544
src/views/dmx/model/index.vue
@@ -1,138 +1,296 @@
<template>
  <div class="container">
    <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"
                show-add-button
                @tab-click="changeTabs"
                @add="handleAdd"
                @delete="handleDelete"
                show-add-button
                auto-switch
              >
                <!--                <a-tab-pane key="1" :title="$t('cardList.tab.title.all')">-->
                <!--                  <QualityInspection />-->
                <!--                  <TheService />-->
                <!--                  <RulesPreset />-->
                <!--                </a-tab-pane>-->
                <!--                <a-tab-pane key="2" :title="$t('cardList.tab.title.content')">-->
                <!--                  <QualityInspection />-->
                <!--                </a-tab-pane>-->
                <!--                <a-tab-pane key="3" :title="$t('cardList.tab.title.service')">-->
                <!--                  <TheService />-->
                <!--                </a-tab-pane>-->
                <!--                <a-tab-pane key="4" :title="$t('cardList.tab.title.preset')">-->
                <!--                  <RulesPreset />-->
                <!--                </a-tab-pane>-->
                <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"
                >
                  <QualityInspection v-if="activeKey === 1" />
                  <TheService v-if="activeKey === 1" />
                  <RulesPreset v-if="activeKey === 1" />
                  <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="dessert"
                            :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>
                          <div class="arco-btn-group">
                            <a-space class="btn-group">
                              <!-- <editModel></editModel> -->
                              <a-button type="primary" @click="handleEditModel">
                                编辑
                              </a-button>
                            </a-space>
                          </div>
                        </a-card>
                      </div>
                    </div>
                    <div
                      class="card-wrap"
                      v-for="(list, index) of item.llm"
                      :key="index"
                    >
                      <div class="card_wrap_box">
                        <div>
                          <img
                            :style="{
                              width: '100%',
                              transform: 'translateY(-20px)',
                            }"
                            alt="dessert"
                            :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>
                          <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>
                  <QualityInspection v-if="activeKey === 2" />
                  <TheService v-if="activeKey === 3" />
                  <RulesPreset v-if="activeKey === 4" />
                  <CustomSettings v-if="activeKey > 4" />
                              <!-- <editModel></editModel> -->
                            </a-space>
                          </div>
                        </a-card>
                      </div>
                    </div>
                  </div>
                </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: 20px"
            />
            <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"
                  :loading="loading2"
                  @click="handleAddModel"
                >
                  <template #icon>
                    <icon-plus />
                  </template>
                  添加
                </a-button>
              </div>
            </div>
          </a-row>
        </a-card>
      </a-col>
    </a-row>
    <a-modal v-model:visible="visible" @Ok="handleOk" @cancel="handleCancel">
      <template #title> 添加框架 </template>
      <a-form
        ref="formRef"
        :size="form.size"
        :model="form"
        @submit="handleSubmit"
      >
        <a-form-item
          field="name"
          label="标签名"
          :rules="[
            { required: true, message: '不能为空' },
            { minLength: 1, message: '至少一个字符' },
          ]"
          :validate-trigger="['change', 'input']"
        >
          <a-input v-model="form.name" placeholder="请输入标签名" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
  <!-- 添加模型 -->
  <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"
    @refresh-parent="refreshParentMethod"
    v-if="tabShow"
  ></addTableName>
</template>
<script lang="ts" setup>
  import { ref, reactive, nextTick } from 'vue';
  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 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: '全部',
      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,
    },
  });
  const isDeleteDialogVisible = ref(false); //删除提醒
  const apiUrl = ref('http://127.0.0.1:5173');
  // const httpUrl = import.meta.env.VITE_API_BASE_URL;
  // console.log(apiUrl.value, 777);
  const modalList = ref({});
  const tabKey = ref('key');
  const changeTabs = (val) => {
    tabKey.value = val;
  };
  const handleDelete = (key: any) => {
    data.value = data.value.filter((item) => item.key !== key);
  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;
    editList.value.llm_factory = tabKey.value;
  };
  const editList = ref({ llm_factory: '' });
  //增加模型子类
  const handleAddModel = () => {
    // if (tabKey.value == 'key') {
    //   tabShow.value = true;
    // } else {
    //   modelType.value = 2;
    //   editList.value.llm_factory = tabKey.value;
    //   show.value = true;
    //   title.value = '添加模式';
    // }
    modelType.value = 2;
    editList.value.llm_factory = tabKey.value;
    show.value = true;
    title.value = '添加模式';
  };
  //编辑模型子类
  const handleEditModel = (val) => {
    if (tabKey.value == 'key') {
      tabShow.value = true;
    } 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(key, 45455);
    // tabData.value = tabData.value.filter((item) => item.key !== key);
    if (key !== 'key') {
      Reflect.deleteProperty(tabData.value, key);
      await deleteLlmFactory(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) => {
    formRef.value?.validate().then((res) => {
      if (res) {
        return;
      }
@@ -146,19 +304,33 @@
    });
    nextTick(() => {
      visible.value = true;
    })
    });
    return false;
  };
  const handleCancel = () => {
    formRef.value.resetFields();
    visible.value = false;
  // const handleCancel = () => {
  //   formRef.value.resetFields();
  //   visible.value = false;
  // };
  // const handleSubmit = ({ values, errors }) => {
  //   this.$refs.formRef.validate().then((res, a, b) => {
  //     debugger;
  //     console.log('values', values);
  //   });
  // };
  //获取模型列表
  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);
  };
  const handleSubmit = ({ values, errors }) => {
    this.$refs.formRef.validate().then((res, a, b) => {
      debugger;
      console.log('values', values);
    });
  queryModel();
  const refreshParentMethod = () => {
    queryModel();
    // 这里执行需要的操作
  };
</script>
@@ -211,4 +383,151 @@
      }
    }
  }
  .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;
      max-height: 240px;
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;
    margin: 30px;
    transition: all 0.3s;
    border: 1px solid var(--color-neutral-3);
    border-radius: 4px;
    position: relative;
    .arco-btn-group {
      position: absolute;
      right: 10px;
      top: 90px;
    }
    &:hover {
      transform: translateY(-4px);
      // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1);
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;
    margin: 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);
    }
  }
  .card-wrap {
    width: 320px;
    height: 350px;
    margin: 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>