forked from JointCloud/JCC-RIP
Merge pull request 'task list page' (#211) from annzee/JCC-RIP:cetc into master
This commit is contained in:
commit
b269835e6e
|
@ -45,6 +45,9 @@
|
|||
"menu": {
|
||||
"taskManagement": "Task",
|
||||
"taskList": "Task",
|
||||
"aiList": "AI Task",
|
||||
"hpcList": "HPC Task",
|
||||
"cloudList": "Cloud Task",
|
||||
"jobTask": "TaskList",
|
||||
"strategyManagement": "Strategy Management",
|
||||
"schedulingStrategy": "Schedule Management",
|
||||
|
@ -98,7 +101,8 @@
|
|||
"storageMana": "Storage Mgmt",
|
||||
"appObserve": "App Monitoring",
|
||||
"logMana": "Log Mgmt",
|
||||
"monitorSelectPcm": "JCCE"
|
||||
"monitorSelectPcm": "JCCE",
|
||||
"fileManagement": "File Management"
|
||||
},
|
||||
"check": {
|
||||
"input": "Please Input",
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
"menu": {
|
||||
"taskManagement": "任务管理",
|
||||
"taskList": "任务列表",
|
||||
"aiList": "智算任务列表",
|
||||
"hpcList": "超算任务列表",
|
||||
"cloudList": "数算任务列表",
|
||||
"jobTask": "作业任务",
|
||||
"strategyManagement": "策略管理",
|
||||
"schedulingStrategy": "调度策略",
|
||||
|
@ -98,7 +101,8 @@
|
|||
"storageMana": "存储管理",
|
||||
"appObserve": "应用观测",
|
||||
"logMana": "日志管理",
|
||||
"monitorSelectPcm": "云际算力网基础平台"
|
||||
"monitorSelectPcm": "云际算力网基础平台",
|
||||
"fileManagement": "文件管理"
|
||||
},
|
||||
"check": {
|
||||
"input": "请输入",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
|
@ -56,6 +56,9 @@
|
|||
<el-dropdown-item v-if="menus.includes('systemManagement')" @click.native="toSetting">
|
||||
{{ $t('menu.systemManagement') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="!menus.includes('fileManagement')" @click.native="toFileManagement">
|
||||
{{ $t('menu.fileManagement') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided @click.native="logout">
|
||||
<span style="display:block;">{{ $t('message.logout') }}</span>
|
||||
</el-dropdown-item>
|
||||
|
@ -165,6 +168,10 @@ export default {
|
|||
this.$store.dispatch('user/setRouteType', 'warnManagement')
|
||||
this.$router.push({ path: '/warnManagement/warnList' })
|
||||
},
|
||||
toFileManagement() {
|
||||
this.$store.dispatch('user/setRouteType', 'fileManagement')
|
||||
this.$router.push({ path: '/fileManagement/fileList' })
|
||||
},
|
||||
toSetting() {
|
||||
this.$store.dispatch('user/setRouteType', 'setting')
|
||||
this.$router.push({ path: '/setting/dictManagement' })
|
||||
|
|
|
@ -18,6 +18,7 @@ import modelarts from './modules/modelarts'
|
|||
import taskManagementRouter from './modules/taskManagement'
|
||||
import strategyManagementRouter from './modules/strategy'
|
||||
import adapterMangementRouter from './modules/adapterManagement'
|
||||
import fileManagementRouter from './modules/fileManagement'
|
||||
/* Router Modules */
|
||||
// import componentsRouter from './modules/components'
|
||||
// import tableRouter from './modules/table'
|
||||
|
@ -153,7 +154,8 @@ export const asyncRoutes = [
|
|||
modelarts,
|
||||
taskManagementRouter,
|
||||
strategyManagementRouter,
|
||||
adapterMangementRouter
|
||||
adapterMangementRouter,
|
||||
fileManagementRouter
|
||||
]
|
||||
|
||||
const createRouter = () => new Router({
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import Layout from '@/layout'
|
||||
const fileManagementRouter = {
|
||||
path: '/fileManagement',
|
||||
component: Layout,
|
||||
name: 'fileManagement',
|
||||
meta: {
|
||||
title: 'fileManagement',
|
||||
icon: 'xunijiguanli-juan'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'fileList',
|
||||
component: () => import('@/views/fileManagement/fileList/list'),
|
||||
name: 'fileManagement',
|
||||
meta: { title: 'overview', icon: 'gailan', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
]
|
||||
}
|
||||
export default fileManagementRouter
|
|
@ -28,6 +28,28 @@ const taskManagementRouter = {
|
|||
name: 'taskList',
|
||||
meta: { title: 'taskList', icon: 'gailan', affix: true },
|
||||
hidden: false
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: 'cloudList',
|
||||
component: () => import('@/views/taskManagement/cloudList/taskList'),
|
||||
name: 'cloudList',
|
||||
meta: { title: 'cloudList', icon: 'gailan', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'aiList',
|
||||
component: () => import('@/views/taskManagement/aiList/taskList'),
|
||||
name: 'aiList',
|
||||
meta: { title: 'aiList', icon: 'gailan', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'hpcList',
|
||||
component: () => import('@/views/taskManagement/hpcList/taskList'),
|
||||
name: 'hpcList',
|
||||
meta: { title: 'hpcList', icon: 'gailan', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
]
|
||||
}
|
||||
export default taskManagementRouter
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
<template>
|
||||
<div class="UsabilityMonitor">
|
||||
<el-card>
|
||||
<Exhibition :data="exhibitionArray" span="8" />
|
||||
</el-card>
|
||||
<el-row>
|
||||
<el-card>
|
||||
<el-row>
|
||||
<div class="select-option">
|
||||
<el-button class="opr-btn" size="middle" type="primary" @click="form={runEnv: 'python3'};dialogCreateVisible=true">上传文件</el-button>
|
||||
<!-- <el-button class="opr-btn" size="middle" @click="downloadList">下载任务列表</el-button> -->
|
||||
</div>
|
||||
<div class="file-breadcrumb">
|
||||
<span class="floatRight">共{{ (diskfileList || []).length }}个文件</span>
|
||||
<el-breadcrumb separator-class="el-icon-arrow-right">
|
||||
<el-breadcrumb-item :to="{ path: '/' }">全部文件</el-breadcrumb-item>
|
||||
<!-- <el-breadcrumb-item>文件夹名</el-breadcrumb-item> -->
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<List
|
||||
ref="multipleTable"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:table-list-data="diskfileList"
|
||||
:pagination="false"
|
||||
tooltip-effect="dark"
|
||||
/>
|
||||
<div class="add-pagination">
|
||||
<el-pagination
|
||||
background
|
||||
:hide-on-single-page="false"
|
||||
:current-page="page"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@current-change="currentChange"
|
||||
/>
|
||||
</div>
|
||||
<el-dialog :visible.sync="dialogCreateVisible" title="上传文件选择" width="35%">
|
||||
<div class="upload-area">
|
||||
<p>存储方式</p>
|
||||
<el-row type="flex" justify="space-between">
|
||||
<el-col :span="6">
|
||||
<el-radio v-model="radio1" label="1" border>直接存储</el-radio>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-radio v-model="radio1" label="2" border>多副本方式</el-radio>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-radio v-model="radio1" label="3" border>纠删码方式</el-radio>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<p style="margin-top: 30px">本地上传</p>
|
||||
<el-upload
|
||||
:key="radio1"
|
||||
ref="upload"
|
||||
class="upload-file"
|
||||
:headers="{'Authorization': token}"
|
||||
:action="location + '/apis/jcc-cloudStorage/storage/uploadFile?mode=' + radio1"
|
||||
:file-list="fileList"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
||||
<div slot="tip" class="el-upload__tip">单个文件支持最大上传2G</div>
|
||||
</el-upload>
|
||||
<el-divider />
|
||||
<el-button type="info" @click="submitUpload">确认</el-button>
|
||||
<el-button @click="dialogCreateVisible=false">取消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog :visible.sync="dialogDetailVisible" title="存储文件详情" width="80%">
|
||||
<div>
|
||||
<!-- <div class="select-option" /> -->
|
||||
<div class="tap-name">
|
||||
存储文件名称:
|
||||
{{ tapTableData0.length > 0 ? tapTableData0[0].name : '' }}
|
||||
<!-- 条带名:/t1efne231_0 -->
|
||||
</div>
|
||||
<List
|
||||
ref="tapTable0"
|
||||
class="tapTable"
|
||||
:columns="tapTableColumns"
|
||||
:table-list-data="tapTableData0"
|
||||
:pagination="false"
|
||||
/>
|
||||
<!-- <div class="add-pagination">
|
||||
<el-pagination
|
||||
background
|
||||
:hide-on-single-page="false"
|
||||
:current-page="1"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="10"
|
||||
/>
|
||||
</div> -->
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import Exhibition from '@/components/Exhibition'
|
||||
import clip from '@/utils/clipboard'
|
||||
import { numberToStr } from '@/utils/data-process'
|
||||
// import deletePng from '@/assets/images/exhibition/statusMonitor-2.png'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
List,
|
||||
Exhibition
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
location: window.location.origin,
|
||||
active: 1,
|
||||
dialogCreateVisible: false,
|
||||
dialogDetailVisible: false,
|
||||
radio1: '1',
|
||||
token: getToken(),
|
||||
exhibitionArray: [
|
||||
{
|
||||
name: '文件个数',
|
||||
src: 'usabilityMonitor-1',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
name: '文件总大小',
|
||||
src: 'usabilityMonitor-2',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
name: '剩余空间容量',
|
||||
src: 'usabilityMonitor-3',
|
||||
value: '0'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{ type: 'selection' },
|
||||
{ prop: 'name', label: '文件名', formatter: (row) => { return <span>{row.name}</span> } },
|
||||
{ prop: 'createdTime', label: '修改时间' },
|
||||
{ prop: 'size', label: '大小', formatter: (row) => { return <span>{numberToStr(row.size - 0, 'B')}</span> } },
|
||||
{ prop: '', label: '操作', formatter: (row) => {
|
||||
const options = { width: 120 }
|
||||
return <div class='opr-group'>
|
||||
<el-popover
|
||||
placement='bottom'
|
||||
width='320'
|
||||
trigger='click'>
|
||||
<div class='qrcode-popover'>
|
||||
<p>文件分享</p>
|
||||
<div class='qrcode'>
|
||||
<qrcode options={ options } value={row.url} />
|
||||
</div>
|
||||
<el-divider/>
|
||||
<span>链接30天后失效</span>
|
||||
<el-button size='middle' type='primary' onClick={ (e) => { this.handleCopy(row.url, e) }}>复制链接</el-button>
|
||||
</div>
|
||||
<svg-icon icon-class='fenxiang' slot='reference'/>
|
||||
</el-popover>
|
||||
<svg-icon icon-class='xiazai' onClick={() => this.downloadFile(row)} />
|
||||
<svg-icon icon-class='bianji' onClick={() => this.viewDetail(row.id)} />
|
||||
<svg-icon icon-class='shanchu' onClick={() => this.deleteFile(row.id)} />
|
||||
</div>
|
||||
} }
|
||||
],
|
||||
tapTableColumns: [
|
||||
{ type: 'index', label: '序号' },
|
||||
{ prop: 'clusterName', label: '集群/虚拟机' },
|
||||
{ prop: 'size', label: '占用大小' },
|
||||
{ prop: 'ip', label: 'IP' },
|
||||
{ prop: 'address', label: '地点' },
|
||||
// { prop: 'status', label: '状态', formatter: (row) => { return <span class={row.status === '异常' ? 'red' : 'nlue'}>{row.status}</span> } }
|
||||
{ prop: 'status', label: '状态', formatter: (row) => <span class='nlue'>正常</span> } // 后端wangqi建议先写死
|
||||
],
|
||||
tapTableData0: [],
|
||||
tapTableData1: [],
|
||||
diskfileList: [],
|
||||
fileList: [],
|
||||
page: 1,
|
||||
size: 12,
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.getCount()
|
||||
},
|
||||
methods: {
|
||||
currentChange(page) {
|
||||
this.page = page
|
||||
this.getList()
|
||||
},
|
||||
handleUploadSuccess() {
|
||||
this.$message.success('文件上传成功')
|
||||
this.dialogCreateVisible = false
|
||||
this.fileList = []
|
||||
this.getList()
|
||||
},
|
||||
handleUploadError() {
|
||||
this.$message.warning('上传失败')
|
||||
},
|
||||
handleCopy(text, event) {
|
||||
clip(text, event)
|
||||
},
|
||||
deleteFile(id) {
|
||||
this.$confirm('<img src=""><p>文件删除后将不可恢复,是否确认删除?</p>', '温馨提示', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
confirmButtonText: '确认',
|
||||
center: true,
|
||||
cancelButtonText: '取消'
|
||||
}).then(() => {
|
||||
this.$Api.deleteFile(id).then(e => {
|
||||
this.$message.success('删除成功')
|
||||
this.getList()
|
||||
})
|
||||
})
|
||||
},
|
||||
downloadFile(row) {
|
||||
const a = document.createElement('a')
|
||||
a.href = row.url
|
||||
a.download = row.name // 下载文件的名字
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
},
|
||||
addFolder() {},
|
||||
downloadList() {},
|
||||
viewDetail(id) {
|
||||
this.$Api.getFileInfoById(id).then(res => {
|
||||
this.tapTableData0 = [
|
||||
{
|
||||
name: res.data.name,
|
||||
clusterName: res.data.clusterName,
|
||||
size: res.data.size,
|
||||
ip: res.data.ip,
|
||||
address: res.data.city,
|
||||
status: res.data.status === 1 ? '正常' : '异常'
|
||||
}
|
||||
]
|
||||
this.dialogDetailVisible = true
|
||||
})
|
||||
},
|
||||
submitUpload() {
|
||||
this.$refs.upload.submit()
|
||||
},
|
||||
getBase64(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
let fileResult = ''
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = () => {
|
||||
fileResult = reader.result
|
||||
}
|
||||
reader.onerror = (error) => {
|
||||
reject(error)
|
||||
}
|
||||
reader.onloadend = () => {
|
||||
resolve(fileResult)
|
||||
}
|
||||
})
|
||||
},
|
||||
getCount() {
|
||||
// this.$Api.getFileCount().then(e => {
|
||||
// this.exhibitionArray[0].value = e.data?.fileCount
|
||||
// this.exhibitionArray[1].value = numberToStr(e.data?.fileSum - 0, 'B')
|
||||
// this.exhibitionArray[2].value = numberToStr(e.data?.surplusCapacity - 0, 'B')
|
||||
// })
|
||||
},
|
||||
getList() {
|
||||
this.$Api.getFileList({ 'mark': 'page', 'page': this.page }).then(e => {
|
||||
this.diskfileList = e.rows
|
||||
this.total = e.total
|
||||
})
|
||||
},
|
||||
deleteFunc(id) {
|
||||
},
|
||||
handleClick() {
|
||||
if (this.activeName === '1') {
|
||||
this.form = { env: 'python' }
|
||||
}
|
||||
},
|
||||
transBase64(code) {
|
||||
return Buffer.from(code).toString('base64')
|
||||
},
|
||||
getResult() {
|
||||
// this.dynamicData();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.select-option{
|
||||
padding: 20px;
|
||||
color: var(--buttonDivC);
|
||||
background: var(--listBtnColor);
|
||||
}
|
||||
.opr-group{
|
||||
color:#999999;
|
||||
svg{
|
||||
margin-right: 37px;
|
||||
cursor: pointer
|
||||
}
|
||||
.svg-icon{width:20px; height: 20px;}
|
||||
}
|
||||
.file-breadcrumb{
|
||||
padding: 17px 32px;
|
||||
.el-breadcrumb__item:last-child .el-breadcrumb__inner, .el-breadcrumb__item:last-child .el-breadcrumb__inner:hover, .el-breadcrumb__item:last-child .el-breadcrumb__inner a, .el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover{
|
||||
font-size: 16px!important;
|
||||
color: var(--buttonDivC);
|
||||
font-weight: 500!important;
|
||||
}
|
||||
.floatRight{
|
||||
text-align: right;
|
||||
float: right;
|
||||
font-size: 16px!important;
|
||||
color: var(--buttonDivC);
|
||||
font-weight: 500!important;
|
||||
}
|
||||
}
|
||||
.el-popper .qrcode-popover{
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
p{
|
||||
margin-top: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.qrcode{
|
||||
margin: 24px auto;
|
||||
margin-top: 40px;
|
||||
width: 140px;
|
||||
padding: 10px;
|
||||
border: 1px solid #eeeeee;
|
||||
border-radius: 10px;
|
||||
}
|
||||
>span{
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
margin-bottom: 24px;
|
||||
color: #999999;
|
||||
}
|
||||
.el-button{
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
.el-divider{
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
.upload-area{
|
||||
text-align: center;
|
||||
p{
|
||||
text-align: left;
|
||||
color: var(--buttonDivC);
|
||||
font-size: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.el-row--flex.is-justify-space-between{
|
||||
margin-top: 20px;
|
||||
}
|
||||
.upload-file{
|
||||
text-align: right;
|
||||
}
|
||||
.el-upload__tip{
|
||||
float: left;
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.el-upload{
|
||||
.el-button{
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.el-upload-list__item-name{
|
||||
text-align: left;
|
||||
}
|
||||
.el-radio{
|
||||
width: 100%;
|
||||
}
|
||||
>.el-button{
|
||||
margin: 100px 18px 10px 18px;
|
||||
}
|
||||
}
|
||||
.red{
|
||||
color: #D9001B;
|
||||
}
|
||||
.blue {
|
||||
color: #3182CE;
|
||||
}
|
||||
.tap-name{
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
background: #3182CE;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 24px;
|
||||
padding: 0 27px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.add-pagination{
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,210 @@
|
|||
<template>
|
||||
<div class="podInfo">
|
||||
<el-card class="basicInfo">
|
||||
<h4>{{ $t('page.ai')+$t('page.task') }}</h4>
|
||||
<span class="tips title-tips">
|
||||
{{ $t('page.taskDescription') }}</span>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<ul class="dataCard">
|
||||
<li>
|
||||
<p>训练任务</p>
|
||||
<div>
|
||||
<div class="data">
|
||||
<span>运行中</span>
|
||||
<p>30</p>
|
||||
</div>
|
||||
<div class="data">
|
||||
<span>总数</span>
|
||||
<p>100</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>推理任务</p>
|
||||
<div>
|
||||
<div class="data">
|
||||
<span>运行中</span>
|
||||
<p>30</p>
|
||||
</div>
|
||||
<div class="data">
|
||||
<span>总数</span>
|
||||
<p>100</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>模型实例</p>
|
||||
<div>
|
||||
<div class="data">
|
||||
<span>运行中</span>
|
||||
<p>30</p>
|
||||
</div>
|
||||
<div class="data">
|
||||
<span>总数</span>
|
||||
<p>100</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<List
|
||||
ref="multipleTable"
|
||||
:key="$i18n.locale"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:filter-map="filterMap"
|
||||
:get-list-action="getAppList"
|
||||
:default-sort="{prop: 'existTime', order: 'ascending'}"
|
||||
:pagination="true"
|
||||
page-key="pageNum"
|
||||
limit-key="pageSize"
|
||||
tooltip-effect="dark"
|
||||
>
|
||||
<template v-slot:filterBtns>
|
||||
<el-button size="medium" type="primary" @click="createItem">{{ $t('message.create') }}</el-button>
|
||||
</template>
|
||||
</List>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import { getAppList } from '@/api/task/task'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { runtimeFormat } from '@/utils/index'
|
||||
export default {
|
||||
components: { List },
|
||||
data() {
|
||||
return {
|
||||
getAppList,
|
||||
strategyList: []
|
||||
// columns: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'dict'
|
||||
]),
|
||||
filterMap() {
|
||||
return {
|
||||
name: {
|
||||
label: this.$t('message.name')
|
||||
},
|
||||
status: {
|
||||
label: this.$t('page.job') + this.$t('page.status'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '已保留', value: 'unschedulable'
|
||||
}, {
|
||||
label: '已下发', value: 'running'
|
||||
}, {
|
||||
label: '错误', value: 'warning'
|
||||
}
|
||||
]
|
||||
},
|
||||
type: {
|
||||
label: this.$t('page.task') + this.$t('page.type'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '部署任务', value: 'unschedulable'
|
||||
}, {
|
||||
label: '应用任务', value: 'running'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
columns() {
|
||||
return this.setColumn()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// '$i18n.locale'() {
|
||||
// console.log('fff')
|
||||
// this.setColumn()
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
setColumn() {
|
||||
return [
|
||||
{ prop: 'name', label: this.$t('page.taskName'), sortable: true, formatter: (row) => { return <a onClick={() => this.viewDetail(row)}>{row.name}</a> } },
|
||||
{ prop: 'adapterTypeDict', label: this.$t('page.cpType'), formatter: row => {
|
||||
return <div>{this.dict.adapter_type.filter(e => { return row.adapterTypeDict.toString() === e.itemValue })?.[0]?.['itemText'] || '-'}</div>
|
||||
} },
|
||||
{
|
||||
prop: 'status',
|
||||
label: this.$t('page.jobStatus')
|
||||
},
|
||||
{ prop: 'strategy', label: this.$t('page.policy'), formatter: row => {
|
||||
const res = this.dict.schedule_Strategy.filter(e => { return row.strategy.toString() === e.itemValue })[0][this.$i18n.locale === 'en' ? 'itemText' : 'description']
|
||||
return <div>{res}</div>
|
||||
} },
|
||||
{ prop: 'synergyStatus', label: this.$t('page.synergyStatus'), sortable: true, formatter: (row) => {
|
||||
return <div>{!row.synergyStatus ? this.$t('page.notSynergistic') : this.$t('page.synergistic')}</div>
|
||||
} },
|
||||
// { prop: 'adapter', label: this.$t('page.adapter'), sortable: true },
|
||||
// { prop: 'cluster', label: this.$t('page.cluster'), sortable: true },
|
||||
{ prop: 'startTime', label: this.$t('page.startTime'), sortable: true, formatter: (row) => {
|
||||
return <div>{row.startTime && new Date(row.startTime).toLocaleString() || '-'}</div>
|
||||
} },
|
||||
{ prop: 'runningTime', label: this.$t('page.elapsedTime'), sortable: true, formatter: row => {
|
||||
return <div>{runtimeFormat(row.runningTime)}</div>
|
||||
} },
|
||||
{ prop: 'more', label: this.$t('page.more'), width: 200, formatter: (row) => {
|
||||
const txt = this.$t('page.viewDetail')
|
||||
return <div>
|
||||
<el-dropdown>
|
||||
<el-button className='el-dropdown-link' size='mini' icon='el-icon-more' circle>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot='dropdown'>
|
||||
<span onClick={() => this.viewDetail(row)}> <el-dropdown-item> {txt} </el-dropdown-item> </span>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
} }
|
||||
]
|
||||
},
|
||||
viewDetail(row) {
|
||||
this.$router.push({ path: `detail`, query: { id: row.id }})
|
||||
},
|
||||
createItem() {
|
||||
this.$router.push({ path: `create` })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.dataCard{
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
// display: flex;
|
||||
// padding-bottom: 1rem;
|
||||
// box-sizing: content-box;
|
||||
li{
|
||||
width: 26.7%;
|
||||
margin: 0 3.3%;
|
||||
float: left;
|
||||
list-style-type: none;
|
||||
box-shadow: 1px 1px 10px #050f27;
|
||||
text-indent: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
p{
|
||||
font-size: 1.2rem;
|
||||
|
||||
}
|
||||
>div{
|
||||
display: flex;
|
||||
.data:first-child{
|
||||
span{
|
||||
color: #3182CE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,142 @@
|
|||
<template>
|
||||
<div class="podInfo">
|
||||
<el-card class="basicInfo">
|
||||
<h4>{{ $t('page.cloud')+$t('page.task') }}</h4>
|
||||
<span class="tips title-tips">
|
||||
{{ $t('page.taskDescription') }}</span>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<List
|
||||
ref="multipleTable"
|
||||
:key="$i18n.locale"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:filter-map="filterMap"
|
||||
:get-list-action="getAppList"
|
||||
:default-sort="{prop: 'existTime', order: 'ascending'}"
|
||||
:pagination="true"
|
||||
page-key="pageNum"
|
||||
limit-key="pageSize"
|
||||
tooltip-effect="dark"
|
||||
>
|
||||
<template v-slot:filterBtns>
|
||||
<el-button size="medium" type="primary" @click="createItem">{{ $t('message.create') }}</el-button>
|
||||
</template>
|
||||
</List>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import { getAppList } from '@/api/task/task'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { runtimeFormat } from '@/utils/index'
|
||||
export default {
|
||||
components: { List },
|
||||
data() {
|
||||
return {
|
||||
getAppList,
|
||||
strategyList: []
|
||||
// columns: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'dict'
|
||||
]),
|
||||
filterMap() {
|
||||
return {
|
||||
name: {
|
||||
label: this.$t('message.name')
|
||||
},
|
||||
status: {
|
||||
label: this.$t('page.job') + this.$t('page.status'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '已保留', value: 'unschedulable'
|
||||
}, {
|
||||
label: '已下发', value: 'running'
|
||||
}, {
|
||||
label: '错误', value: 'warning'
|
||||
}
|
||||
]
|
||||
},
|
||||
type: {
|
||||
label: this.$t('page.task') + this.$t('page.type'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '部署任务', value: 'unschedulable'
|
||||
}, {
|
||||
label: '应用任务', value: 'running'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
columns() {
|
||||
return this.setColumn()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// '$i18n.locale'() {
|
||||
// console.log('fff')
|
||||
// this.setColumn()
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
setColumn() {
|
||||
return [
|
||||
{ prop: 'name', label: this.$t('page.taskName'), sortable: true, formatter: (row) => { return <a onClick={() => this.viewDetail(row)}>{row.name}</a> } },
|
||||
{ prop: 'adapterTypeDict', label: this.$t('page.cpType'), formatter: row => {
|
||||
return <div>{this.dict.adapter_type.filter(e => { return row.adapterTypeDict.toString() === e.itemValue })?.[0]?.['itemText'] || '-'}</div>
|
||||
} },
|
||||
{
|
||||
prop: 'status',
|
||||
label: this.$t('page.jobStatus')
|
||||
},
|
||||
{ prop: 'strategy', label: this.$t('page.policy'), formatter: row => {
|
||||
const res = this.dict.schedule_Strategy.filter(e => { return row.strategy.toString() === e.itemValue })[0][this.$i18n.locale === 'en' ? 'itemText' : 'description']
|
||||
return <div>{res}</div>
|
||||
} },
|
||||
{ prop: 'synergyStatus', label: this.$t('page.synergyStatus'), sortable: true, formatter: (row) => {
|
||||
return <div>{!row.synergyStatus ? this.$t('page.notSynergistic') : this.$t('page.synergistic')}</div>
|
||||
} },
|
||||
// { prop: 'adapter', label: this.$t('page.adapter'), sortable: true },
|
||||
// { prop: 'cluster', label: this.$t('page.cluster'), sortable: true },
|
||||
{ prop: 'startTime', label: this.$t('page.startTime'), sortable: true, formatter: (row) => {
|
||||
return <div>{row.startTime && new Date(row.startTime).toLocaleString() || '-'}</div>
|
||||
} },
|
||||
{ prop: 'runningTime', label: this.$t('page.elapsedTime'), sortable: true, formatter: row => {
|
||||
return <div>{runtimeFormat(row.runningTime)}</div>
|
||||
} },
|
||||
{ prop: 'more', label: this.$t('page.more'), width: 200, formatter: (row) => {
|
||||
const txt = this.$t('page.viewDetail')
|
||||
return <div>
|
||||
<el-dropdown>
|
||||
<el-button className='el-dropdown-link' size='mini' icon='el-icon-more' circle>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot='dropdown'>
|
||||
<span onClick={() => this.viewDetail(row)}> <el-dropdown-item> {txt} </el-dropdown-item> </span>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
} }
|
||||
]
|
||||
},
|
||||
viewDetail(row) {
|
||||
this.$router.push({ path: `detail`, query: { id: row.id }})
|
||||
},
|
||||
createItem() {
|
||||
this.$router.push({ path: `create` })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -0,0 +1,142 @@
|
|||
<template>
|
||||
<div class="podInfo">
|
||||
<el-card class="basicInfo">
|
||||
<h4>{{ $t('page.hpc')+ $t('page.task') }}</h4>
|
||||
<span class="tips title-tips">
|
||||
{{ $t('page.taskDescription') }}</span>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<List
|
||||
ref="multipleTable"
|
||||
:key="$i18n.locale"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:filter-map="filterMap"
|
||||
:get-list-action="getAppList"
|
||||
:default-sort="{prop: 'existTime', order: 'ascending'}"
|
||||
:pagination="true"
|
||||
page-key="pageNum"
|
||||
limit-key="pageSize"
|
||||
tooltip-effect="dark"
|
||||
>
|
||||
<template v-slot:filterBtns>
|
||||
<el-button size="medium" type="primary" @click="createItem">{{ $t('message.create') }}</el-button>
|
||||
</template>
|
||||
</List>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import { getAppList } from '@/api/task/task'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { runtimeFormat } from '@/utils/index'
|
||||
export default {
|
||||
components: { List },
|
||||
data() {
|
||||
return {
|
||||
getAppList,
|
||||
strategyList: []
|
||||
// columns: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'dict'
|
||||
]),
|
||||
filterMap() {
|
||||
return {
|
||||
name: {
|
||||
label: this.$t('message.name')
|
||||
},
|
||||
status: {
|
||||
label: this.$t('page.job') + this.$t('page.status'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '已保留', value: 'unschedulable'
|
||||
}, {
|
||||
label: '已下发', value: 'running'
|
||||
}, {
|
||||
label: '错误', value: 'warning'
|
||||
}
|
||||
]
|
||||
},
|
||||
type: {
|
||||
label: this.$t('page.task') + this.$t('page.type'),
|
||||
type: 'select',
|
||||
dataSource: [
|
||||
{
|
||||
label: '部署任务', value: 'unschedulable'
|
||||
}, {
|
||||
label: '应用任务', value: 'running'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
columns() {
|
||||
return this.setColumn()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// '$i18n.locale'() {
|
||||
// console.log('fff')
|
||||
// this.setColumn()
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
setColumn() {
|
||||
return [
|
||||
{ prop: 'name', label: this.$t('page.taskName'), sortable: true, formatter: (row) => { return <a onClick={() => this.viewDetail(row)}>{row.name}</a> } },
|
||||
{ prop: 'adapterTypeDict', label: this.$t('page.cpType'), formatter: row => {
|
||||
return <div>{this.dict.adapter_type.filter(e => { return row.adapterTypeDict.toString() === e.itemValue })?.[0]?.['itemText'] || '-'}</div>
|
||||
} },
|
||||
{
|
||||
prop: 'status',
|
||||
label: this.$t('page.jobStatus')
|
||||
},
|
||||
{ prop: 'strategy', label: this.$t('page.policy'), formatter: row => {
|
||||
const res = this.dict.schedule_Strategy.filter(e => { return row.strategy.toString() === e.itemValue })[0][this.$i18n.locale === 'en' ? 'itemText' : 'description']
|
||||
return <div>{res}</div>
|
||||
} },
|
||||
{ prop: 'synergyStatus', label: this.$t('page.synergyStatus'), sortable: true, formatter: (row) => {
|
||||
return <div>{!row.synergyStatus ? this.$t('page.notSynergistic') : this.$t('page.synergistic')}</div>
|
||||
} },
|
||||
// { prop: 'adapter', label: this.$t('page.adapter'), sortable: true },
|
||||
// { prop: 'cluster', label: this.$t('page.cluster'), sortable: true },
|
||||
{ prop: 'startTime', label: this.$t('page.startTime'), sortable: true, formatter: (row) => {
|
||||
return <div>{row.startTime && new Date(row.startTime).toLocaleString() || '-'}</div>
|
||||
} },
|
||||
{ prop: 'runningTime', label: this.$t('page.elapsedTime'), sortable: true, formatter: row => {
|
||||
return <div>{runtimeFormat(row.runningTime)}</div>
|
||||
} },
|
||||
{ prop: 'more', label: this.$t('page.more'), width: 200, formatter: (row) => {
|
||||
const txt = this.$t('page.viewDetail')
|
||||
return <div>
|
||||
<el-dropdown>
|
||||
<el-button className='el-dropdown-link' size='mini' icon='el-icon-more' circle>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot='dropdown'>
|
||||
<span onClick={() => this.viewDetail(row)}> <el-dropdown-item> {txt} </el-dropdown-item> </span>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
} }
|
||||
]
|
||||
},
|
||||
viewDetail(row) {
|
||||
this.$router.push({ path: `detail`, query: { id: row.id }})
|
||||
},
|
||||
createItem() {
|
||||
this.$router.push({ path: `create` })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
|
@ -50,6 +50,31 @@ export default {
|
|||
name: {
|
||||
label: this.$t('message.name')
|
||||
}
|
||||
// status: {
|
||||
// label: this.$t('page.job') + this.$t('page.status'),
|
||||
// type: 'select',
|
||||
// dataSource: [
|
||||
// {
|
||||
// label: '已保留', value: 'unschedulable'
|
||||
// }, {
|
||||
// label: '已下发', value: 'running'
|
||||
// }, {
|
||||
// label: '错误', value: 'warning'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// type: {
|
||||
// label: this.$t('page.task') + this.$t('page.type'),
|
||||
// type: 'select',
|
||||
// dataSource: [
|
||||
// {
|
||||
// label: '智算资源任务', value: 'unschedulable'
|
||||
// }, {
|
||||
// label: '智算资源任务', value: 'running'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
},
|
||||
columns() {
|
||||
|
|
Loading…
Reference in New Issue