Newer
Older
dxCard-admin / src / views / super / airag / aimodel / AiModelList.vue
YFJ on 23 Sep 11 KB 项目推送
<template>
  <div class="model">
    <!--查询区域-->
    <div class="jeecg-basic-table-form-container">
      <a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol" style="background-color: #f7f8fc !important;">
        <a-row :gutter="24">
          <a-col :lg="6">
            <a-form-item name="name" label="模板名称">
              <JInput v-model:value="queryParam.name" />
            </a-form-item>
          </a-col>
          <a-col :lg="6">
            <a-form-item name="modelType" label="模板类型">
              <JDictSelectTag v-model:value="queryParam.modelType" dict-code="model_type" />
            </a-form-item>
          </a-col>
          <a-col :xl="6" :lg="7" :md="8" :sm="24">
            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
              <a-col :lg="6">
                <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
                <a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
              </a-col>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <a-row :span="24" class="model-row">
      <a-col :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24">
        <a-card class="add-knowledge-card" @click="handleAdd">
          <div class="flex">
            <Icon icon="ant-design:plus-outlined" class="add-knowledge-card-icon" size="20"></Icon>
            <span class="add-knowledge-card-title">添加模型</span>
          </div>
        </a-card>
      </a-col>
      <a-col :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24" v-for="item in modalList" v-if="modalList && modalList.length>0">
        <a-card class="model-card" @click="handleEditClick(item)">
          <div class="model-header">
            <div class="flex">
              <img :src="getImage(item.provider)" class="header-img" />
              <div class="header-text">{{ item.name }}</div>
            </div>
          </div>
          <div class="mt-6">
            <ul>
              <li class="flex mr-14">
                <span class="label">模型类型</span>
                <span class="described">{{ item.modelType_dictText }}</span>
              </li>
              <li class="flex mr-14 mt-6">
                <span class="label">基础模型</span>
                <span class="described">{{ item.modelName }}</span>
              </li>
              <li class="flex mr-14 mt-6">
                <span class="label">创建者</span>
                <span class="described">{{ item.createBy_dictText || item.createBy }}</span>
              </li>
            </ul>
          </div>
          <div class="model-btn">
            <a-button class="model-icon" size="small" @click.prevent.stop="handleEditClick(item)">
              <Icon icon="ant-design:edit-outlined"></Icon>
            </a-button>
            <a-dropdown placement="bottomRight" :trigger="['click']" :getPopupContainer="(node) => node.parentNode">
              <div class="ant-dropdown-link pointer model-icon" @click.prevent.stop>
                <Icon icon="ant-design:ellipsis-outlined"></Icon>
              </div>
              <template #overlay>
                <a-menu>
                  <!--<a-menu-item key="param" @click="handleParamClick(item.id)">
                    <Icon icon="ant-design:setting-outlined" size="16"></Icon>
                    <span class="ml-4">模型参数配置</span>
                  </a-menu-item>-->
                  <a-menu-item key="delete" @click.prevent.stop="handleDeleteClick(item)">
                    <Icon icon="ant-design:delete-outlined" size="16"></Icon> 删除
                  </a-menu-item>
                </a-menu>
              </template>
            </a-dropdown>
          </div>
        </a-card>
      </a-col>
    </a-row>
    <Pagination
      v-if="modalList.length > 0"
      :current="pageNo"
      :page-size="pageSize"
      :page-size-options="pageSizeOptions"
      :total="total"
      :showQuickJumper="true"
      :showSizeChanger="true"
      @change="handlePageChange"
      class="list-footer"
      size="small"
      :show-total="() => `共${total}条` "
    />
  </div>

  <!--添加模型弹窗-->
  <AiModelModal @register="registerModal" @success="reload"></AiModelModal>
</template>

<script lang="ts">
  import { reactive, ref } from 'vue';
  import AiModelModal from './components/AiModelModal.vue';
  import { useModal } from '@/components/Modal';
  import { deleteModel, list } from './model.api';
  import { imageList } from './model.data';
  import { Pagination } from 'ant-design-vue';
  import JInput from '@/components/Form/src/jeecg/components/JInput.vue';
  import JSelectUser from '@/components/Form/src/jeecg/components/JSelectUser.vue';
  import JDictSelectTag from '@/components/Form/src/jeecg/components/JDictSelectTag.vue';

  export default {
    name: 'ModelList',
    components: {
      JDictSelectTag,
      JSelectUser,
      JInput,
      AiModelModal,
      Pagination,
    },
    setup() {
      //模型列表
      const modalList = ref([]);

      const [registerModal, { openModal }] = useModal();

      //当前页数
      const pageNo = ref<number>(1);
      //每页条数
      const pageSize = ref<number>(10);
      //总条数
      const total = ref<number>(0);
      //可选择的页数
      const pageSizeOptions = ref<any>(['10', '20', '30']);
      //查询参数
      const queryParam = reactive<any>({});
      //查询区域label宽度
      const labelCol = reactive({
        xs: 24,
        sm: 4,
        xl: 6,
        xxl: 6,
      });
      //查询区域组件宽度
      const wrapperCol = reactive({
        xs: 24,
        sm: 20,
      });
      //查询区域表单的ref
      const formRef = ref();

      //页面初始化执行列表查询
      reload();

      /**
       * 新增
       */
      async function handleAdd() {
        openModal(true, {});
      }

      /**
       * 编辑
       *
       * @param item
       */
      function handleEditClick(item) {
        openModal(true, {
          id: item.id,
        });
      }

      /**
       * 重新加载数据
       */
      function reload() {
        let params = {
          pageNo: pageNo.value,
          pageSize: pageSize.value,
          column: 'createTime',
          order: 'desc'
        };
        Object.assign(params, queryParam);
        list(params).then((res) => {
          if (res.success) {
            modalList.value = res.result.records;
            total.value = res.result.total;
          } else {
            modalList.value = [];
            total.value = 0;
          }
        });
      }

      /**
       * 分页改变事件
       * @param page
       * @param current
       */
      function handlePageChange(page, current) {
        pageNo.value = page;
        pageSize.value = current;
        reload();
      }

      /**
       * 获取图片
       * @param name
       */
      const getImage = (name) => {
        return imageList.value[name];
      };

      /**
       * 删除模型
       * @param item
       */
      async function handleDeleteClick(item) {
        if(modalList.value.length == 1 && pageNo.value > 1) {
          pageNo.value = pageNo.value - 1;
        }
        await deleteModel({ id: item.id, name: item.name }, reload);
      }

      /**
       * 查询
       */
      function searchQuery() {
        pageNo.value = 1;
        reload();
      }

      /**
       * 重置
       */
      function searchReset() {
        formRef.value.resetFields();
        queryParam.createBy = '';
        //刷新数据
        reload();
      }

      /**
       * 参数配置点击事件
       *
       * @param id
       */
      function handleParamClick(id) {}

      return {
        handleAdd,
        handleEditClick,
        registerModal,
        modalList,
        reload,
        pageNo,
        pageSize,
        pageSizeOptions,
        total,
        handlePageChange,
        getImage,
        handleDeleteClick,
        searchQuery,
        searchReset,
        queryParam,
        labelCol,
        wrapperCol,
        formRef,
        handleParamClick,
      };
    },
  };
</script>

<style scoped lang="less">
  .model {
    height: calc(100vh - 115px);
    background: #f7f8fc;
    padding: 24px;
    overflow-y: auto;
    .model-row {
      max-height: calc(100% - 100px);
      margin-top: 20px;
      overflow-y: auto;
      .model-header {
        position: relative;
        font-size: 14px;
        .header-img {
          width: 32px;
          height: 32px;
          margin-right: 12px;
        }
        .header-text {
          font-size: 16px;
          font-weight: bold;
          color: #354052;
          width: calc(100% - 80px);
          overflow: hidden;
          align-content: center;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }

  .label {
    font-weight: 400;
    font-size: 12px;
    align-self: center;
    color: #8a8f98;
    overflow-wrap: break-word;
  }
  .described {
    font-weight: 400;
    margin-left: 14px;
    display: inline-block;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    font-size: 12px;
  }

  .flex {
    display: flex;
  }

  :deep(.ant-card .ant-card-body) {
    padding: 16px;
  }

  .mr-14 {
    margin-right: 14px;
  }
  .mt-6 {
    margin-top: 6px;
  }

  .ml-4 {
    margin-left: 4px;
  }

  .model-btn {
    position: absolute;
    right: 4px;
    top: 6px;
    height: auto;
    display: none;
  }
  .model-card {
    margin-right: 20px;
    margin-bottom: 20px;
    background: #fcfcfd;
    border: 1px solid #f0f0f0;
    box-shadow: 0 2px 4px #e6e6e6;
    transition: all 0.3s ease;
    border-radius: 10px;
    height: 152px;
    cursor: pointer;
  }
  .model-card:hover {
    box-shadow: 0 6px 12px #d0d3d8;
    .model-btn {
      display: flex;
    }
  }
  .pointer {
    cursor: pointer;
  }
  .list-footer {
    text-align: right;
    margin-top: 5px;
  }
  .jeecg-basic-table-form-container {
    padding: 0;
    :deep(.ant-form) {
      background-color: transparent;
    }
    .table-page-search-submitButtons {
      display: block;
      margin-bottom: 24px;
      white-space: nowrap;
    }
  }

  .add-knowledge-card {
    margin-bottom: 20px;
    background: #fcfcfd;
    border: 1px solid #f0f0f0;
    box-shadow: 0 2px 4px #e6e6e6;
    transition: all 0.3s ease;
    border-radius: 10px;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    font-size: 16px;
    cursor: pointer;
    height: 152px;
    width: calc(100% - 20px);
    .add-knowledge-card-icon {
      padding: 8px;
      color: #1f2329;
      background-color: #f5f6f7;
      margin-right: 12px;
    }
    .add-knowledge-card-title {
      font-size: 16px;
      color:#1f2329;
      font-weight: 400;
      align-self: center;
    }
  }

  .add-knowledge-card:hover {
    box-shadow: 0 6px 12px #d0d3d8;
  }
  .model-icon{
    background-color: unset;
    border: none;
    margin-right: 2px;
  }
  .model-icon:hover{
    color: #000000;
    background-color: #e9ecf2;
    border: none;
  }
  .ant-dropdown-link{
    font-size: 14px;
    height: 24px;
    padding: 0 7px;
    border-radius: 4px;
    align-content: center;
    text-align: center;
  }
</style>