You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
542 lines
16 KiB
Vue
542 lines
16 KiB
Vue
<template>
|
|
<a-spin tip="加载中..." :spinning="loading">
|
|
<div class="page-out">
|
|
<div class="title">
|
|
<div class="search-div">
|
|
<a-input class="search-input" v-model:value="searchValue" placeholder="搜索实例名称…">
|
|
<template #prefix>
|
|
<div class="search-input-icon"></div>
|
|
</template>
|
|
</a-input>
|
|
<a-select
|
|
placeholder="请选择算法"
|
|
class="select-algorithm"
|
|
v-model:value="instanceAlgorithm"
|
|
:options="algorithmOptions"
|
|
/>
|
|
<a-button class="search-button" type="primary" @click="query">查询</a-button>
|
|
</div>
|
|
<a-button class="add-instance" type="primary" :icon="h(PlusOutlined)" @click="changeAddModal(true)">新建算法实例</a-button>
|
|
</div>
|
|
<div class="show-list-div">
|
|
<div class="show-list">
|
|
<div class="item-list" v-for="item in dataList">
|
|
<div class="image-div">
|
|
<img class="image-item" :src="`${VITE_GLOB_API_URL}/${item.cover}`">
|
|
<!--<div class="image-icon">盖板缺失</div> -->
|
|
</div>
|
|
<div class="show-info-div">
|
|
<div class="info-title-div">
|
|
<div class="info-icon"></div>
|
|
<div class="info-title-inner">
|
|
<div class="info-title">{{ item.name }}</div>
|
|
<div style="display: flex;justify-content: space-between;">
|
|
<div class="info-subtitle">{{ item.description? item.description: '暂无描述' }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="info-content-div">
|
|
<div class="content-div">
|
|
<div class="content-title-div">关联算法</div>
|
|
<div class="content-info" v-html="getContentStr(item.algoNames)"></div>
|
|
</div>
|
|
<div class="button-div">
|
|
<div style="margin-bottom: 13px;">
|
|
<a-button class="delete-button" @click="delData(item)">删除</a-button>
|
|
</div>
|
|
<div>
|
|
<a-button class="show-info-button" type="primary" @click="showInfo(item)">查看</a-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- <div class="item-footer">
|
|
<a-button class="item-del" @click="delData(item)">删除</a-button>
|
|
<a-button class="item-show" type="primary" @click="showInfo(item)">查看</a-button>
|
|
</div> -->
|
|
</div>
|
|
</div>
|
|
<div class="pagination-div">
|
|
<a-pagination
|
|
size="small"
|
|
:total="total"
|
|
v-model:current="page"
|
|
v-model:page-size="limit"
|
|
show-size-changer
|
|
show-quick-jumper
|
|
:show-total="total => `共 ${total} 条数据`"
|
|
@change="changePagination"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<a-modal width="853px" v-model:open="addInstanceModal" :footer="false" :closable="false" :destroyOnClose="true" :maskClosable="false" :keyboard="false">
|
|
<AddInstanceModal :modalType="modalType" :showInfoData="showInfoData" :algorithmOptions="algorithmOptions" @changeAddModal="changeAddModal" @query="query"/>
|
|
</a-modal>
|
|
<a-drawer
|
|
width="442px"
|
|
:closable="false"
|
|
v-model:open="showInfoDrawer"
|
|
placement="right"
|
|
rootClassName="instance-show-info-drawer"
|
|
>
|
|
<ShowInfoDrawer :showInfoData="showInfoData" @changeDrawerModal="changeDrawerModal" @changeAddModal="changeAddModal"/>
|
|
</a-drawer>
|
|
</div>
|
|
</a-spin>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, h, onMounted, createVNode } from "vue"
|
|
import { ExclamationCircleOutlined, PlusOutlined, } from '@ant-design/icons-vue';
|
|
import AddInstanceModal from "./AddInstanceModal.vue";
|
|
import ShowInfoDrawer from "./ShowInfoDrawer.vue";
|
|
import { getAppEnvConfig } from '@/utils/env';
|
|
import { GetAlgoInstanceList, DeleteAlgoInstance } from '@/api/demo/aiinstance'
|
|
import { GetAlgorithmsRepositoryList } from '@/api/demo/ailist'
|
|
import { DataListType } from './utils'
|
|
import { message, Modal } from "ant-design-vue";
|
|
|
|
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
|
const searchValue = ref('')
|
|
const instanceAlgorithm = ref()
|
|
const addInstanceModal = ref(false)
|
|
const showInfoDrawer = ref(false)
|
|
const page = ref('1')
|
|
const limit = ref('10')
|
|
const total = ref('0')
|
|
const dataList = ref<DataListType[]>([])
|
|
const loading = ref(false)
|
|
const algorithmOptions = ref([])
|
|
const showInfoData = ref({})
|
|
const modalType = ref('')
|
|
onMounted(() => {
|
|
GetAlgorithmsRepositoryList({page:1,limit: 999}).then(res => {
|
|
algorithmOptions.value = res.items.map(item => {
|
|
return {
|
|
label: item.name,
|
|
value: item.id,
|
|
modelLabels: item.modelLabels
|
|
}
|
|
})
|
|
})
|
|
query()
|
|
})
|
|
const query = () => {
|
|
loading.value = true
|
|
let params = {
|
|
page: page.value,
|
|
limit: limit.value,
|
|
key: searchValue.value,
|
|
}
|
|
GetAlgoInstanceList(params).then(res => {
|
|
console.log('res',res)
|
|
total.value = res.total
|
|
dataList.value = res.items
|
|
}).finally(() => {
|
|
loading.value = false
|
|
})
|
|
}
|
|
const changePagination = () => {
|
|
query()
|
|
}
|
|
const changeAddModal = (type: boolean, isInsert:boolean = true) => {
|
|
console.log('type',type,'isInsert',isInsert)
|
|
if(type){
|
|
if(isInsert){
|
|
modalType.value = 'insert'
|
|
}else{
|
|
modalType.value = 'update'
|
|
changeDrawerModal(false)
|
|
}
|
|
}
|
|
addInstanceModal.value = type
|
|
}
|
|
const showInfo = (item) => {
|
|
showInfoData.value = item
|
|
changeDrawerModal(true)
|
|
}
|
|
const changeDrawerModal = (type: boolean) => {
|
|
showInfoDrawer.value = type
|
|
}
|
|
const delData = (item) => {
|
|
Modal.confirm({
|
|
title: `确认删除 ${item.name} 吗?`,
|
|
icon: createVNode(ExclamationCircleOutlined),
|
|
okText: '确认',
|
|
cancelText: '取消',
|
|
centered: true,
|
|
onOk() {
|
|
return DeleteAlgoInstance({id: item.id}).then(res => {
|
|
message.success("删除成功")
|
|
query()
|
|
})
|
|
},
|
|
});
|
|
}
|
|
const getContentStr = (list: string[]) => {
|
|
return list.map( item => `#${item}`).join('<br/>')
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.page-out{
|
|
padding: 16px 30px 33px 17px;
|
|
width: 100%;
|
|
height: calc(100vh - 80px);
|
|
.title{
|
|
height: 58px;
|
|
background: #fff;
|
|
padding-left: 28px;
|
|
padding-right: 36px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 17px;
|
|
.search-div{
|
|
display: flex;
|
|
align-items: center;
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 16px;
|
|
line-height: 28px;
|
|
.search-input{
|
|
width: 232px;
|
|
height: 36px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #30384F;
|
|
margin-right: 13px;
|
|
.search-input-icon{
|
|
width: 18px;
|
|
height: 18px;
|
|
background-image: url('/public/ailist/search_input_icon.png');
|
|
}
|
|
}
|
|
.select-algorithm{
|
|
margin-right: 13px;
|
|
:deep(.ant-select-selector){
|
|
width: 191px;
|
|
height: 36px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #30384F;
|
|
}
|
|
:deep(.ant-select-selection-placeholder){
|
|
line-height: 34px;
|
|
}
|
|
}
|
|
.search-button{
|
|
width: 80px;
|
|
height: 36px;
|
|
background: #0B60BD;
|
|
border-radius: 4px;
|
|
font-family: PingFangSC-Medium;
|
|
font-weight: 500;
|
|
font-size: 16px;
|
|
color: #FFFFFF;
|
|
line-height: 22px;
|
|
}
|
|
}
|
|
.add-instance{
|
|
width: 148px;
|
|
height: 36px;
|
|
background: #0B60BD;
|
|
border-radius: 4px;
|
|
font-family: PingFangSC-Medium;
|
|
font-weight: 500;
|
|
font-size: 16px;
|
|
color: #FFFFFF;
|
|
line-height: 22px;
|
|
}
|
|
}
|
|
.show-list-div{
|
|
width: 100%;
|
|
height: calc(100% - 60px);
|
|
background: #fff;
|
|
padding: 26px 26px 0px 26px;
|
|
|
|
.show-list{
|
|
min-height: calc(100% - 69px);
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 20px;
|
|
padding-bottom: 20px;
|
|
overflow: auto;
|
|
scrollbar-width: none;
|
|
::-webkit-scrollbar{
|
|
width: 0;
|
|
height: 0;
|
|
}
|
|
.item-list{
|
|
width: 300px;
|
|
height: 321px;
|
|
background: #FFFFFF;
|
|
box-shadow: 5px 18px 32px 0px rgba(28,29,34,0.1);
|
|
border-radius: 10px;
|
|
.image-div{
|
|
position: relative;
|
|
width: 300px;
|
|
height: 200px;
|
|
border-top-left-radius: 8px;
|
|
border-top-right-radius: 8px;
|
|
margin-bottom: 10px;
|
|
.image-item{
|
|
width: 300px;
|
|
height: 200px;
|
|
border-top-left-radius: 8px;
|
|
border-top-right-radius: 8px;
|
|
}
|
|
.image-icon{
|
|
position: absolute;
|
|
top: 0px;
|
|
left: 0px;
|
|
width: 46px;
|
|
height: 16px;
|
|
background: linear-gradient( 320deg, #6C90F5 0%, #3A57E8 100%);
|
|
border-radius: 8px 0px 8px 0px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 9px;
|
|
color: #FFFFFF;
|
|
line-height: 12px;
|
|
}
|
|
}
|
|
.show-info-div{
|
|
padding-left: 9px;
|
|
padding-right: 12px;
|
|
.info-title-div{
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 4px;
|
|
.info-icon{
|
|
width: 3px;
|
|
height: 34px;
|
|
background: #0B60BD;
|
|
margin-right: 5px;
|
|
}
|
|
.info-title-inner{
|
|
width: calc(100% - 8px);
|
|
.info-title{
|
|
font-family: PingFangSC-Medium;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
color: #1C1D22;
|
|
line-height: 20px;
|
|
margin-bottom: 5px;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.info-subtitle{
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 11px;
|
|
color: rgba(28,29,34,0.5);
|
|
line-height: 15px;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.show-more-info{
|
|
display: flex;
|
|
align-items: center;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
.show-more-span{
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 11px;
|
|
color: #1C1D22;
|
|
line-height: 15px;
|
|
margin-right: 6px;
|
|
}
|
|
.show-more-icon{
|
|
width: 12px;
|
|
height: 8px;
|
|
background-image: url('/public/instance/instance_show_more_icon.png');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.info-content-div{
|
|
display: flex;
|
|
.content-div{
|
|
width: 200px;
|
|
margin-top: 4px;
|
|
padding-top: 8px;
|
|
border-top: 1px dashed rgba(151, 151, 151, 0.37);
|
|
margin-right: 27px;
|
|
.content-title-div{
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 47px;
|
|
height: 19px;
|
|
background: rgba(216, 216, 216,0.34);
|
|
border-radius: 2px;
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 10px;
|
|
color: #1C1D22;
|
|
line-height: 14px;
|
|
}
|
|
.content-info{
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 10px;
|
|
color: #1C1D22;
|
|
line-height: 14px;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
}
|
|
.button-div{
|
|
.delete-button{
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 54px;
|
|
height: 23px;
|
|
border-radius: 2px;
|
|
border: 1px solid #F2F2F2;
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 11px;
|
|
color: #E3150E;
|
|
line-height: 15px;
|
|
}
|
|
.show-info-button{
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 54px;
|
|
height: 23px;
|
|
background: #0B60BD;
|
|
border-radius: 2px;
|
|
border: 1px solid #0B60BD;
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 11px;
|
|
color: #FFFFFF;
|
|
line-height: 15px;
|
|
}
|
|
}
|
|
}
|
|
// .info-content-div{
|
|
// width: 100%;
|
|
// height: 66px;
|
|
// background-image: url('/public/instance/instance_list_item_info_content.png');
|
|
// padding-top: 8px;
|
|
// padding-left: 12px;
|
|
// margin-bottom: 13px;
|
|
// .content-raw{
|
|
// display: flex;
|
|
// .content-label{
|
|
// font-family: PingFangSC-Regular;
|
|
// font-weight: 400;
|
|
// font-size: 12px;
|
|
// color: #1C1D22;
|
|
// line-height: 17px;
|
|
// margin-right: 11px;
|
|
// }
|
|
// .content-value{
|
|
// font-family: PingFangSC-Medium;
|
|
// font-weight: 500;
|
|
// font-size: 12px;
|
|
// color: #1C1D22;
|
|
// line-height: 17px;
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
// .item-footer{
|
|
// width: 100%;
|
|
// height: 23px;
|
|
// display: flex;
|
|
// align-items: center;
|
|
// justify-content: end;
|
|
// padding-right: 12px;
|
|
// .item-del{
|
|
// width: 54px;
|
|
// height: 23px;
|
|
// border-radius: 2px;
|
|
// border: 1px solid #F2F2F2;
|
|
// margin-right: 7px;
|
|
// font-family: PingFangSC-Regular;
|
|
// font-weight: 400;
|
|
// font-size: 11px;
|
|
// color: #E3150E;
|
|
// line-height: 15px;
|
|
// }
|
|
// .item-show{
|
|
// width: 54px;
|
|
// height: 23px;
|
|
// background: #0B60BD;
|
|
// border-radius: 2px;
|
|
// border: 1px solid #0B60BD;
|
|
// font-family: PingFangSC-Regular;
|
|
// font-weight: 400;
|
|
// font-size: 11px;
|
|
// color: #FFFFFF;
|
|
// line-height: 15px;
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
.pagination-div{
|
|
padding-right: 32px;
|
|
// width: 100%;
|
|
height: 69px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: end;
|
|
border-top: 1px solid rgba(28,29,34,0.08);
|
|
margin-left: -26px;
|
|
margin-right: -26px;
|
|
padding-right: 45px;
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|
|
<style lang="scss">
|
|
.instance-show-more-info-popover{
|
|
.ant-popover-inner{
|
|
background-color: rgba(5, 5, 5, 0.56);
|
|
}
|
|
.show-more-content{
|
|
width: 232px;
|
|
.content-raw{
|
|
display: flex;
|
|
.content-label{
|
|
font-family: PingFangSC-Regular;
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #FFFFFF;
|
|
line-height: 17px;
|
|
margin-right: 11px;
|
|
}
|
|
.content-value{
|
|
font-family: PingFangSC-Medium;
|
|
font-weight: 500;
|
|
font-size: 12px;
|
|
color: #FFFFFF;
|
|
line-height: 17px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.instance-show-info-drawer{
|
|
.ant-drawer-body{
|
|
padding: 0px;
|
|
}
|
|
}
|
|
</style> |